1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/proc_fs.h>
23#include <linux/ptrace.h>
24#include <linux/seq_file.h>
25#include <linux/string.h>
26#include <linux/timer.h>
27#include <linux/init.h>
28#include <linux/netdevice.h>
29#include <linux/etherdevice.h>
30#include <linux/if_arp.h>
31#include <linux/ioport.h>
32#include <linux/skbuff.h>
33#include <linux/ieee80211.h>
34
35#include <pcmcia/cistpl.h>
36#include <pcmcia/cisreg.h>
37#include <pcmcia/ds.h>
38
39#include <linux/wireless.h>
40#include <net/iw_handler.h>
41
42#include <asm/io.h>
43#include <asm/byteorder.h>
44#include <linux/uaccess.h>
45
46
47#define WIRELESS_SPY
48
49typedef struct iw_statistics iw_stats;
50typedef u_char mac_addr[ETH_ALEN];
51
52#include "rayctl.h"
53#include "ray_cs.h"
54
55
56
57static int ray_config(struct pcmcia_device *link);
58static void ray_release(struct pcmcia_device *link);
59static void ray_detach(struct pcmcia_device *p_dev);
60
61
62static int ray_dev_close(struct net_device *dev);
63static int ray_dev_config(struct net_device *dev, struct ifmap *map);
64static struct net_device_stats *ray_get_stats(struct net_device *dev);
65static int ray_dev_init(struct net_device *dev);
66
67static int ray_open(struct net_device *dev);
68static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
69 struct net_device *dev);
70static void set_multicast_list(struct net_device *dev);
71static void ray_update_multi_list(struct net_device *dev, int all);
72static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
73 unsigned char *data, int len);
74static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
75 UCHAR msg_type, unsigned char *data);
76static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
77static iw_stats *ray_get_wireless_stats(struct net_device *dev);
78static const struct iw_handler_def ray_handler_def;
79
80
81static void authenticate(ray_dev_t *local);
82static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
83static void authenticate_timeout(struct timer_list *t);
84static int get_free_ccs(ray_dev_t *local);
85static int get_free_tx_ccs(ray_dev_t *local);
86static void init_startup_params(ray_dev_t *local);
87static int parse_addr(char *in_str, UCHAR *out);
88static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, UCHAR type);
89static int ray_init(struct net_device *dev);
90static int interrupt_ecf(ray_dev_t *local, int ccs);
91static void ray_reset(struct net_device *dev);
92static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);
93static void verify_dl_startup(struct timer_list *t);
94
95
96static irqreturn_t ray_interrupt(int reg, void *dev_id);
97static void clear_interrupt(ray_dev_t *local);
98static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
99 unsigned int pkt_addr, int rx_len);
100static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
101static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
102static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
103static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
104 unsigned int pkt_addr, int rx_len);
105static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
106 unsigned int pkt_addr, int rx_len);
107static void associate(ray_dev_t *local);
108
109
110static int dl_startup_params(struct net_device *dev);
111static void join_net(struct timer_list *t);
112static void start_net(struct timer_list *t);
113
114
115
116
117
118static int net_type = ADHOC;
119
120
121static int hop_dwell = 128;
122
123
124static int beacon_period = 256;
125
126
127static int psm;
128
129
130static char *essid;
131
132
133static bool translate = true;
134
135static int country = USA;
136
137static int sniffer;
138
139static int bc;
140
141
142
143
144
145
146
147
148
149
150
151static char *phy_addr = NULL;
152
153static unsigned int ray_mem_speed = 500;
154
155
156static struct pcmcia_device *this_device = NULL;
157
158MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
159MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
160MODULE_LICENSE("GPL");
161
162module_param(net_type, int, 0);
163module_param(hop_dwell, int, 0);
164module_param(beacon_period, int, 0);
165module_param(psm, int, 0);
166module_param(essid, charp, 0);
167module_param(translate, bool, 0);
168module_param(country, int, 0);
169module_param(sniffer, int, 0);
170module_param(bc, int, 0);
171module_param(phy_addr, charp, 0);
172module_param(ray_mem_speed, int, 0);
173
174static const UCHAR b5_default_startup_parms[] = {
175 0, 0,
176 'L', 'I', 'N', 'U', 'X', 0, 0, 0,
177 0, 0, 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 0, 0, 0,
180 1, 0,
181 0, 0, 0, 0, 0, 0,
182 0x7f, 0xff,
183 0x00, 0x80,
184 0x01, 0x00,
185 0x01, 0x07, 0xa3,
186 0x1d, 0x82, 0x4e,
187 0x7f, 0xff,
188 0x04, 0xe2, 0x38, 0xA4,
189 0x05,
190 0x08, 0x02, 0x08,
191 0,
192 0x0c, 0x0bd,
193 0x32,
194 0xff, 0xff,
195 0x05, 0xff,
196 0x01, 0x0b, 0x4f,
197
198 0x00, 0x3f,
199 0x00, 0x0f,
200 0x04, 0x08,
201 0x28, 0x28,
202 7,
203 0, 2, 2,
204 0,
205 0, 0,
206 2, 0, 0, 0, 0, 0, 0, 0
207};
208
209static const UCHAR b4_default_startup_parms[] = {
210 0, 0,
211 'L', 'I', 'N', 'U', 'X', 0, 0, 0,
212 0, 0, 0, 0, 0, 0, 0, 0,
213 0, 0, 0, 0, 0, 0, 0, 0,
214 0, 0, 0, 0, 0, 0, 0, 0,
215 1, 0,
216 0, 0, 0, 0, 0, 0,
217 0x7f, 0xff,
218 0x02, 0x00,
219 0x00, 0x01,
220 0x01, 0x07, 0xa3,
221 0x1d, 0x82, 0xce,
222 0x7f, 0xff,
223 0xfb, 0x1e, 0xc7, 0x5c,
224 0x05,
225 0x04, 0x02, 0x4,
226 0,
227 0x0c, 0x0bd,
228 0x4e,
229 0xff, 0xff,
230 0x05, 0xff,
231 0x01, 0x0b, 0x4e,
232
233 0x3f, 0x0f,
234 0x04, 0x08,
235 0x28, 0x28,
236 7,
237 0, 2, 2,
238 0,
239 0, 0, 0, 0, 0, 0,
240 0
241};
242
243
244static const u8 eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
245
246static const char hop_pattern_length[] = { 1,
247 USA_HOP_MOD, EUROPE_HOP_MOD,
248 JAPAN_HOP_MOD, KOREA_HOP_MOD,
249 SPAIN_HOP_MOD, FRANCE_HOP_MOD,
250 ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
251 JAPAN_TEST_HOP_MOD
252};
253
254static const char rcsid[] =
255 "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
256
257static const struct net_device_ops ray_netdev_ops = {
258 .ndo_init = ray_dev_init,
259 .ndo_open = ray_open,
260 .ndo_stop = ray_dev_close,
261 .ndo_start_xmit = ray_dev_start_xmit,
262 .ndo_set_config = ray_dev_config,
263 .ndo_get_stats = ray_get_stats,
264 .ndo_set_rx_mode = set_multicast_list,
265 .ndo_set_mac_address = eth_mac_addr,
266 .ndo_validate_addr = eth_validate_addr,
267};
268
269static int ray_probe(struct pcmcia_device *p_dev)
270{
271 ray_dev_t *local;
272 struct net_device *dev;
273
274 dev_dbg(&p_dev->dev, "ray_attach()\n");
275
276
277 dev = alloc_etherdev(sizeof(ray_dev_t));
278 if (!dev)
279 goto fail_alloc_dev;
280
281 local = netdev_priv(dev);
282 local->finder = p_dev;
283
284
285 p_dev->resource[0]->end = 0;
286 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
287
288
289 p_dev->config_flags |= CONF_ENABLE_IRQ;
290 p_dev->config_index = 1;
291
292 p_dev->priv = dev;
293
294 local->finder = p_dev;
295 local->card_status = CARD_INSERTED;
296 local->authentication_state = UNAUTHENTICATED;
297 local->num_multi = 0;
298 dev_dbg(&p_dev->dev, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
299 p_dev, dev, local, &ray_interrupt);
300
301
302 dev->netdev_ops = &ray_netdev_ops;
303 dev->wireless_handlers = &ray_handler_def;
304#ifdef WIRELESS_SPY
305 local->wireless_data.spy_data = &local->spy_data;
306 dev->wireless_data = &local->wireless_data;
307#endif
308
309
310 dev_dbg(&p_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
311 netif_stop_queue(dev);
312
313 timer_setup(&local->timer, NULL, 0);
314
315 this_device = p_dev;
316 return ray_config(p_dev);
317
318fail_alloc_dev:
319 return -ENOMEM;
320}
321
322static void ray_detach(struct pcmcia_device *link)
323{
324 struct net_device *dev;
325 ray_dev_t *local;
326
327 dev_dbg(&link->dev, "ray_detach\n");
328
329 this_device = NULL;
330 dev = link->priv;
331
332 ray_release(link);
333
334 local = netdev_priv(dev);
335 del_timer_sync(&local->timer);
336
337 if (link->priv) {
338 unregister_netdev(dev);
339 free_netdev(dev);
340 }
341 dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
342}
343
344#define MAX_TUPLE_SIZE 128
345static int ray_config(struct pcmcia_device *link)
346{
347 int ret = 0;
348 int i;
349 struct net_device *dev = (struct net_device *)link->priv;
350 ray_dev_t *local = netdev_priv(dev);
351
352 dev_dbg(&link->dev, "ray_config\n");
353
354
355 printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
356 link->prod_id[0] ? link->prod_id[0] : " ",
357 link->prod_id[1] ? link->prod_id[1] : " ",
358 link->prod_id[2] ? link->prod_id[2] : " ",
359 link->prod_id[3] ? link->prod_id[3] : " ");
360
361
362
363
364 ret = pcmcia_request_irq(link, ray_interrupt);
365 if (ret)
366 goto failed;
367 dev->irq = link->irq;
368
369 ret = pcmcia_enable_device(link);
370 if (ret)
371 goto failed;
372
373
374 link->resource[2]->flags |= WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
375 link->resource[2]->start = 0;
376 link->resource[2]->end = 0x8000;
377 ret = pcmcia_request_window(link, link->resource[2], ray_mem_speed);
378 if (ret)
379 goto failed;
380 ret = pcmcia_map_mem_page(link, link->resource[2], 0);
381 if (ret)
382 goto failed;
383 local->sram = ioremap(link->resource[2]->start,
384 resource_size(link->resource[2]));
385
386
387 link->resource[3]->flags |=
388 WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
389 link->resource[3]->start = 0;
390 link->resource[3]->end = 0x4000;
391 ret = pcmcia_request_window(link, link->resource[3], ray_mem_speed);
392 if (ret)
393 goto failed;
394 ret = pcmcia_map_mem_page(link, link->resource[3], 0x8000);
395 if (ret)
396 goto failed;
397 local->rmem = ioremap(link->resource[3]->start,
398 resource_size(link->resource[3]));
399
400
401 link->resource[4]->flags |=
402 WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
403 link->resource[4]->start = 0;
404 link->resource[4]->end = 0x1000;
405 ret = pcmcia_request_window(link, link->resource[4], ray_mem_speed);
406 if (ret)
407 goto failed;
408 ret = pcmcia_map_mem_page(link, link->resource[4], 0);
409 if (ret)
410 goto failed;
411 local->amem = ioremap(link->resource[4]->start,
412 resource_size(link->resource[4]));
413
414 dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram);
415 dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem);
416 dev_dbg(&link->dev, "ray_config amem=%p\n", local->amem);
417 if (ray_init(dev) < 0) {
418 ray_release(link);
419 return -ENODEV;
420 }
421
422 SET_NETDEV_DEV(dev, &link->dev);
423 i = register_netdev(dev);
424 if (i != 0) {
425 printk("ray_config register_netdev() failed\n");
426 ray_release(link);
427 return i;
428 }
429
430 printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
431 dev->name, dev->irq, dev->dev_addr);
432
433 return 0;
434
435failed:
436 ray_release(link);
437 return -ENODEV;
438}
439
440static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
441{
442 return dev->sram + CCS_BASE;
443}
444
445static inline struct rcs __iomem *rcs_base(ray_dev_t *dev)
446{
447
448
449
450
451
452
453
454 return dev->sram + CCS_BASE;
455}
456
457
458static int ray_init(struct net_device *dev)
459{
460 int i;
461 struct ccs __iomem *pccs;
462 ray_dev_t *local = netdev_priv(dev);
463 struct pcmcia_device *link = local->finder;
464 dev_dbg(&link->dev, "ray_init(0x%p)\n", dev);
465 if (!(pcmcia_dev_present(link))) {
466 dev_dbg(&link->dev, "ray_init - device not present\n");
467 return -1;
468 }
469
470 local->net_type = net_type;
471 local->sta_type = TYPE_STA;
472
473
474 memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,
475 sizeof(struct startup_res_6));
476
477
478 if (local->startup_res.startup_word != 0x80) {
479 printk(KERN_INFO "ray_init ERROR card status = %2x\n",
480 local->startup_res.startup_word);
481 local->card_status = CARD_INIT_ERROR;
482 return -1;
483 }
484
485 local->fw_ver = local->startup_res.firmware_version[0];
486 local->fw_bld = local->startup_res.firmware_version[1];
487 local->fw_var = local->startup_res.firmware_version[2];
488 dev_dbg(&link->dev, "ray_init firmware version %d.%d\n", local->fw_ver,
489 local->fw_bld);
490
491 local->tib_length = 0x20;
492 if ((local->fw_ver == 5) && (local->fw_bld >= 30))
493 local->tib_length = local->startup_res.tib_length;
494 dev_dbg(&link->dev, "ray_init tib_length = 0x%02x\n", local->tib_length);
495
496 pccs = ccs_base(local);
497 for (i = 0; i < NUMBER_OF_CCS; i++) {
498 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
499 }
500 init_startup_params(local);
501
502
503 if (!parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) {
504 memcpy(&local->sparm.b4.a_mac_addr,
505 &local->startup_res.station_addr, ADDRLEN);
506 }
507
508 clear_interrupt(local);
509 local->card_status = CARD_AWAITING_PARAM;
510 dev_dbg(&link->dev, "ray_init ending\n");
511 return 0;
512}
513
514
515
516static int dl_startup_params(struct net_device *dev)
517{
518 int ccsindex;
519 ray_dev_t *local = netdev_priv(dev);
520 struct ccs __iomem *pccs;
521 struct pcmcia_device *link = local->finder;
522
523 dev_dbg(&link->dev, "dl_startup_params entered\n");
524 if (!(pcmcia_dev_present(link))) {
525 dev_dbg(&link->dev, "ray_cs dl_startup_params - device not present\n");
526 return -1;
527 }
528
529
530 if (local->fw_ver == 0x55)
531 memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
532 sizeof(struct b4_startup_params));
533 else
534 memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
535 sizeof(struct b5_startup_params));
536
537
538 if ((ccsindex = get_free_ccs(local)) < 0)
539 return -1;
540 local->dl_param_ccs = ccsindex;
541 pccs = ccs_base(local) + ccsindex;
542 writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
543 dev_dbg(&link->dev, "dl_startup_params start ccsindex = %d\n",
544 local->dl_param_ccs);
545
546 if (interrupt_ecf(local, ccsindex)) {
547 printk(KERN_INFO "ray dl_startup_params failed - "
548 "ECF not ready for intr\n");
549 local->card_status = CARD_DL_PARAM_ERROR;
550 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
551 return -2;
552 }
553 local->card_status = CARD_DL_PARAM;
554
555 local->timer.expires = jiffies + HZ / 2;
556 local->timer.function = verify_dl_startup;
557 add_timer(&local->timer);
558 dev_dbg(&link->dev,
559 "ray_cs dl_startup_params started timer for verify_dl_startup\n");
560 return 0;
561}
562
563
564static void init_startup_params(ray_dev_t *local)
565{
566 int i;
567
568 if (country > JAPAN_TEST)
569 country = USA;
570 else if (country < USA)
571 country = USA;
572
573
574
575
576
577
578
579
580
581
582
583
584 if (local->fw_ver == 0x55) {
585 memcpy(&local->sparm.b4, b4_default_startup_parms,
586 sizeof(struct b4_startup_params));
587
588
589 i = (hop_dwell * 1024) & 0xffffff;
590 local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
591 local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
592 local->sparm.b4.a_beacon_period[0] = 0;
593 local->sparm.b4.a_beacon_period[1] =
594 ((beacon_period / hop_dwell) - 1) & 0xff;
595 local->sparm.b4.a_curr_country_code = country;
596 local->sparm.b4.a_hop_pattern_length =
597 hop_pattern_length[(int)country] - 1;
598 if (bc) {
599 local->sparm.b4.a_ack_timeout = 0x50;
600 local->sparm.b4.a_sifs = 0x3f;
601 }
602 } else {
603 memcpy((UCHAR *) &local->sparm.b5, b5_default_startup_parms,
604 sizeof(struct b5_startup_params));
605
606 local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
607 local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
608 local->sparm.b5.a_beacon_period[0] =
609 (beacon_period >> 8) & 0xff;
610 local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
611 if (psm)
612 local->sparm.b5.a_power_mgt_state = 1;
613 local->sparm.b5.a_curr_country_code = country;
614 local->sparm.b5.a_hop_pattern_length =
615 hop_pattern_length[(int)country];
616 }
617
618 local->sparm.b4.a_network_type = net_type & 0x01;
619 local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
620
621 if (essid != NULL)
622 strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
623}
624
625
626static void verify_dl_startup(struct timer_list *t)
627{
628 ray_dev_t *local = from_timer(local, t, timer);
629 struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
630 UCHAR status;
631 struct pcmcia_device *link = local->finder;
632
633 if (!(pcmcia_dev_present(link))) {
634 dev_dbg(&link->dev, "ray_cs verify_dl_startup - device not present\n");
635 return;
636 }
637#if 0
638 {
639 int i;
640 printk(KERN_DEBUG
641 "verify_dl_startup parameters sent via ccs %d:\n",
642 local->dl_param_ccs);
643 for (i = 0; i < sizeof(struct b5_startup_params); i++) {
644 printk(" %2x",
645 (unsigned int)readb(local->sram +
646 HOST_TO_ECF_BASE + i));
647 }
648 printk("\n");
649 }
650#endif
651
652 status = readb(&pccs->buffer_status);
653 if (status != CCS_BUFFER_FREE) {
654 printk(KERN_INFO
655 "Download startup params failed. Status = %d\n",
656 status);
657 local->card_status = CARD_DL_PARAM_ERROR;
658 return;
659 }
660 if (local->sparm.b4.a_network_type == ADHOC)
661 start_net(&local->timer);
662 else
663 join_net(&local->timer);
664}
665
666
667
668static void start_net(struct timer_list *t)
669{
670 ray_dev_t *local = from_timer(local, t, timer);
671 struct ccs __iomem *pccs;
672 int ccsindex;
673 struct pcmcia_device *link = local->finder;
674 if (!(pcmcia_dev_present(link))) {
675 dev_dbg(&link->dev, "ray_cs start_net - device not present\n");
676 return;
677 }
678
679 if ((ccsindex = get_free_ccs(local)) < 0)
680 return;
681 pccs = ccs_base(local) + ccsindex;
682 writeb(CCS_START_NETWORK, &pccs->cmd);
683 writeb(0, &pccs->var.start_network.update_param);
684
685 if (interrupt_ecf(local, ccsindex)) {
686 dev_dbg(&link->dev, "ray start net failed - card not ready for intr\n");
687 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
688 return;
689 }
690 local->card_status = CARD_DOING_ACQ;
691}
692
693
694
695static void join_net(struct timer_list *t)
696{
697 ray_dev_t *local = from_timer(local, t, timer);
698
699 struct ccs __iomem *pccs;
700 int ccsindex;
701 struct pcmcia_device *link = local->finder;
702
703 if (!(pcmcia_dev_present(link))) {
704 dev_dbg(&link->dev, "ray_cs join_net - device not present\n");
705 return;
706 }
707
708 if ((ccsindex = get_free_ccs(local)) < 0)
709 return;
710 pccs = ccs_base(local) + ccsindex;
711 writeb(CCS_JOIN_NETWORK, &pccs->cmd);
712 writeb(0, &pccs->var.join_network.update_param);
713 writeb(0, &pccs->var.join_network.net_initiated);
714
715 if (interrupt_ecf(local, ccsindex)) {
716 dev_dbg(&link->dev, "ray join net failed - card not ready for intr\n");
717 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
718 return;
719 }
720 local->card_status = CARD_DOING_ACQ;
721}
722
723
724static void ray_release(struct pcmcia_device *link)
725{
726 struct net_device *dev = link->priv;
727 ray_dev_t *local = netdev_priv(dev);
728
729 dev_dbg(&link->dev, "ray_release\n");
730
731 del_timer(&local->timer);
732
733 iounmap(local->sram);
734 iounmap(local->rmem);
735 iounmap(local->amem);
736 pcmcia_disable_device(link);
737
738 dev_dbg(&link->dev, "ray_release ending\n");
739}
740
741static int ray_suspend(struct pcmcia_device *link)
742{
743 struct net_device *dev = link->priv;
744
745 if (link->open)
746 netif_device_detach(dev);
747
748 return 0;
749}
750
751static int ray_resume(struct pcmcia_device *link)
752{
753 struct net_device *dev = link->priv;
754
755 if (link->open) {
756 ray_reset(dev);
757 netif_device_attach(dev);
758 }
759
760 return 0;
761}
762
763
764static int ray_dev_init(struct net_device *dev)
765{
766#ifdef RAY_IMMEDIATE_INIT
767 int i;
768#endif
769 ray_dev_t *local = netdev_priv(dev);
770 struct pcmcia_device *link = local->finder;
771
772 dev_dbg(&link->dev, "ray_dev_init(dev=%p)\n", dev);
773 if (!(pcmcia_dev_present(link))) {
774 dev_dbg(&link->dev, "ray_dev_init - device not present\n");
775 return -1;
776 }
777#ifdef RAY_IMMEDIATE_INIT
778
779 if ((i = dl_startup_params(dev)) < 0) {
780 printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
781 "returns 0x%x\n", i);
782 return -1;
783 }
784#else
785
786
787
788 dev_dbg(&link->dev,
789 "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
790 local->card_status);
791#endif
792
793
794 memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
795 eth_broadcast_addr(dev->broadcast);
796
797 dev_dbg(&link->dev, "ray_dev_init ending\n");
798 return 0;
799}
800
801
802static int ray_dev_config(struct net_device *dev, struct ifmap *map)
803{
804 ray_dev_t *local = netdev_priv(dev);
805 struct pcmcia_device *link = local->finder;
806
807 dev_dbg(&link->dev, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
808 if (!(pcmcia_dev_present(link))) {
809 dev_dbg(&link->dev, "ray_dev_config - device not present\n");
810 return -1;
811 }
812
813 return 0;
814}
815
816
817static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
818 struct net_device *dev)
819{
820 ray_dev_t *local = netdev_priv(dev);
821 struct pcmcia_device *link = local->finder;
822 short length = skb->len;
823
824 if (!pcmcia_dev_present(link)) {
825 dev_dbg(&link->dev, "ray_dev_start_xmit - device not present\n");
826 dev_kfree_skb(skb);
827 return NETDEV_TX_OK;
828 }
829
830 dev_dbg(&link->dev, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
831 if (local->authentication_state == NEED_TO_AUTH) {
832 dev_dbg(&link->dev, "ray_cs Sending authentication request.\n");
833 if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
834 local->authentication_state = AUTHENTICATED;
835 netif_stop_queue(dev);
836 return NETDEV_TX_BUSY;
837 }
838 }
839
840 if (length < ETH_ZLEN) {
841 if (skb_padto(skb, ETH_ZLEN))
842 return NETDEV_TX_OK;
843 length = ETH_ZLEN;
844 }
845 switch (ray_hw_xmit(skb->data, length, dev, DATA_TYPE)) {
846 case XMIT_NO_CCS:
847 case XMIT_NEED_AUTH:
848 netif_stop_queue(dev);
849 return NETDEV_TX_BUSY;
850 case XMIT_NO_INTR:
851 case XMIT_MSG_BAD:
852 case XMIT_OK:
853 default:
854 dev_kfree_skb(skb);
855 }
856
857 return NETDEV_TX_OK;
858}
859
860
861static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
862 UCHAR msg_type)
863{
864 ray_dev_t *local = netdev_priv(dev);
865 struct ccs __iomem *pccs;
866 int ccsindex;
867 int offset;
868 struct tx_msg __iomem *ptx;
869 short int addr;
870
871 pr_debug("ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
872 if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
873 printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
874 len);
875 return XMIT_MSG_BAD;
876 }
877 switch (ccsindex = get_free_tx_ccs(local)) {
878 case ECCSBUSY:
879 pr_debug("ray_hw_xmit tx_ccs table busy\n");
880 fallthrough;
881 case ECCSFULL:
882 pr_debug("ray_hw_xmit No free tx ccs\n");
883 fallthrough;
884 case ECARDGONE:
885 netif_stop_queue(dev);
886 return XMIT_NO_CCS;
887 default:
888 break;
889 }
890 addr = TX_BUF_BASE + (ccsindex << 11);
891
892 if (msg_type == DATA_TYPE) {
893 local->stats.tx_bytes += len;
894 local->stats.tx_packets++;
895 }
896
897 ptx = local->sram + addr;
898
899 ray_build_header(local, ptx, msg_type, data);
900 if (translate) {
901 offset = translate_frame(local, ptx, data, len);
902 } else {
903
904 memcpy_toio(&ptx->var, data, len);
905 offset = 0;
906 }
907
908
909 pccs = ccs_base(local) + ccsindex;
910 len += TX_HEADER_LENGTH + offset;
911 writeb(CCS_TX_REQUEST, &pccs->cmd);
912 writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
913 writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
914 writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
915 writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
916
917 writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
918 writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
919 writeb(0, &pccs->var.tx_request.antenna);
920 pr_debug("ray_hw_xmit default_tx_rate = 0x%x\n",
921 local->net_default_tx_rate);
922
923
924 if (interrupt_ecf(local, ccsindex)) {
925 pr_debug("ray_hw_xmit failed - ECF not ready for intr\n");
926
927
928
929
930 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
931 return XMIT_NO_INTR;
932 }
933 return XMIT_OK;
934}
935
936
937static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
938 unsigned char *data, int len)
939{
940 __be16 proto = ((struct ethhdr *)data)->h_proto;
941 if (ntohs(proto) >= ETH_P_802_3_MIN) {
942 pr_debug("ray_cs translate_frame DIX II\n");
943
944 memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
945 memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
946 (UCHAR *) &proto, 2);
947 if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
948
949 writeb(0xf8,
950 &((struct snaphdr_t __iomem *)ptx->var)->org[2]);
951 }
952
953 memcpy_toio((void __iomem *)&ptx->var +
954 sizeof(struct snaphdr_t), data + ETH_HLEN,
955 len - ETH_HLEN);
956 return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
957 } else {
958 pr_debug("ray_cs translate_frame 802\n");
959 if (proto == htons(0xffff)) {
960 pr_debug("ray_cs translate_frame evil IPX\n");
961 memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
962 return 0 - ETH_HLEN;
963 }
964 memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
965 return 0 - ETH_HLEN;
966 }
967
968}
969
970
971static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
972 UCHAR msg_type, unsigned char *data)
973{
974 writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
975
976
977
978
979
980
981
982 if (local->net_type == ADHOC) {
983 writeb(0, &ptx->mac.frame_ctl_2);
984 memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest,
985 ADDRLEN);
986 memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source,
987 ADDRLEN);
988 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
989 } else {
990
991 if (local->sparm.b4.a_acting_as_ap_status) {
992 writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
993 memcpy_toio(ptx->mac.addr_1,
994 ((struct ethhdr *)data)->h_dest, ADDRLEN);
995 memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
996 memcpy_toio(ptx->mac.addr_3,
997 ((struct ethhdr *)data)->h_source, ADDRLEN);
998 } else {
999
1000 writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
1001 memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
1002 memcpy_toio(ptx->mac.addr_2,
1003 ((struct ethhdr *)data)->h_source, ADDRLEN);
1004 memcpy_toio(ptx->mac.addr_3,
1005 ((struct ethhdr *)data)->h_dest, ADDRLEN);
1006 }
1007 }
1008}
1009
1010
1011
1012
1013
1014
1015
1016static int ray_get_name(struct net_device *dev, struct iw_request_info *info,
1017 union iwreq_data *wrqu, char *extra)
1018{
1019 strcpy(wrqu->name, "IEEE 802.11-FH");
1020 return 0;
1021}
1022
1023
1024
1025
1026
1027static int ray_set_freq(struct net_device *dev, struct iw_request_info *info,
1028 union iwreq_data *wrqu, char *extra)
1029{
1030 ray_dev_t *local = netdev_priv(dev);
1031 int err = -EINPROGRESS;
1032
1033
1034 if (local->card_status != CARD_AWAITING_PARAM)
1035 return -EBUSY;
1036
1037
1038 if ((wrqu->freq.m > USA_HOP_MOD) || (wrqu->freq.e > 0))
1039 err = -EOPNOTSUPP;
1040 else
1041 local->sparm.b5.a_hop_pattern = wrqu->freq.m;
1042
1043 return err;
1044}
1045
1046
1047
1048
1049
1050static int ray_get_freq(struct net_device *dev, struct iw_request_info *info,
1051 union iwreq_data *wrqu, char *extra)
1052{
1053 ray_dev_t *local = netdev_priv(dev);
1054
1055 wrqu->freq.m = local->sparm.b5.a_hop_pattern;
1056 wrqu->freq.e = 0;
1057 return 0;
1058}
1059
1060
1061
1062
1063
1064static int ray_set_essid(struct net_device *dev, struct iw_request_info *info,
1065 union iwreq_data *wrqu, char *extra)
1066{
1067 ray_dev_t *local = netdev_priv(dev);
1068
1069
1070 if (local->card_status != CARD_AWAITING_PARAM)
1071 return -EBUSY;
1072
1073
1074 if (wrqu->essid.flags == 0)
1075
1076 return -EOPNOTSUPP;
1077
1078
1079 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1080 return -E2BIG;
1081
1082
1083 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1084 memcpy(local->sparm.b5.a_current_ess_id, extra, wrqu->essid.length);
1085
1086 return -EINPROGRESS;
1087}
1088
1089
1090
1091
1092
1093static int ray_get_essid(struct net_device *dev, struct iw_request_info *info,
1094 union iwreq_data *wrqu, char *extra)
1095{
1096 ray_dev_t *local = netdev_priv(dev);
1097 UCHAR tmp[IW_ESSID_MAX_SIZE + 1];
1098
1099
1100 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1101 memcpy(tmp, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1102 tmp[IW_ESSID_MAX_SIZE] = '\0';
1103
1104
1105 wrqu->essid.length = strlen(tmp);
1106 wrqu->essid.flags = 1;
1107
1108 return 0;
1109}
1110
1111
1112
1113
1114
1115static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1116 union iwreq_data *wrqu, char *extra)
1117{
1118 ray_dev_t *local = netdev_priv(dev);
1119
1120 memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1121 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1122
1123 return 0;
1124}
1125
1126
1127
1128
1129
1130static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1131 union iwreq_data *wrqu, char *extra)
1132{
1133 ray_dev_t *local = netdev_priv(dev);
1134
1135
1136 if (local->card_status != CARD_AWAITING_PARAM)
1137 return -EBUSY;
1138
1139
1140 if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1141 return -EINVAL;
1142
1143
1144 if ((local->fw_ver == 0x55) &&
1145 (wrqu->bitrate.value == 2000000))
1146 local->net_default_tx_rate = 3;
1147 else
1148 local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1149
1150 return 0;
1151}
1152
1153
1154
1155
1156
1157static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1158 union iwreq_data *wrqu, char *extra)
1159{
1160 ray_dev_t *local = netdev_priv(dev);
1161
1162 if (local->net_default_tx_rate == 3)
1163 wrqu->bitrate.value = 2000000;
1164 else
1165 wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1166 wrqu->bitrate.fixed = 0;
1167
1168 return 0;
1169}
1170
1171
1172
1173
1174
1175static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1176 union iwreq_data *wrqu, char *extra)
1177{
1178 ray_dev_t *local = netdev_priv(dev);
1179 int rthr = wrqu->rts.value;
1180
1181
1182 if (local->card_status != CARD_AWAITING_PARAM)
1183 return -EBUSY;
1184
1185
1186 if (wrqu->rts.disabled)
1187 rthr = 32767;
1188 else {
1189 if ((rthr < 0) || (rthr > 2347))
1190 return -EINVAL;
1191 }
1192 local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1193 local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1194
1195 return -EINPROGRESS;
1196}
1197
1198
1199
1200
1201
1202static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1203 union iwreq_data *wrqu, char *extra)
1204{
1205 ray_dev_t *local = netdev_priv(dev);
1206
1207 wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1208 + local->sparm.b5.a_rts_threshold[1];
1209 wrqu->rts.disabled = (wrqu->rts.value == 32767);
1210 wrqu->rts.fixed = 1;
1211
1212 return 0;
1213}
1214
1215
1216
1217
1218
1219static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1220 union iwreq_data *wrqu, char *extra)
1221{
1222 ray_dev_t *local = netdev_priv(dev);
1223 int fthr = wrqu->frag.value;
1224
1225
1226 if (local->card_status != CARD_AWAITING_PARAM)
1227 return -EBUSY;
1228
1229
1230 if (wrqu->frag.disabled)
1231 fthr = 32767;
1232 else {
1233 if ((fthr < 256) || (fthr > 2347))
1234 return -EINVAL;
1235 }
1236 local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1237 local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1238
1239 return -EINPROGRESS;
1240}
1241
1242
1243
1244
1245
1246static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1247 union iwreq_data *wrqu, char *extra)
1248{
1249 ray_dev_t *local = netdev_priv(dev);
1250
1251 wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1252 + local->sparm.b5.a_frag_threshold[1];
1253 wrqu->frag.disabled = (wrqu->frag.value == 32767);
1254 wrqu->frag.fixed = 1;
1255
1256 return 0;
1257}
1258
1259
1260
1261
1262
1263static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1264 union iwreq_data *wrqu, char *extra)
1265{
1266 ray_dev_t *local = netdev_priv(dev);
1267 int err = -EINPROGRESS;
1268 char card_mode = 1;
1269
1270
1271 if (local->card_status != CARD_AWAITING_PARAM)
1272 return -EBUSY;
1273
1274 switch (wrqu->mode) {
1275 case IW_MODE_ADHOC:
1276 card_mode = 0;
1277 fallthrough;
1278 case IW_MODE_INFRA:
1279 local->sparm.b5.a_network_type = card_mode;
1280 break;
1281 default:
1282 err = -EINVAL;
1283 }
1284
1285 return err;
1286}
1287
1288
1289
1290
1291
1292static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1293 union iwreq_data *wrqu, char *extra)
1294{
1295 ray_dev_t *local = netdev_priv(dev);
1296
1297 if (local->sparm.b5.a_network_type)
1298 wrqu->mode = IW_MODE_INFRA;
1299 else
1300 wrqu->mode = IW_MODE_ADHOC;
1301
1302 return 0;
1303}
1304
1305
1306
1307
1308
1309static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1310 union iwreq_data *wrqu, char *extra)
1311{
1312 struct iw_range *range = (struct iw_range *)extra;
1313
1314 memset(range, 0, sizeof(struct iw_range));
1315
1316
1317 wrqu->data.length = sizeof(struct iw_range);
1318
1319
1320 range->we_version_compiled = WIRELESS_EXT;
1321 range->we_version_source = 9;
1322
1323
1324 range->throughput = 1.1 * 1000 * 1000;
1325 range->num_channels = hop_pattern_length[(int)country];
1326 range->num_frequency = 0;
1327 range->max_qual.qual = 0;
1328 range->max_qual.level = 255;
1329 range->max_qual.noise = 255;
1330 range->num_bitrates = 2;
1331 range->bitrate[0] = 1000000;
1332 range->bitrate[1] = 2000000;
1333 return 0;
1334}
1335
1336
1337
1338
1339
1340static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1341 union iwreq_data *wrqu, char *extra)
1342{
1343 translate = !!*(extra);
1344
1345 return 0;
1346}
1347
1348
1349
1350
1351
1352static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1353 union iwreq_data *wrqu, char *extra)
1354{
1355 *(extra) = translate;
1356
1357 return 0;
1358}
1359
1360
1361
1362
1363
1364static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1365 union iwreq_data *wrqu, char *extra)
1366{
1367 *(extra) = country;
1368
1369 return 0;
1370}
1371
1372
1373
1374
1375
1376static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1377 union iwreq_data *wrqu, char *extra)
1378{
1379 return 0;
1380}
1381
1382
1383
1384
1385
1386static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1387{
1388 ray_dev_t *local = netdev_priv(dev);
1389 struct pcmcia_device *link = local->finder;
1390 struct status __iomem *p = local->sram + STATUS_BASE;
1391
1392 local->wstats.status = local->card_status;
1393#ifdef WIRELESS_SPY
1394 if ((local->spy_data.spy_number > 0)
1395 && (local->sparm.b5.a_network_type == 0)) {
1396
1397 local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
1398 local->wstats.qual.level = local->spy_data.spy_stat[0].level;
1399 local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
1400 local->wstats.qual.updated =
1401 local->spy_data.spy_stat[0].updated;
1402 }
1403#endif
1404
1405 if (pcmcia_dev_present(link)) {
1406 local->wstats.qual.noise = readb(&p->rxnoise);
1407 local->wstats.qual.updated |= 4;
1408 }
1409
1410 return &local->wstats;
1411}
1412
1413
1414
1415
1416
1417
1418static const iw_handler ray_handler[] = {
1419 IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1420 IW_HANDLER(SIOCGIWNAME, ray_get_name),
1421 IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1422 IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1423 IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1424 IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1425 IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1426#ifdef WIRELESS_SPY
1427 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1428 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1429 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1430 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1431#endif
1432 IW_HANDLER(SIOCGIWAP, ray_get_wap),
1433 IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1434 IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1435 IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1436 IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1437 IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1438 IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1439 IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1440 IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1441};
1442
1443#define SIOCSIPFRAMING SIOCIWFIRSTPRIV
1444#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1
1445#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3
1446
1447static const iw_handler ray_private_handler[] = {
1448 [0] = ray_set_framing,
1449 [1] = ray_get_framing,
1450 [3] = ray_get_country,
1451};
1452
1453static const struct iw_priv_args ray_private_args[] = {
1454
1455 {SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
1456 "set_framing"},
1457 {SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1458 "get_framing"},
1459 {SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1460 "get_country"},
1461};
1462
1463static const struct iw_handler_def ray_handler_def = {
1464 .num_standard = ARRAY_SIZE(ray_handler),
1465 .num_private = ARRAY_SIZE(ray_private_handler),
1466 .num_private_args = ARRAY_SIZE(ray_private_args),
1467 .standard = ray_handler,
1468 .private = ray_private_handler,
1469 .private_args = ray_private_args,
1470 .get_wireless_stats = ray_get_wireless_stats,
1471};
1472
1473
1474static int ray_open(struct net_device *dev)
1475{
1476 ray_dev_t *local = netdev_priv(dev);
1477 struct pcmcia_device *link;
1478 link = local->finder;
1479
1480 dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
1481
1482 if (link->open == 0)
1483 local->num_multi = 0;
1484 link->open++;
1485
1486
1487 if (local->card_status == CARD_AWAITING_PARAM) {
1488 int i;
1489
1490 dev_dbg(&link->dev, "ray_open: doing init now !\n");
1491
1492
1493 if ((i = dl_startup_params(dev)) < 0) {
1494 printk(KERN_INFO
1495 "ray_dev_init dl_startup_params failed - "
1496 "returns 0x%x\n", i);
1497 return -1;
1498 }
1499 }
1500
1501 if (sniffer)
1502 netif_stop_queue(dev);
1503 else
1504 netif_start_queue(dev);
1505
1506 dev_dbg(&link->dev, "ray_open ending\n");
1507 return 0;
1508}
1509
1510
1511static int ray_dev_close(struct net_device *dev)
1512{
1513 ray_dev_t *local = netdev_priv(dev);
1514 struct pcmcia_device *link;
1515 link = local->finder;
1516
1517 dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
1518
1519 link->open--;
1520 netif_stop_queue(dev);
1521
1522
1523
1524
1525
1526
1527 return 0;
1528}
1529
1530
1531static void ray_reset(struct net_device *dev)
1532{
1533 pr_debug("ray_reset entered\n");
1534}
1535
1536
1537
1538
1539static int interrupt_ecf(ray_dev_t *local, int ccs)
1540{
1541 int i = 50;
1542 struct pcmcia_device *link = local->finder;
1543
1544 if (!(pcmcia_dev_present(link))) {
1545 dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
1546 return -1;
1547 }
1548 dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
1549
1550 while (i &&
1551 (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
1552 ECF_INTR_SET))
1553 i--;
1554 if (i == 0) {
1555 dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
1556 return -1;
1557 }
1558
1559 writeb(ccs, local->sram + SCB_BASE);
1560 writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1561 return 0;
1562}
1563
1564
1565
1566
1567static int get_free_tx_ccs(ray_dev_t *local)
1568{
1569 int i;
1570 struct ccs __iomem *pccs = ccs_base(local);
1571 struct pcmcia_device *link = local->finder;
1572
1573 if (!(pcmcia_dev_present(link))) {
1574 dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
1575 return ECARDGONE;
1576 }
1577
1578 if (test_and_set_bit(0, &local->tx_ccs_lock)) {
1579 dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
1580 return ECCSBUSY;
1581 }
1582
1583 for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
1584 if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1585 writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1586 writeb(CCS_END_LIST, &(pccs + i)->link);
1587 local->tx_ccs_lock = 0;
1588 return i;
1589 }
1590 }
1591 local->tx_ccs_lock = 0;
1592 dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
1593 return ECCSFULL;
1594}
1595
1596
1597
1598
1599static int get_free_ccs(ray_dev_t *local)
1600{
1601 int i;
1602 struct ccs __iomem *pccs = ccs_base(local);
1603 struct pcmcia_device *link = local->finder;
1604
1605 if (!(pcmcia_dev_present(link))) {
1606 dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
1607 return ECARDGONE;
1608 }
1609 if (test_and_set_bit(0, &local->ccs_lock)) {
1610 dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
1611 return ECCSBUSY;
1612 }
1613
1614 for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1615 if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1616 writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1617 writeb(CCS_END_LIST, &(pccs + i)->link);
1618 local->ccs_lock = 0;
1619 return i;
1620 }
1621 }
1622 local->ccs_lock = 0;
1623 dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
1624 return ECCSFULL;
1625}
1626
1627
1628static void authenticate_timeout(struct timer_list *t)
1629{
1630 ray_dev_t *local = from_timer(local, t, timer);
1631 del_timer(&local->timer);
1632 printk(KERN_INFO "ray_cs Authentication with access point failed"
1633 " - timeout\n");
1634 join_net(&local->timer);
1635}
1636
1637
1638static int parse_addr(char *in_str, UCHAR *out)
1639{
1640 int len;
1641 int i, j, k;
1642 int status;
1643
1644 if (in_str == NULL)
1645 return 0;
1646 if ((len = strlen(in_str)) < 2)
1647 return 0;
1648 memset(out, 0, ADDRLEN);
1649
1650 status = 1;
1651 j = len - 1;
1652 if (j > 12)
1653 j = 12;
1654 i = 5;
1655
1656 while (j > 0) {
1657 if ((k = hex_to_bin(in_str[j--])) != -1)
1658 out[i] = k;
1659 else
1660 return 0;
1661
1662 if (j == 0)
1663 break;
1664 if ((k = hex_to_bin(in_str[j--])) != -1)
1665 out[i] += k << 4;
1666 else
1667 return 0;
1668 if (!i--)
1669 break;
1670 }
1671 return status;
1672}
1673
1674
1675static struct net_device_stats *ray_get_stats(struct net_device *dev)
1676{
1677 ray_dev_t *local = netdev_priv(dev);
1678 struct pcmcia_device *link = local->finder;
1679 struct status __iomem *p = local->sram + STATUS_BASE;
1680 if (!(pcmcia_dev_present(link))) {
1681 dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
1682 return &local->stats;
1683 }
1684 if (readb(&p->mrx_overflow_for_host)) {
1685 local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
1686 writeb(0, &p->mrx_overflow);
1687 writeb(0, &p->mrx_overflow_for_host);
1688 }
1689 if (readb(&p->mrx_checksum_error_for_host)) {
1690 local->stats.rx_crc_errors +=
1691 swab16(readw(&p->mrx_checksum_error));
1692 writeb(0, &p->mrx_checksum_error);
1693 writeb(0, &p->mrx_checksum_error_for_host);
1694 }
1695 if (readb(&p->rx_hec_error_for_host)) {
1696 local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
1697 writeb(0, &p->rx_hec_error);
1698 writeb(0, &p->rx_hec_error_for_host);
1699 }
1700 return &local->stats;
1701}
1702
1703
1704static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
1705 int len)
1706{
1707 ray_dev_t *local = netdev_priv(dev);
1708 struct pcmcia_device *link = local->finder;
1709 int ccsindex;
1710 int i;
1711 struct ccs __iomem *pccs;
1712
1713 if (!(pcmcia_dev_present(link))) {
1714 dev_dbg(&link->dev, "ray_update_parm - device not present\n");
1715 return;
1716 }
1717
1718 if ((ccsindex = get_free_ccs(local)) < 0) {
1719 dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
1720 return;
1721 }
1722 pccs = ccs_base(local) + ccsindex;
1723 writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1724 writeb(objid, &pccs->var.update_param.object_id);
1725 writeb(1, &pccs->var.update_param.number_objects);
1726 writeb(0, &pccs->var.update_param.failure_cause);
1727 for (i = 0; i < len; i++) {
1728 writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1729 }
1730
1731 if (interrupt_ecf(local, ccsindex)) {
1732 dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
1733 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1734 }
1735}
1736
1737
1738static void ray_update_multi_list(struct net_device *dev, int all)
1739{
1740 int ccsindex;
1741 struct ccs __iomem *pccs;
1742 ray_dev_t *local = netdev_priv(dev);
1743 struct pcmcia_device *link = local->finder;
1744 void __iomem *p = local->sram + HOST_TO_ECF_BASE;
1745
1746 if (!(pcmcia_dev_present(link))) {
1747 dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
1748 return;
1749 } else
1750 dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
1751 if ((ccsindex = get_free_ccs(local)) < 0) {
1752 dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
1753 return;
1754 }
1755 pccs = ccs_base(local) + ccsindex;
1756 writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
1757
1758 if (all) {
1759 writeb(0xff, &pccs->var);
1760 local->num_multi = 0xff;
1761 } else {
1762 struct netdev_hw_addr *ha;
1763 int i = 0;
1764
1765
1766 netdev_for_each_mc_addr(ha, dev) {
1767 memcpy_toio(p, ha->addr, ETH_ALEN);
1768 dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
1769 ha->addr);
1770 p += ETH_ALEN;
1771 i++;
1772 }
1773 if (i > 256 / ADDRLEN)
1774 i = 256 / ADDRLEN;
1775 writeb((UCHAR) i, &pccs->var);
1776 dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
1777
1778 local->num_multi = i;
1779 }
1780 if (interrupt_ecf(local, ccsindex)) {
1781 dev_dbg(&link->dev,
1782 "ray_cs update_multi failed - ECF not ready for intr\n");
1783 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1784 }
1785}
1786
1787
1788static void set_multicast_list(struct net_device *dev)
1789{
1790 ray_dev_t *local = netdev_priv(dev);
1791 UCHAR promisc;
1792
1793 pr_debug("ray_cs set_multicast_list(%p)\n", dev);
1794
1795 if (dev->flags & IFF_PROMISC) {
1796 if (local->sparm.b5.a_promiscuous_mode == 0) {
1797 pr_debug("ray_cs set_multicast_list promisc on\n");
1798 local->sparm.b5.a_promiscuous_mode = 1;
1799 promisc = 1;
1800 ray_update_parm(dev, OBJID_promiscuous_mode,
1801 &promisc, sizeof(promisc));
1802 }
1803 } else {
1804 if (local->sparm.b5.a_promiscuous_mode == 1) {
1805 pr_debug("ray_cs set_multicast_list promisc off\n");
1806 local->sparm.b5.a_promiscuous_mode = 0;
1807 promisc = 0;
1808 ray_update_parm(dev, OBJID_promiscuous_mode,
1809 &promisc, sizeof(promisc));
1810 }
1811 }
1812
1813 if (dev->flags & IFF_ALLMULTI)
1814 ray_update_multi_list(dev, 1);
1815 else {
1816 if (local->num_multi != netdev_mc_count(dev))
1817 ray_update_multi_list(dev, 0);
1818 }
1819}
1820
1821
1822
1823
1824static irqreturn_t ray_interrupt(int irq, void *dev_id)
1825{
1826 struct net_device *dev = (struct net_device *)dev_id;
1827 struct pcmcia_device *link;
1828 ray_dev_t *local;
1829 struct ccs __iomem *pccs;
1830 struct rcs __iomem *prcs;
1831 UCHAR rcsindex;
1832 UCHAR tmp;
1833 UCHAR cmd;
1834 UCHAR status;
1835 UCHAR memtmp[ESSID_SIZE + 1];
1836
1837
1838 if (dev == NULL)
1839 return IRQ_NONE;
1840
1841 pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
1842
1843 local = netdev_priv(dev);
1844 link = local->finder;
1845 if (!pcmcia_dev_present(link)) {
1846 pr_debug(
1847 "ray_cs interrupt from device not present or suspended.\n");
1848 return IRQ_NONE;
1849 }
1850 rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
1851
1852 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
1853 dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
1854 clear_interrupt(local);
1855 return IRQ_HANDLED;
1856 }
1857 if (rcsindex < NUMBER_OF_CCS) {
1858 pccs = ccs_base(local) + rcsindex;
1859 cmd = readb(&pccs->cmd);
1860 status = readb(&pccs->buffer_status);
1861 switch (cmd) {
1862 case CCS_DOWNLOAD_STARTUP_PARAMS:
1863 del_timer(&local->timer);
1864 if (status == CCS_COMMAND_COMPLETE) {
1865 dev_dbg(&link->dev,
1866 "ray_cs interrupt download_startup_parameters OK\n");
1867 } else {
1868 dev_dbg(&link->dev,
1869 "ray_cs interrupt download_startup_parameters fail\n");
1870 }
1871 break;
1872 case CCS_UPDATE_PARAMS:
1873 dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
1874 if (status != CCS_COMMAND_COMPLETE) {
1875 tmp =
1876 readb(&pccs->var.update_param.
1877 failure_cause);
1878 dev_dbg(&link->dev,
1879 "ray_cs interrupt update params failed - reason %d\n",
1880 tmp);
1881 }
1882 break;
1883 case CCS_REPORT_PARAMS:
1884 dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
1885 break;
1886 case CCS_UPDATE_MULTICAST_LIST:
1887 dev_dbg(&link->dev,
1888 "ray_cs interrupt CCS Update Multicast List done\n");
1889 break;
1890 case CCS_UPDATE_POWER_SAVINGS_MODE:
1891 dev_dbg(&link->dev,
1892 "ray_cs interrupt update power save mode done\n");
1893 break;
1894 case CCS_START_NETWORK:
1895 case CCS_JOIN_NETWORK:
1896 memcpy(memtmp, local->sparm.b4.a_current_ess_id,
1897 ESSID_SIZE);
1898 memtmp[ESSID_SIZE] = '\0';
1899
1900 if (status == CCS_COMMAND_COMPLETE) {
1901 if (readb
1902 (&pccs->var.start_network.net_initiated) ==
1903 1) {
1904 dev_dbg(&link->dev,
1905 "ray_cs interrupt network \"%s\" started\n",
1906 memtmp);
1907 } else {
1908 dev_dbg(&link->dev,
1909 "ray_cs interrupt network \"%s\" joined\n",
1910 memtmp);
1911 }
1912 memcpy_fromio(&local->bss_id,
1913 pccs->var.start_network.bssid,
1914 ADDRLEN);
1915
1916 if (local->fw_ver == 0x55)
1917 local->net_default_tx_rate = 3;
1918 else
1919 local->net_default_tx_rate =
1920 readb(&pccs->var.start_network.
1921 net_default_tx_rate);
1922 local->encryption =
1923 readb(&pccs->var.start_network.encryption);
1924 if (!sniffer && (local->net_type == INFRA)
1925 && !(local->sparm.b4.a_acting_as_ap_status)) {
1926 authenticate(local);
1927 }
1928 local->card_status = CARD_ACQ_COMPLETE;
1929 } else {
1930 local->card_status = CARD_ACQ_FAILED;
1931
1932 del_timer(&local->timer);
1933 local->timer.expires = jiffies + HZ * 5;
1934 if (status == CCS_START_NETWORK) {
1935 dev_dbg(&link->dev,
1936 "ray_cs interrupt network \"%s\" start failed\n",
1937 memtmp);
1938 local->timer.function = start_net;
1939 } else {
1940 dev_dbg(&link->dev,
1941 "ray_cs interrupt network \"%s\" join failed\n",
1942 memtmp);
1943 local->timer.function = join_net;
1944 }
1945 add_timer(&local->timer);
1946 }
1947 break;
1948 case CCS_START_ASSOCIATION:
1949 if (status == CCS_COMMAND_COMPLETE) {
1950 local->card_status = CARD_ASSOC_COMPLETE;
1951 dev_dbg(&link->dev, "ray_cs association successful\n");
1952 } else {
1953 dev_dbg(&link->dev, "ray_cs association failed,\n");
1954 local->card_status = CARD_ASSOC_FAILED;
1955 join_net(&local->timer);
1956 }
1957 break;
1958 case CCS_TX_REQUEST:
1959 if (status == CCS_COMMAND_COMPLETE) {
1960 dev_dbg(&link->dev,
1961 "ray_cs interrupt tx request complete\n");
1962 } else {
1963 dev_dbg(&link->dev,
1964 "ray_cs interrupt tx request failed\n");
1965 }
1966 if (!sniffer)
1967 netif_start_queue(dev);
1968 netif_wake_queue(dev);
1969 break;
1970 case CCS_TEST_MEMORY:
1971 dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
1972 break;
1973 case CCS_SHUTDOWN:
1974 dev_dbg(&link->dev,
1975 "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
1976 break;
1977 case CCS_DUMP_MEMORY:
1978 dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
1979 break;
1980 case CCS_START_TIMER:
1981 dev_dbg(&link->dev,
1982 "ray_cs interrupt DING - raylink timer expired\n");
1983 break;
1984 default:
1985 dev_dbg(&link->dev,
1986 "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
1987 rcsindex, cmd);
1988 }
1989 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1990 } else {
1991
1992 prcs = rcs_base(local) + rcsindex;
1993
1994 switch (readb(&prcs->interrupt_id)) {
1995 case PROCESS_RX_PACKET:
1996 ray_rx(dev, local, prcs);
1997 break;
1998 case REJOIN_NET_COMPLETE:
1999 dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
2000 local->card_status = CARD_ACQ_COMPLETE;
2001
2002 if (local->sparm.b4.a_network_type == ADHOC) {
2003 if (!sniffer)
2004 netif_start_queue(dev);
2005 } else {
2006 memcpy_fromio(&local->bss_id,
2007 prcs->var.rejoin_net_complete.
2008 bssid, ADDRLEN);
2009 dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
2010 local->bss_id);
2011 if (!sniffer)
2012 authenticate(local);
2013 }
2014 break;
2015 case ROAMING_INITIATED:
2016 dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
2017 netif_stop_queue(dev);
2018 local->card_status = CARD_DOING_ACQ;
2019 break;
2020 case JAPAN_CALL_SIGN_RXD:
2021 dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
2022 break;
2023 default:
2024 dev_dbg(&link->dev,
2025 "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
2026 rcsindex,
2027 (unsigned int)readb(&prcs->interrupt_id));
2028 break;
2029 }
2030 writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
2031 }
2032 clear_interrupt(local);
2033 return IRQ_HANDLED;
2034}
2035
2036
2037static void ray_rx(struct net_device *dev, ray_dev_t *local,
2038 struct rcs __iomem *prcs)
2039{
2040 int rx_len;
2041 unsigned int pkt_addr;
2042 void __iomem *pmsg;
2043 pr_debug("ray_rx process rx packet\n");
2044
2045
2046 pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
2047 + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
2048
2049 rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
2050 + readb(&prcs->var.rx_packet.rx_data_length[1]);
2051
2052 local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
2053 pmsg = local->rmem + pkt_addr;
2054 switch (readb(pmsg)) {
2055 case DATA_TYPE:
2056 pr_debug("ray_rx data type\n");
2057 rx_data(dev, prcs, pkt_addr, rx_len);
2058 break;
2059 case AUTHENTIC_TYPE:
2060 pr_debug("ray_rx authentic type\n");
2061 if (sniffer)
2062 rx_data(dev, prcs, pkt_addr, rx_len);
2063 else
2064 rx_authenticate(local, prcs, pkt_addr, rx_len);
2065 break;
2066 case DEAUTHENTIC_TYPE:
2067 pr_debug("ray_rx deauth type\n");
2068 if (sniffer)
2069 rx_data(dev, prcs, pkt_addr, rx_len);
2070 else
2071 rx_deauthenticate(local, prcs, pkt_addr, rx_len);
2072 break;
2073 case NULL_MSG_TYPE:
2074 pr_debug("ray_cs rx NULL msg\n");
2075 break;
2076 case BEACON_TYPE:
2077 pr_debug("ray_rx beacon type\n");
2078 if (sniffer)
2079 rx_data(dev, prcs, pkt_addr, rx_len);
2080
2081 copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
2082 rx_len < sizeof(struct beacon_rx) ?
2083 rx_len : sizeof(struct beacon_rx));
2084
2085 local->beacon_rxed = 1;
2086
2087 ray_get_stats(dev);
2088 break;
2089 default:
2090 pr_debug("ray_cs unknown pkt type %2x\n",
2091 (unsigned int)readb(pmsg));
2092 break;
2093 }
2094
2095}
2096
2097
2098static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2099 unsigned int pkt_addr, int rx_len)
2100{
2101 struct sk_buff *skb = NULL;
2102 struct rcs __iomem *prcslink = prcs;
2103 ray_dev_t *local = netdev_priv(dev);
2104 UCHAR *rx_ptr;
2105 int total_len;
2106 int tmp;
2107#ifdef WIRELESS_SPY
2108 int siglev = local->last_rsl;
2109 u_char linksrcaddr[ETH_ALEN];
2110#endif
2111
2112 if (!sniffer) {
2113 if (translate) {
2114
2115 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2116 rx_len >
2117 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2118 FCS_LEN)) {
2119 pr_debug(
2120 "ray_cs invalid packet length %d received\n",
2121 rx_len);
2122 return;
2123 }
2124 } else {
2125
2126 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2127 rx_len >
2128 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2129 FCS_LEN)) {
2130 pr_debug(
2131 "ray_cs invalid packet length %d received\n",
2132 rx_len);
2133 return;
2134 }
2135 }
2136 }
2137 pr_debug("ray_cs rx_data packet\n");
2138
2139 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2140 pr_debug("ray_cs rx'ed fragment\n");
2141 tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
2142 + readb(&prcs->var.rx_packet.totalpacketlength[1]);
2143 total_len = tmp;
2144 prcslink = prcs;
2145 do {
2146 tmp -=
2147 (readb(&prcslink->var.rx_packet.rx_data_length[0])
2148 << 8)
2149 + readb(&prcslink->var.rx_packet.rx_data_length[1]);
2150 if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
2151 == 0xFF || tmp < 0)
2152 break;
2153 prcslink = rcs_base(local)
2154 + readb(&prcslink->link_field);
2155 } while (1);
2156
2157 if (tmp < 0) {
2158 pr_debug(
2159 "ray_cs rx_data fragment lengths don't add up\n");
2160 local->stats.rx_dropped++;
2161 release_frag_chain(local, prcs);
2162 return;
2163 }
2164 } else {
2165 total_len = rx_len;
2166 }
2167
2168 skb = dev_alloc_skb(total_len + 5);
2169 if (skb == NULL) {
2170 pr_debug("ray_cs rx_data could not allocate skb\n");
2171 local->stats.rx_dropped++;
2172 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
2173 release_frag_chain(local, prcs);
2174 return;
2175 }
2176 skb_reserve(skb, 2);
2177
2178 pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
2179 rx_len);
2180
2181
2182
2183 rx_ptr = skb_put(skb, total_len);
2184
2185 rx_ptr +=
2186 copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
2187
2188#ifdef WIRELESS_SPY
2189 skb_copy_from_linear_data_offset(skb,
2190 offsetof(struct mac_header, addr_2),
2191 linksrcaddr, ETH_ALEN);
2192#endif
2193
2194 if (!sniffer) {
2195 if (!translate) {
2196
2197
2198 skb_pull(skb, RX_MAC_HEADER_LENGTH);
2199 } else {
2200
2201 untranslate(local, skb, total_len);
2202 }
2203 } else {
2204 }
2205
2206
2207
2208 tmp = 17;
2209 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2210 prcslink = prcs;
2211 pr_debug("ray_cs rx_data in fragment loop\n");
2212 do {
2213 prcslink = rcs_base(local)
2214 +
2215 readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2216 rx_len =
2217 ((readb(&prcslink->var.rx_packet.rx_data_length[0])
2218 << 8)
2219 +
2220 readb(&prcslink->var.rx_packet.rx_data_length[1]))
2221 & RX_BUFF_END;
2222 pkt_addr =
2223 ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
2224 8)
2225 + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
2226 & RX_BUFF_END;
2227
2228 rx_ptr +=
2229 copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
2230
2231 } while (tmp-- &&
2232 readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
2233 0xFF);
2234 release_frag_chain(local, prcs);
2235 }
2236
2237 skb->protocol = eth_type_trans(skb, dev);
2238 netif_rx(skb);
2239 local->stats.rx_packets++;
2240 local->stats.rx_bytes += total_len;
2241
2242
2243#ifdef WIRELESS_SPY
2244
2245
2246
2247 if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
2248
2249
2250 local->wstats.qual.level = siglev;
2251
2252 local->wstats.qual.updated = 0x2;
2253 }
2254
2255 {
2256 struct iw_quality wstats;
2257 wstats.level = siglev;
2258
2259
2260 wstats.updated = 0x2;
2261
2262 wireless_spy_update(dev, linksrcaddr, &wstats);
2263 }
2264#endif
2265}
2266
2267
2268static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
2269{
2270 snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
2271 struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
2272 __be16 type = *(__be16 *) psnap->ethertype;
2273 int delta;
2274 struct ethhdr *peth;
2275 UCHAR srcaddr[ADDRLEN];
2276 UCHAR destaddr[ADDRLEN];
2277 static const UCHAR org_bridge[3] = { 0, 0, 0xf8 };
2278 static const UCHAR org_1042[3] = { 0, 0, 0 };
2279
2280 memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
2281 memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
2282
2283#if 0
2284 if {
2285 print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
2286 DUMP_PREFIX_NONE, 16, 1,
2287 skb->data, 64, true);
2288 printk(KERN_DEBUG
2289 "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
2290 ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
2291 psnap->org[0], psnap->org[1], psnap->org[2]);
2292 printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
2293 }
2294#endif
2295
2296 if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
2297
2298 pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
2299 psnap->dsap, psnap->ssap, psnap->ctrl);
2300
2301 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2302 peth = (struct ethhdr *)(skb->data + delta);
2303 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2304 } else {
2305 if (memcmp(psnap->org, org_bridge, 3) == 0) {
2306
2307 pr_debug("ray_cs untranslate Bridge encap\n");
2308 delta = RX_MAC_HEADER_LENGTH
2309 + sizeof(struct snaphdr_t) - ETH_HLEN;
2310 peth = (struct ethhdr *)(skb->data + delta);
2311 peth->h_proto = type;
2312 } else if (memcmp(psnap->org, org_1042, 3) == 0) {
2313 switch (ntohs(type)) {
2314 case ETH_P_IPX:
2315 case ETH_P_AARP:
2316 pr_debug("ray_cs untranslate RFC IPX/AARP\n");
2317 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2318 peth = (struct ethhdr *)(skb->data + delta);
2319 peth->h_proto =
2320 htons(len - RX_MAC_HEADER_LENGTH);
2321 break;
2322 default:
2323 pr_debug("ray_cs untranslate RFC default\n");
2324 delta = RX_MAC_HEADER_LENGTH +
2325 sizeof(struct snaphdr_t) - ETH_HLEN;
2326 peth = (struct ethhdr *)(skb->data + delta);
2327 peth->h_proto = type;
2328 break;
2329 }
2330 } else {
2331 printk("ray_cs untranslate very confused by packet\n");
2332 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2333 peth = (struct ethhdr *)(skb->data + delta);
2334 peth->h_proto = type;
2335 }
2336 }
2337
2338 skb_pull(skb, delta);
2339 pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
2340 skb->data);
2341 memcpy(peth->h_dest, destaddr, ADDRLEN);
2342 memcpy(peth->h_source, srcaddr, ADDRLEN);
2343#if 0
2344 {
2345 int i;
2346 printk(KERN_DEBUG "skb->data after untranslate:");
2347 for (i = 0; i < 64; i++)
2348 printk("%02x ", skb->data[i]);
2349 printk("\n");
2350 }
2351#endif
2352}
2353
2354
2355
2356
2357
2358
2359
2360static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
2361 int length)
2362{
2363 int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2364 if (wrap_bytes <= 0) {
2365 memcpy_fromio(dest, local->rmem + pkt_addr, length);
2366 } else {
2367
2368 memcpy_fromio(dest, local->rmem + pkt_addr,
2369 length - wrap_bytes);
2370 memcpy_fromio(dest + length - wrap_bytes, local->rmem,
2371 wrap_bytes);
2372 }
2373 return length;
2374}
2375
2376
2377static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
2378{
2379 struct rcs __iomem *prcslink = prcs;
2380 int tmp = 17;
2381 unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2382
2383 while (tmp--) {
2384 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2385 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2386 pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
2387 rcsindex);
2388 break;
2389 }
2390 prcslink = rcs_base(local) + rcsindex;
2391 rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2392 }
2393 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2394}
2395
2396
2397static void authenticate(ray_dev_t *local)
2398{
2399 struct pcmcia_device *link = local->finder;
2400 dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
2401 if (!(pcmcia_dev_present(link))) {
2402 dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
2403 return;
2404 }
2405
2406 del_timer(&local->timer);
2407 if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2408 local->timer.function = join_net;
2409 } else {
2410 local->timer.function = authenticate_timeout;
2411 }
2412 local->timer.expires = jiffies + HZ * 2;
2413 add_timer(&local->timer);
2414 local->authentication_state = AWAITING_RESPONSE;
2415}
2416
2417
2418static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2419 unsigned int pkt_addr, int rx_len)
2420{
2421 UCHAR buff[256];
2422 struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
2423
2424 del_timer(&local->timer);
2425
2426 copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2427
2428 if (local->sparm.b4.a_network_type == ADHOC) {
2429 pr_debug("ray_cs rx_auth var= %6ph\n", msg->var);
2430 if (msg->var[2] == 1) {
2431 pr_debug("ray_cs Sending authentication response.\n");
2432 if (!build_auth_frame
2433 (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
2434 local->authentication_state = NEED_TO_AUTH;
2435 memcpy(local->auth_id, msg->mac.addr_2,
2436 ADDRLEN);
2437 }
2438 }
2439 } else {
2440
2441 if (local->authentication_state == AWAITING_RESPONSE) {
2442
2443 if (msg->var[2] == 2) {
2444 if ((msg->var[3] | msg->var[4]) == 0) {
2445 pr_debug("Authentication successful\n");
2446 local->card_status = CARD_AUTH_COMPLETE;
2447 associate(local);
2448 local->authentication_state =
2449 AUTHENTICATED;
2450 } else {
2451 pr_debug("Authentication refused\n");
2452 local->card_status = CARD_AUTH_REFUSED;
2453 join_net(&local->timer);
2454 local->authentication_state =
2455 UNAUTHENTICATED;
2456 }
2457 }
2458 }
2459 }
2460
2461}
2462
2463
2464static void associate(ray_dev_t *local)
2465{
2466 struct ccs __iomem *pccs;
2467 struct pcmcia_device *link = local->finder;
2468 struct net_device *dev = link->priv;
2469 int ccsindex;
2470 if (!(pcmcia_dev_present(link))) {
2471 dev_dbg(&link->dev, "ray_cs associate - device not present\n");
2472 return;
2473 }
2474
2475 if ((ccsindex = get_free_ccs(local)) < 0) {
2476
2477 dev_dbg(&link->dev, "ray_cs associate - No free ccs\n");
2478 return;
2479 }
2480 dev_dbg(&link->dev, "ray_cs Starting association with access point\n");
2481 pccs = ccs_base(local) + ccsindex;
2482
2483 writeb(CCS_START_ASSOCIATION, &pccs->cmd);
2484
2485 if (interrupt_ecf(local, ccsindex)) {
2486 dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
2487 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2488
2489 del_timer(&local->timer);
2490 local->timer.expires = jiffies + HZ * 2;
2491 local->timer.function = join_net;
2492 add_timer(&local->timer);
2493 local->card_status = CARD_ASSOC_FAILED;
2494 return;
2495 }
2496 if (!sniffer)
2497 netif_start_queue(dev);
2498
2499}
2500
2501
2502static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2503 unsigned int pkt_addr, int rx_len)
2504{
2505
2506
2507
2508 pr_debug("Deauthentication frame received\n");
2509 local->authentication_state = UNAUTHENTICATED;
2510
2511
2512
2513}
2514
2515
2516static void clear_interrupt(ray_dev_t *local)
2517{
2518 writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
2519}
2520
2521
2522#ifdef CONFIG_PROC_FS
2523#define MAXDATA (PAGE_SIZE - 80)
2524
2525static const char *card_status[] = {
2526 "Card inserted - uninitialized",
2527 "Card not downloaded",
2528 "Waiting for download parameters",
2529 "Card doing acquisition",
2530 "Acquisition complete",
2531 "Authentication complete",
2532 "Association complete",
2533 "???", "???", "???", "???",
2534 "Card init error",
2535 "Download parameters error",
2536 "???",
2537 "Acquisition failed",
2538 "Authentication refused",
2539 "Association failed"
2540};
2541
2542static const char *nettype[] = { "Adhoc", "Infra " };
2543static const char *framing[] = { "Encapsulation", "Translation" }
2544
2545;
2546
2547static int ray_cs_proc_show(struct seq_file *m, void *v)
2548{
2549
2550
2551
2552 int i;
2553 struct pcmcia_device *link;
2554 struct net_device *dev;
2555 ray_dev_t *local;
2556 UCHAR *p;
2557 struct freq_hop_element *pfh;
2558 UCHAR c[33];
2559
2560 link = this_device;
2561 if (!link)
2562 return 0;
2563 dev = (struct net_device *)link->priv;
2564 if (!dev)
2565 return 0;
2566 local = netdev_priv(dev);
2567 if (!local)
2568 return 0;
2569
2570 seq_puts(m, "Raylink Wireless LAN driver status\n");
2571 seq_printf(m, "%s\n", rcsid);
2572
2573 seq_puts(m, "Firmware version = ");
2574 if (local->fw_ver == 0x55)
2575 seq_puts(m, "4 - Use dump_cis for more details\n");
2576 else
2577 seq_printf(m, "%2d.%02d.%02d\n",
2578 local->fw_ver, local->fw_bld, local->fw_var);
2579
2580 for (i = 0; i < 32; i++)
2581 c[i] = local->sparm.b5.a_current_ess_id[i];
2582 c[32] = 0;
2583 seq_printf(m, "%s network ESSID = \"%s\"\n",
2584 nettype[local->sparm.b5.a_network_type], c);
2585
2586 p = local->bss_id;
2587 seq_printf(m, "BSSID = %pM\n", p);
2588
2589 seq_printf(m, "Country code = %d\n",
2590 local->sparm.b5.a_curr_country_code);
2591
2592 i = local->card_status;
2593 if (i < 0)
2594 i = 10;
2595 if (i > 16)
2596 i = 10;
2597 seq_printf(m, "Card status = %s\n", card_status[i]);
2598
2599 seq_printf(m, "Framing mode = %s\n", framing[translate]);
2600
2601 seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
2602
2603 if (local->beacon_rxed) {
2604
2605 seq_printf(m, "Beacon Interval = %d Kus\n",
2606 local->last_bcn.beacon_intvl[0]
2607 + 256 * local->last_bcn.beacon_intvl[1]);
2608
2609 p = local->last_bcn.elements;
2610 if (p[0] == C_ESSID_ELEMENT_ID)
2611 p += p[1] + 2;
2612 else {
2613 seq_printf(m,
2614 "Parse beacon failed at essid element id = %d\n",
2615 p[0]);
2616 return 0;
2617 }
2618
2619 if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
2620 seq_puts(m, "Supported rate codes = ");
2621 for (i = 2; i < p[1] + 2; i++)
2622 seq_printf(m, "0x%02x ", p[i]);
2623 seq_putc(m, '\n');
2624 p += p[1] + 2;
2625 } else {
2626 seq_puts(m, "Parse beacon failed at rates element\n");
2627 return 0;
2628 }
2629
2630 if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
2631 pfh = (struct freq_hop_element *)p;
2632 seq_printf(m, "Hop dwell = %d Kus\n",
2633 pfh->dwell_time[0] +
2634 256 * pfh->dwell_time[1]);
2635 seq_printf(m, "Hop set = %d\n",
2636 pfh->hop_set);
2637 seq_printf(m, "Hop pattern = %d\n",
2638 pfh->hop_pattern);
2639 seq_printf(m, "Hop index = %d\n",
2640 pfh->hop_index);
2641 p += p[1] + 2;
2642 } else {
2643 seq_puts(m,
2644 "Parse beacon failed at FH param element\n");
2645 return 0;
2646 }
2647 } else {
2648 seq_puts(m, "No beacons received\n");
2649 }
2650 return 0;
2651}
2652#endif
2653
2654static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
2655{
2656 int addr;
2657 struct ccs __iomem *pccs;
2658 struct tx_msg __iomem *ptx;
2659 int ccsindex;
2660
2661
2662 if ((ccsindex = get_free_tx_ccs(local)) < 0) {
2663 pr_debug("ray_cs send authenticate - No free tx ccs\n");
2664 return -1;
2665 }
2666
2667 pccs = ccs_base(local) + ccsindex;
2668
2669
2670 addr = TX_BUF_BASE + (ccsindex << 11);
2671
2672 writeb(CCS_TX_REQUEST, &pccs->cmd);
2673 writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
2674 writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
2675 writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
2676 writeb(TX_AUTHENTICATE_LENGTH_LSB,
2677 pccs->var.tx_request.tx_data_length + 1);
2678 writeb(0, &pccs->var.tx_request.pow_sav_mode);
2679
2680 ptx = local->sram + addr;
2681
2682 writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
2683 writeb(0, &ptx->mac.frame_ctl_2);
2684
2685 memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
2686 memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
2687 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
2688
2689
2690 memset_io(ptx->var, 0, 6);
2691 writeb(auth_type & 0xff, ptx->var + 2);
2692
2693
2694 if (interrupt_ecf(local, ccsindex)) {
2695 pr_debug(
2696 "ray_cs send authentication request failed - ECF not ready for intr\n");
2697 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2698 return -1;
2699 }
2700 return 0;
2701}
2702
2703
2704#ifdef CONFIG_PROC_FS
2705static ssize_t ray_cs_essid_proc_write(struct file *file,
2706 const char __user *buffer, size_t count, loff_t *pos)
2707{
2708 static char proc_essid[33];
2709 unsigned int len = count;
2710
2711 if (len > 32)
2712 len = 32;
2713 memset(proc_essid, 0, 33);
2714 if (copy_from_user(proc_essid, buffer, len))
2715 return -EFAULT;
2716 essid = proc_essid;
2717 return count;
2718}
2719
2720static const struct proc_ops ray_cs_essid_proc_ops = {
2721 .proc_write = ray_cs_essid_proc_write,
2722 .proc_lseek = noop_llseek,
2723};
2724
2725static ssize_t int_proc_write(struct file *file, const char __user *buffer,
2726 size_t count, loff_t *pos)
2727{
2728 static char proc_number[10];
2729 char *p;
2730 int nr, len;
2731
2732 if (!count)
2733 return 0;
2734
2735 if (count > 9)
2736 return -EINVAL;
2737 if (copy_from_user(proc_number, buffer, count))
2738 return -EFAULT;
2739 p = proc_number;
2740 nr = 0;
2741 len = count;
2742 do {
2743 unsigned int c = *p - '0';
2744 if (c > 9)
2745 return -EINVAL;
2746 nr = nr * 10 + c;
2747 p++;
2748 } while (--len);
2749 *(int *)PDE_DATA(file_inode(file)) = nr;
2750 return count;
2751}
2752
2753static const struct proc_ops int_proc_ops = {
2754 .proc_write = int_proc_write,
2755 .proc_lseek = noop_llseek,
2756};
2757#endif
2758
2759static const struct pcmcia_device_id ray_ids[] = {
2760 PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
2761 PCMCIA_DEVICE_NULL,
2762};
2763
2764MODULE_DEVICE_TABLE(pcmcia, ray_ids);
2765
2766static struct pcmcia_driver ray_driver = {
2767 .owner = THIS_MODULE,
2768 .name = "ray_cs",
2769 .probe = ray_probe,
2770 .remove = ray_detach,
2771 .id_table = ray_ids,
2772 .suspend = ray_suspend,
2773 .resume = ray_resume,
2774};
2775
2776static int __init init_ray_cs(void)
2777{
2778 int rc;
2779
2780 pr_debug("%s\n", rcsid);
2781 rc = pcmcia_register_driver(&ray_driver);
2782 pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
2783 rc);
2784 if (rc)
2785 return rc;
2786
2787#ifdef CONFIG_PROC_FS
2788 proc_mkdir("driver/ray_cs", NULL);
2789
2790 proc_create_single("driver/ray_cs/ray_cs", 0, NULL, ray_cs_proc_show);
2791 proc_create("driver/ray_cs/essid", 0200, NULL, &ray_cs_essid_proc_ops);
2792 proc_create_data("driver/ray_cs/net_type", 0200, NULL, &int_proc_ops,
2793 &net_type);
2794 proc_create_data("driver/ray_cs/translate", 0200, NULL, &int_proc_ops,
2795 &translate);
2796#endif
2797 translate = !!translate;
2798 return 0;
2799}
2800
2801
2802
2803static void __exit exit_ray_cs(void)
2804{
2805 pr_debug("ray_cs: cleanup_module\n");
2806
2807#ifdef CONFIG_PROC_FS
2808 remove_proc_subtree("driver/ray_cs", NULL);
2809#endif
2810
2811 pcmcia_unregister_driver(&ray_driver);
2812}
2813
2814module_init(init_ray_cs);
2815module_exit(exit_ray_cs);
2816
2817
2818