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
881 case ECCSFULL:
882 pr_debug("ray_hw_xmit No free tx ccs\n");
883
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 2 * ADDRLEN);
986 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
987 } else {
988
989 if (local->sparm.b4.a_acting_as_ap_status) {
990 writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
991 memcpy_toio(ptx->mac.addr_1,
992 ((struct ethhdr *)data)->h_dest, ADDRLEN);
993 memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
994 memcpy_toio(ptx->mac.addr_3,
995 ((struct ethhdr *)data)->h_source, ADDRLEN);
996 } else {
997
998 writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
999 memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
1000 memcpy_toio(ptx->mac.addr_2,
1001 ((struct ethhdr *)data)->h_source, ADDRLEN);
1002 memcpy_toio(ptx->mac.addr_3,
1003 ((struct ethhdr *)data)->h_dest, ADDRLEN);
1004 }
1005 }
1006}
1007
1008
1009
1010
1011
1012
1013
1014static int ray_get_name(struct net_device *dev, struct iw_request_info *info,
1015 union iwreq_data *wrqu, char *extra)
1016{
1017 strcpy(wrqu->name, "IEEE 802.11-FH");
1018 return 0;
1019}
1020
1021
1022
1023
1024
1025static int ray_set_freq(struct net_device *dev, struct iw_request_info *info,
1026 union iwreq_data *wrqu, char *extra)
1027{
1028 ray_dev_t *local = netdev_priv(dev);
1029 int err = -EINPROGRESS;
1030
1031
1032 if (local->card_status != CARD_AWAITING_PARAM)
1033 return -EBUSY;
1034
1035
1036 if ((wrqu->freq.m > USA_HOP_MOD) || (wrqu->freq.e > 0))
1037 err = -EOPNOTSUPP;
1038 else
1039 local->sparm.b5.a_hop_pattern = wrqu->freq.m;
1040
1041 return err;
1042}
1043
1044
1045
1046
1047
1048static int ray_get_freq(struct net_device *dev, struct iw_request_info *info,
1049 union iwreq_data *wrqu, char *extra)
1050{
1051 ray_dev_t *local = netdev_priv(dev);
1052
1053 wrqu->freq.m = local->sparm.b5.a_hop_pattern;
1054 wrqu->freq.e = 0;
1055 return 0;
1056}
1057
1058
1059
1060
1061
1062static int ray_set_essid(struct net_device *dev, struct iw_request_info *info,
1063 union iwreq_data *wrqu, char *extra)
1064{
1065 ray_dev_t *local = netdev_priv(dev);
1066
1067
1068 if (local->card_status != CARD_AWAITING_PARAM)
1069 return -EBUSY;
1070
1071
1072 if (wrqu->essid.flags == 0)
1073
1074 return -EOPNOTSUPP;
1075
1076
1077 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1078 return -E2BIG;
1079
1080
1081 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1082 memcpy(local->sparm.b5.a_current_ess_id, extra, wrqu->essid.length);
1083
1084 return -EINPROGRESS;
1085}
1086
1087
1088
1089
1090
1091static int ray_get_essid(struct net_device *dev, struct iw_request_info *info,
1092 union iwreq_data *wrqu, char *extra)
1093{
1094 ray_dev_t *local = netdev_priv(dev);
1095 UCHAR tmp[IW_ESSID_MAX_SIZE + 1];
1096
1097
1098 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1099 memcpy(tmp, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1100 tmp[IW_ESSID_MAX_SIZE] = '\0';
1101
1102
1103 wrqu->essid.length = strlen(tmp);
1104 wrqu->essid.flags = 1;
1105
1106 return 0;
1107}
1108
1109
1110
1111
1112
1113static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1114 union iwreq_data *wrqu, char *extra)
1115{
1116 ray_dev_t *local = netdev_priv(dev);
1117
1118 memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1119 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1120
1121 return 0;
1122}
1123
1124
1125
1126
1127
1128static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1129 union iwreq_data *wrqu, char *extra)
1130{
1131 ray_dev_t *local = netdev_priv(dev);
1132
1133
1134 if (local->card_status != CARD_AWAITING_PARAM)
1135 return -EBUSY;
1136
1137
1138 if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1139 return -EINVAL;
1140
1141
1142 if ((local->fw_ver == 0x55) &&
1143 (wrqu->bitrate.value == 2000000))
1144 local->net_default_tx_rate = 3;
1145 else
1146 local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1147
1148 return 0;
1149}
1150
1151
1152
1153
1154
1155static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1156 union iwreq_data *wrqu, char *extra)
1157{
1158 ray_dev_t *local = netdev_priv(dev);
1159
1160 if (local->net_default_tx_rate == 3)
1161 wrqu->bitrate.value = 2000000;
1162 else
1163 wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1164 wrqu->bitrate.fixed = 0;
1165
1166 return 0;
1167}
1168
1169
1170
1171
1172
1173static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1174 union iwreq_data *wrqu, char *extra)
1175{
1176 ray_dev_t *local = netdev_priv(dev);
1177 int rthr = wrqu->rts.value;
1178
1179
1180 if (local->card_status != CARD_AWAITING_PARAM)
1181 return -EBUSY;
1182
1183
1184 if (wrqu->rts.disabled)
1185 rthr = 32767;
1186 else {
1187 if ((rthr < 0) || (rthr > 2347))
1188 return -EINVAL;
1189 }
1190 local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1191 local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1192
1193 return -EINPROGRESS;
1194}
1195
1196
1197
1198
1199
1200static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1201 union iwreq_data *wrqu, char *extra)
1202{
1203 ray_dev_t *local = netdev_priv(dev);
1204
1205 wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1206 + local->sparm.b5.a_rts_threshold[1];
1207 wrqu->rts.disabled = (wrqu->rts.value == 32767);
1208 wrqu->rts.fixed = 1;
1209
1210 return 0;
1211}
1212
1213
1214
1215
1216
1217static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1218 union iwreq_data *wrqu, char *extra)
1219{
1220 ray_dev_t *local = netdev_priv(dev);
1221 int fthr = wrqu->frag.value;
1222
1223
1224 if (local->card_status != CARD_AWAITING_PARAM)
1225 return -EBUSY;
1226
1227
1228 if (wrqu->frag.disabled)
1229 fthr = 32767;
1230 else {
1231 if ((fthr < 256) || (fthr > 2347))
1232 return -EINVAL;
1233 }
1234 local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1235 local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1236
1237 return -EINPROGRESS;
1238}
1239
1240
1241
1242
1243
1244static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1245 union iwreq_data *wrqu, char *extra)
1246{
1247 ray_dev_t *local = netdev_priv(dev);
1248
1249 wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1250 + local->sparm.b5.a_frag_threshold[1];
1251 wrqu->frag.disabled = (wrqu->frag.value == 32767);
1252 wrqu->frag.fixed = 1;
1253
1254 return 0;
1255}
1256
1257
1258
1259
1260
1261static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1262 union iwreq_data *wrqu, char *extra)
1263{
1264 ray_dev_t *local = netdev_priv(dev);
1265 int err = -EINPROGRESS;
1266 char card_mode = 1;
1267
1268
1269 if (local->card_status != CARD_AWAITING_PARAM)
1270 return -EBUSY;
1271
1272 switch (wrqu->mode) {
1273 case IW_MODE_ADHOC:
1274 card_mode = 0;
1275
1276 case IW_MODE_INFRA:
1277 local->sparm.b5.a_network_type = card_mode;
1278 break;
1279 default:
1280 err = -EINVAL;
1281 }
1282
1283 return err;
1284}
1285
1286
1287
1288
1289
1290static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1291 union iwreq_data *wrqu, char *extra)
1292{
1293 ray_dev_t *local = netdev_priv(dev);
1294
1295 if (local->sparm.b5.a_network_type)
1296 wrqu->mode = IW_MODE_INFRA;
1297 else
1298 wrqu->mode = IW_MODE_ADHOC;
1299
1300 return 0;
1301}
1302
1303
1304
1305
1306
1307static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1308 union iwreq_data *wrqu, char *extra)
1309{
1310 struct iw_range *range = (struct iw_range *)extra;
1311
1312 memset(range, 0, sizeof(struct iw_range));
1313
1314
1315 wrqu->data.length = sizeof(struct iw_range);
1316
1317
1318 range->we_version_compiled = WIRELESS_EXT;
1319 range->we_version_source = 9;
1320
1321
1322 range->throughput = 1.1 * 1000 * 1000;
1323 range->num_channels = hop_pattern_length[(int)country];
1324 range->num_frequency = 0;
1325 range->max_qual.qual = 0;
1326 range->max_qual.level = 255;
1327 range->max_qual.noise = 255;
1328 range->num_bitrates = 2;
1329 range->bitrate[0] = 1000000;
1330 range->bitrate[1] = 2000000;
1331 return 0;
1332}
1333
1334
1335
1336
1337
1338static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1339 union iwreq_data *wrqu, char *extra)
1340{
1341 translate = !!*(extra);
1342
1343 return 0;
1344}
1345
1346
1347
1348
1349
1350static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1351 union iwreq_data *wrqu, char *extra)
1352{
1353 *(extra) = translate;
1354
1355 return 0;
1356}
1357
1358
1359
1360
1361
1362static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1363 union iwreq_data *wrqu, char *extra)
1364{
1365 *(extra) = country;
1366
1367 return 0;
1368}
1369
1370
1371
1372
1373
1374static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1375 union iwreq_data *wrqu, char *extra)
1376{
1377 return 0;
1378}
1379
1380
1381
1382
1383
1384static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1385{
1386 ray_dev_t *local = netdev_priv(dev);
1387 struct pcmcia_device *link = local->finder;
1388 struct status __iomem *p = local->sram + STATUS_BASE;
1389
1390 local->wstats.status = local->card_status;
1391#ifdef WIRELESS_SPY
1392 if ((local->spy_data.spy_number > 0)
1393 && (local->sparm.b5.a_network_type == 0)) {
1394
1395 local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
1396 local->wstats.qual.level = local->spy_data.spy_stat[0].level;
1397 local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
1398 local->wstats.qual.updated =
1399 local->spy_data.spy_stat[0].updated;
1400 }
1401#endif
1402
1403 if (pcmcia_dev_present(link)) {
1404 local->wstats.qual.noise = readb(&p->rxnoise);
1405 local->wstats.qual.updated |= 4;
1406 }
1407
1408 return &local->wstats;
1409}
1410
1411
1412
1413
1414
1415
1416static const iw_handler ray_handler[] = {
1417 IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1418 IW_HANDLER(SIOCGIWNAME, ray_get_name),
1419 IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1420 IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1421 IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1422 IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1423 IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1424#ifdef WIRELESS_SPY
1425 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1426 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1427 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1428 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1429#endif
1430 IW_HANDLER(SIOCGIWAP, ray_get_wap),
1431 IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1432 IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1433 IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1434 IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1435 IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1436 IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1437 IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1438 IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1439};
1440
1441#define SIOCSIPFRAMING SIOCIWFIRSTPRIV
1442#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1
1443#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3
1444
1445static const iw_handler ray_private_handler[] = {
1446 [0] = ray_set_framing,
1447 [1] = ray_get_framing,
1448 [3] = ray_get_country,
1449};
1450
1451static const struct iw_priv_args ray_private_args[] = {
1452
1453 {SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
1454 "set_framing"},
1455 {SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1456 "get_framing"},
1457 {SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1458 "get_country"},
1459};
1460
1461static const struct iw_handler_def ray_handler_def = {
1462 .num_standard = ARRAY_SIZE(ray_handler),
1463 .num_private = ARRAY_SIZE(ray_private_handler),
1464 .num_private_args = ARRAY_SIZE(ray_private_args),
1465 .standard = ray_handler,
1466 .private = ray_private_handler,
1467 .private_args = ray_private_args,
1468 .get_wireless_stats = ray_get_wireless_stats,
1469};
1470
1471
1472static int ray_open(struct net_device *dev)
1473{
1474 ray_dev_t *local = netdev_priv(dev);
1475 struct pcmcia_device *link;
1476 link = local->finder;
1477
1478 dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
1479
1480 if (link->open == 0)
1481 local->num_multi = 0;
1482 link->open++;
1483
1484
1485 if (local->card_status == CARD_AWAITING_PARAM) {
1486 int i;
1487
1488 dev_dbg(&link->dev, "ray_open: doing init now !\n");
1489
1490
1491 if ((i = dl_startup_params(dev)) < 0) {
1492 printk(KERN_INFO
1493 "ray_dev_init dl_startup_params failed - "
1494 "returns 0x%x\n", i);
1495 return -1;
1496 }
1497 }
1498
1499 if (sniffer)
1500 netif_stop_queue(dev);
1501 else
1502 netif_start_queue(dev);
1503
1504 dev_dbg(&link->dev, "ray_open ending\n");
1505 return 0;
1506}
1507
1508
1509static int ray_dev_close(struct net_device *dev)
1510{
1511 ray_dev_t *local = netdev_priv(dev);
1512 struct pcmcia_device *link;
1513 link = local->finder;
1514
1515 dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
1516
1517 link->open--;
1518 netif_stop_queue(dev);
1519
1520
1521
1522
1523
1524
1525 return 0;
1526}
1527
1528
1529static void ray_reset(struct net_device *dev)
1530{
1531 pr_debug("ray_reset entered\n");
1532}
1533
1534
1535
1536
1537static int interrupt_ecf(ray_dev_t *local, int ccs)
1538{
1539 int i = 50;
1540 struct pcmcia_device *link = local->finder;
1541
1542 if (!(pcmcia_dev_present(link))) {
1543 dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
1544 return -1;
1545 }
1546 dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
1547
1548 while (i &&
1549 (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
1550 ECF_INTR_SET))
1551 i--;
1552 if (i == 0) {
1553 dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
1554 return -1;
1555 }
1556
1557 writeb(ccs, local->sram + SCB_BASE);
1558 writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1559 return 0;
1560}
1561
1562
1563
1564
1565static int get_free_tx_ccs(ray_dev_t *local)
1566{
1567 int i;
1568 struct ccs __iomem *pccs = ccs_base(local);
1569 struct pcmcia_device *link = local->finder;
1570
1571 if (!(pcmcia_dev_present(link))) {
1572 dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
1573 return ECARDGONE;
1574 }
1575
1576 if (test_and_set_bit(0, &local->tx_ccs_lock)) {
1577 dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
1578 return ECCSBUSY;
1579 }
1580
1581 for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
1582 if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1583 writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1584 writeb(CCS_END_LIST, &(pccs + i)->link);
1585 local->tx_ccs_lock = 0;
1586 return i;
1587 }
1588 }
1589 local->tx_ccs_lock = 0;
1590 dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
1591 return ECCSFULL;
1592}
1593
1594
1595
1596
1597static int get_free_ccs(ray_dev_t *local)
1598{
1599 int i;
1600 struct ccs __iomem *pccs = ccs_base(local);
1601 struct pcmcia_device *link = local->finder;
1602
1603 if (!(pcmcia_dev_present(link))) {
1604 dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
1605 return ECARDGONE;
1606 }
1607 if (test_and_set_bit(0, &local->ccs_lock)) {
1608 dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
1609 return ECCSBUSY;
1610 }
1611
1612 for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1613 if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1614 writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1615 writeb(CCS_END_LIST, &(pccs + i)->link);
1616 local->ccs_lock = 0;
1617 return i;
1618 }
1619 }
1620 local->ccs_lock = 0;
1621 dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
1622 return ECCSFULL;
1623}
1624
1625
1626static void authenticate_timeout(struct timer_list *t)
1627{
1628 ray_dev_t *local = from_timer(local, t, timer);
1629 del_timer(&local->timer);
1630 printk(KERN_INFO "ray_cs Authentication with access point failed"
1631 " - timeout\n");
1632 join_net(&local->timer);
1633}
1634
1635
1636static int parse_addr(char *in_str, UCHAR *out)
1637{
1638 int len;
1639 int i, j, k;
1640 int status;
1641
1642 if (in_str == NULL)
1643 return 0;
1644 if ((len = strlen(in_str)) < 2)
1645 return 0;
1646 memset(out, 0, ADDRLEN);
1647
1648 status = 1;
1649 j = len - 1;
1650 if (j > 12)
1651 j = 12;
1652 i = 5;
1653
1654 while (j > 0) {
1655 if ((k = hex_to_bin(in_str[j--])) != -1)
1656 out[i] = k;
1657 else
1658 return 0;
1659
1660 if (j == 0)
1661 break;
1662 if ((k = hex_to_bin(in_str[j--])) != -1)
1663 out[i] += k << 4;
1664 else
1665 return 0;
1666 if (!i--)
1667 break;
1668 }
1669 return status;
1670}
1671
1672
1673static struct net_device_stats *ray_get_stats(struct net_device *dev)
1674{
1675 ray_dev_t *local = netdev_priv(dev);
1676 struct pcmcia_device *link = local->finder;
1677 struct status __iomem *p = local->sram + STATUS_BASE;
1678 if (!(pcmcia_dev_present(link))) {
1679 dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
1680 return &local->stats;
1681 }
1682 if (readb(&p->mrx_overflow_for_host)) {
1683 local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
1684 writeb(0, &p->mrx_overflow);
1685 writeb(0, &p->mrx_overflow_for_host);
1686 }
1687 if (readb(&p->mrx_checksum_error_for_host)) {
1688 local->stats.rx_crc_errors +=
1689 swab16(readw(&p->mrx_checksum_error));
1690 writeb(0, &p->mrx_checksum_error);
1691 writeb(0, &p->mrx_checksum_error_for_host);
1692 }
1693 if (readb(&p->rx_hec_error_for_host)) {
1694 local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
1695 writeb(0, &p->rx_hec_error);
1696 writeb(0, &p->rx_hec_error_for_host);
1697 }
1698 return &local->stats;
1699}
1700
1701
1702static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
1703 int len)
1704{
1705 ray_dev_t *local = netdev_priv(dev);
1706 struct pcmcia_device *link = local->finder;
1707 int ccsindex;
1708 int i;
1709 struct ccs __iomem *pccs;
1710
1711 if (!(pcmcia_dev_present(link))) {
1712 dev_dbg(&link->dev, "ray_update_parm - device not present\n");
1713 return;
1714 }
1715
1716 if ((ccsindex = get_free_ccs(local)) < 0) {
1717 dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
1718 return;
1719 }
1720 pccs = ccs_base(local) + ccsindex;
1721 writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1722 writeb(objid, &pccs->var.update_param.object_id);
1723 writeb(1, &pccs->var.update_param.number_objects);
1724 writeb(0, &pccs->var.update_param.failure_cause);
1725 for (i = 0; i < len; i++) {
1726 writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1727 }
1728
1729 if (interrupt_ecf(local, ccsindex)) {
1730 dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
1731 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1732 }
1733}
1734
1735
1736static void ray_update_multi_list(struct net_device *dev, int all)
1737{
1738 int ccsindex;
1739 struct ccs __iomem *pccs;
1740 ray_dev_t *local = netdev_priv(dev);
1741 struct pcmcia_device *link = local->finder;
1742 void __iomem *p = local->sram + HOST_TO_ECF_BASE;
1743
1744 if (!(pcmcia_dev_present(link))) {
1745 dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
1746 return;
1747 } else
1748 dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
1749 if ((ccsindex = get_free_ccs(local)) < 0) {
1750 dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
1751 return;
1752 }
1753 pccs = ccs_base(local) + ccsindex;
1754 writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
1755
1756 if (all) {
1757 writeb(0xff, &pccs->var);
1758 local->num_multi = 0xff;
1759 } else {
1760 struct netdev_hw_addr *ha;
1761 int i = 0;
1762
1763
1764 netdev_for_each_mc_addr(ha, dev) {
1765 memcpy_toio(p, ha->addr, ETH_ALEN);
1766 dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
1767 ha->addr);
1768 p += ETH_ALEN;
1769 i++;
1770 }
1771 if (i > 256 / ADDRLEN)
1772 i = 256 / ADDRLEN;
1773 writeb((UCHAR) i, &pccs->var);
1774 dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
1775
1776 local->num_multi = i;
1777 }
1778 if (interrupt_ecf(local, ccsindex)) {
1779 dev_dbg(&link->dev,
1780 "ray_cs update_multi failed - ECF not ready for intr\n");
1781 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1782 }
1783}
1784
1785
1786static void set_multicast_list(struct net_device *dev)
1787{
1788 ray_dev_t *local = netdev_priv(dev);
1789 UCHAR promisc;
1790
1791 pr_debug("ray_cs set_multicast_list(%p)\n", dev);
1792
1793 if (dev->flags & IFF_PROMISC) {
1794 if (local->sparm.b5.a_promiscuous_mode == 0) {
1795 pr_debug("ray_cs set_multicast_list promisc on\n");
1796 local->sparm.b5.a_promiscuous_mode = 1;
1797 promisc = 1;
1798 ray_update_parm(dev, OBJID_promiscuous_mode,
1799 &promisc, sizeof(promisc));
1800 }
1801 } else {
1802 if (local->sparm.b5.a_promiscuous_mode == 1) {
1803 pr_debug("ray_cs set_multicast_list promisc off\n");
1804 local->sparm.b5.a_promiscuous_mode = 0;
1805 promisc = 0;
1806 ray_update_parm(dev, OBJID_promiscuous_mode,
1807 &promisc, sizeof(promisc));
1808 }
1809 }
1810
1811 if (dev->flags & IFF_ALLMULTI)
1812 ray_update_multi_list(dev, 1);
1813 else {
1814 if (local->num_multi != netdev_mc_count(dev))
1815 ray_update_multi_list(dev, 0);
1816 }
1817}
1818
1819
1820
1821
1822static irqreturn_t ray_interrupt(int irq, void *dev_id)
1823{
1824 struct net_device *dev = (struct net_device *)dev_id;
1825 struct pcmcia_device *link;
1826 ray_dev_t *local;
1827 struct ccs __iomem *pccs;
1828 struct rcs __iomem *prcs;
1829 UCHAR rcsindex;
1830 UCHAR tmp;
1831 UCHAR cmd;
1832 UCHAR status;
1833 UCHAR memtmp[ESSID_SIZE + 1];
1834
1835
1836 if (dev == NULL)
1837 return IRQ_NONE;
1838
1839 pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
1840
1841 local = netdev_priv(dev);
1842 link = local->finder;
1843 if (!pcmcia_dev_present(link)) {
1844 pr_debug(
1845 "ray_cs interrupt from device not present or suspended.\n");
1846 return IRQ_NONE;
1847 }
1848 rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
1849
1850 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
1851 dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
1852 clear_interrupt(local);
1853 return IRQ_HANDLED;
1854 }
1855 if (rcsindex < NUMBER_OF_CCS) {
1856 pccs = ccs_base(local) + rcsindex;
1857 cmd = readb(&pccs->cmd);
1858 status = readb(&pccs->buffer_status);
1859 switch (cmd) {
1860 case CCS_DOWNLOAD_STARTUP_PARAMS:
1861 del_timer(&local->timer);
1862 if (status == CCS_COMMAND_COMPLETE) {
1863 dev_dbg(&link->dev,
1864 "ray_cs interrupt download_startup_parameters OK\n");
1865 } else {
1866 dev_dbg(&link->dev,
1867 "ray_cs interrupt download_startup_parameters fail\n");
1868 }
1869 break;
1870 case CCS_UPDATE_PARAMS:
1871 dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
1872 if (status != CCS_COMMAND_COMPLETE) {
1873 tmp =
1874 readb(&pccs->var.update_param.
1875 failure_cause);
1876 dev_dbg(&link->dev,
1877 "ray_cs interrupt update params failed - reason %d\n",
1878 tmp);
1879 }
1880 break;
1881 case CCS_REPORT_PARAMS:
1882 dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
1883 break;
1884 case CCS_UPDATE_MULTICAST_LIST:
1885 dev_dbg(&link->dev,
1886 "ray_cs interrupt CCS Update Multicast List done\n");
1887 break;
1888 case CCS_UPDATE_POWER_SAVINGS_MODE:
1889 dev_dbg(&link->dev,
1890 "ray_cs interrupt update power save mode done\n");
1891 break;
1892 case CCS_START_NETWORK:
1893 case CCS_JOIN_NETWORK:
1894 memcpy(memtmp, local->sparm.b4.a_current_ess_id,
1895 ESSID_SIZE);
1896 memtmp[ESSID_SIZE] = '\0';
1897
1898 if (status == CCS_COMMAND_COMPLETE) {
1899 if (readb
1900 (&pccs->var.start_network.net_initiated) ==
1901 1) {
1902 dev_dbg(&link->dev,
1903 "ray_cs interrupt network \"%s\" started\n",
1904 memtmp);
1905 } else {
1906 dev_dbg(&link->dev,
1907 "ray_cs interrupt network \"%s\" joined\n",
1908 memtmp);
1909 }
1910 memcpy_fromio(&local->bss_id,
1911 pccs->var.start_network.bssid,
1912 ADDRLEN);
1913
1914 if (local->fw_ver == 0x55)
1915 local->net_default_tx_rate = 3;
1916 else
1917 local->net_default_tx_rate =
1918 readb(&pccs->var.start_network.
1919 net_default_tx_rate);
1920 local->encryption =
1921 readb(&pccs->var.start_network.encryption);
1922 if (!sniffer && (local->net_type == INFRA)
1923 && !(local->sparm.b4.a_acting_as_ap_status)) {
1924 authenticate(local);
1925 }
1926 local->card_status = CARD_ACQ_COMPLETE;
1927 } else {
1928 local->card_status = CARD_ACQ_FAILED;
1929
1930 del_timer(&local->timer);
1931 local->timer.expires = jiffies + HZ * 5;
1932 if (status == CCS_START_NETWORK) {
1933 dev_dbg(&link->dev,
1934 "ray_cs interrupt network \"%s\" start failed\n",
1935 memtmp);
1936 local->timer.function = start_net;
1937 } else {
1938 dev_dbg(&link->dev,
1939 "ray_cs interrupt network \"%s\" join failed\n",
1940 memtmp);
1941 local->timer.function = join_net;
1942 }
1943 add_timer(&local->timer);
1944 }
1945 break;
1946 case CCS_START_ASSOCIATION:
1947 if (status == CCS_COMMAND_COMPLETE) {
1948 local->card_status = CARD_ASSOC_COMPLETE;
1949 dev_dbg(&link->dev, "ray_cs association successful\n");
1950 } else {
1951 dev_dbg(&link->dev, "ray_cs association failed,\n");
1952 local->card_status = CARD_ASSOC_FAILED;
1953 join_net(&local->timer);
1954 }
1955 break;
1956 case CCS_TX_REQUEST:
1957 if (status == CCS_COMMAND_COMPLETE) {
1958 dev_dbg(&link->dev,
1959 "ray_cs interrupt tx request complete\n");
1960 } else {
1961 dev_dbg(&link->dev,
1962 "ray_cs interrupt tx request failed\n");
1963 }
1964 if (!sniffer)
1965 netif_start_queue(dev);
1966 netif_wake_queue(dev);
1967 break;
1968 case CCS_TEST_MEMORY:
1969 dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
1970 break;
1971 case CCS_SHUTDOWN:
1972 dev_dbg(&link->dev,
1973 "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
1974 break;
1975 case CCS_DUMP_MEMORY:
1976 dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
1977 break;
1978 case CCS_START_TIMER:
1979 dev_dbg(&link->dev,
1980 "ray_cs interrupt DING - raylink timer expired\n");
1981 break;
1982 default:
1983 dev_dbg(&link->dev,
1984 "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
1985 rcsindex, cmd);
1986 }
1987 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1988 } else {
1989
1990 prcs = rcs_base(local) + rcsindex;
1991
1992 switch (readb(&prcs->interrupt_id)) {
1993 case PROCESS_RX_PACKET:
1994 ray_rx(dev, local, prcs);
1995 break;
1996 case REJOIN_NET_COMPLETE:
1997 dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
1998 local->card_status = CARD_ACQ_COMPLETE;
1999
2000 if (local->sparm.b4.a_network_type == ADHOC) {
2001 if (!sniffer)
2002 netif_start_queue(dev);
2003 } else {
2004 memcpy_fromio(&local->bss_id,
2005 prcs->var.rejoin_net_complete.
2006 bssid, ADDRLEN);
2007 dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
2008 local->bss_id);
2009 if (!sniffer)
2010 authenticate(local);
2011 }
2012 break;
2013 case ROAMING_INITIATED:
2014 dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
2015 netif_stop_queue(dev);
2016 local->card_status = CARD_DOING_ACQ;
2017 break;
2018 case JAPAN_CALL_SIGN_RXD:
2019 dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
2020 break;
2021 default:
2022 dev_dbg(&link->dev,
2023 "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
2024 rcsindex,
2025 (unsigned int)readb(&prcs->interrupt_id));
2026 break;
2027 }
2028 writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
2029 }
2030 clear_interrupt(local);
2031 return IRQ_HANDLED;
2032}
2033
2034
2035static void ray_rx(struct net_device *dev, ray_dev_t *local,
2036 struct rcs __iomem *prcs)
2037{
2038 int rx_len;
2039 unsigned int pkt_addr;
2040 void __iomem *pmsg;
2041 pr_debug("ray_rx process rx packet\n");
2042
2043
2044 pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
2045 + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
2046
2047 rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
2048 + readb(&prcs->var.rx_packet.rx_data_length[1]);
2049
2050 local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
2051 pmsg = local->rmem + pkt_addr;
2052 switch (readb(pmsg)) {
2053 case DATA_TYPE:
2054 pr_debug("ray_rx data type\n");
2055 rx_data(dev, prcs, pkt_addr, rx_len);
2056 break;
2057 case AUTHENTIC_TYPE:
2058 pr_debug("ray_rx authentic type\n");
2059 if (sniffer)
2060 rx_data(dev, prcs, pkt_addr, rx_len);
2061 else
2062 rx_authenticate(local, prcs, pkt_addr, rx_len);
2063 break;
2064 case DEAUTHENTIC_TYPE:
2065 pr_debug("ray_rx deauth type\n");
2066 if (sniffer)
2067 rx_data(dev, prcs, pkt_addr, rx_len);
2068 else
2069 rx_deauthenticate(local, prcs, pkt_addr, rx_len);
2070 break;
2071 case NULL_MSG_TYPE:
2072 pr_debug("ray_cs rx NULL msg\n");
2073 break;
2074 case BEACON_TYPE:
2075 pr_debug("ray_rx beacon type\n");
2076 if (sniffer)
2077 rx_data(dev, prcs, pkt_addr, rx_len);
2078
2079 copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
2080 rx_len < sizeof(struct beacon_rx) ?
2081 rx_len : sizeof(struct beacon_rx));
2082
2083 local->beacon_rxed = 1;
2084
2085 ray_get_stats(dev);
2086 break;
2087 default:
2088 pr_debug("ray_cs unknown pkt type %2x\n",
2089 (unsigned int)readb(pmsg));
2090 break;
2091 }
2092
2093}
2094
2095
2096static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2097 unsigned int pkt_addr, int rx_len)
2098{
2099 struct sk_buff *skb = NULL;
2100 struct rcs __iomem *prcslink = prcs;
2101 ray_dev_t *local = netdev_priv(dev);
2102 UCHAR *rx_ptr;
2103 int total_len;
2104 int tmp;
2105#ifdef WIRELESS_SPY
2106 int siglev = local->last_rsl;
2107 u_char linksrcaddr[ETH_ALEN];
2108#endif
2109
2110 if (!sniffer) {
2111 if (translate) {
2112
2113 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2114 rx_len >
2115 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2116 FCS_LEN)) {
2117 pr_debug(
2118 "ray_cs invalid packet length %d received\n",
2119 rx_len);
2120 return;
2121 }
2122 } else {
2123
2124 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2125 rx_len >
2126 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2127 FCS_LEN)) {
2128 pr_debug(
2129 "ray_cs invalid packet length %d received\n",
2130 rx_len);
2131 return;
2132 }
2133 }
2134 }
2135 pr_debug("ray_cs rx_data packet\n");
2136
2137 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2138 pr_debug("ray_cs rx'ed fragment\n");
2139 tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
2140 + readb(&prcs->var.rx_packet.totalpacketlength[1]);
2141 total_len = tmp;
2142 prcslink = prcs;
2143 do {
2144 tmp -=
2145 (readb(&prcslink->var.rx_packet.rx_data_length[0])
2146 << 8)
2147 + readb(&prcslink->var.rx_packet.rx_data_length[1]);
2148 if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
2149 == 0xFF || tmp < 0)
2150 break;
2151 prcslink = rcs_base(local)
2152 + readb(&prcslink->link_field);
2153 } while (1);
2154
2155 if (tmp < 0) {
2156 pr_debug(
2157 "ray_cs rx_data fragment lengths don't add up\n");
2158 local->stats.rx_dropped++;
2159 release_frag_chain(local, prcs);
2160 return;
2161 }
2162 } else {
2163 total_len = rx_len;
2164 }
2165
2166 skb = dev_alloc_skb(total_len + 5);
2167 if (skb == NULL) {
2168 pr_debug("ray_cs rx_data could not allocate skb\n");
2169 local->stats.rx_dropped++;
2170 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
2171 release_frag_chain(local, prcs);
2172 return;
2173 }
2174 skb_reserve(skb, 2);
2175
2176 pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
2177 rx_len);
2178
2179
2180
2181 rx_ptr = skb_put(skb, total_len);
2182
2183 rx_ptr +=
2184 copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
2185
2186#ifdef WIRELESS_SPY
2187 skb_copy_from_linear_data_offset(skb,
2188 offsetof(struct mac_header, addr_2),
2189 linksrcaddr, ETH_ALEN);
2190#endif
2191
2192 if (!sniffer) {
2193 if (!translate) {
2194
2195
2196 skb_pull(skb, RX_MAC_HEADER_LENGTH);
2197 } else {
2198
2199 untranslate(local, skb, total_len);
2200 }
2201 } else {
2202 }
2203
2204
2205
2206 tmp = 17;
2207 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2208 prcslink = prcs;
2209 pr_debug("ray_cs rx_data in fragment loop\n");
2210 do {
2211 prcslink = rcs_base(local)
2212 +
2213 readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2214 rx_len =
2215 ((readb(&prcslink->var.rx_packet.rx_data_length[0])
2216 << 8)
2217 +
2218 readb(&prcslink->var.rx_packet.rx_data_length[1]))
2219 & RX_BUFF_END;
2220 pkt_addr =
2221 ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
2222 8)
2223 + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
2224 & RX_BUFF_END;
2225
2226 rx_ptr +=
2227 copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
2228
2229 } while (tmp-- &&
2230 readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
2231 0xFF);
2232 release_frag_chain(local, prcs);
2233 }
2234
2235 skb->protocol = eth_type_trans(skb, dev);
2236 netif_rx(skb);
2237 local->stats.rx_packets++;
2238 local->stats.rx_bytes += total_len;
2239
2240
2241#ifdef WIRELESS_SPY
2242
2243
2244
2245 if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
2246
2247
2248 local->wstats.qual.level = siglev;
2249
2250 local->wstats.qual.updated = 0x2;
2251 }
2252
2253 {
2254 struct iw_quality wstats;
2255 wstats.level = siglev;
2256
2257
2258 wstats.updated = 0x2;
2259
2260 wireless_spy_update(dev, linksrcaddr, &wstats);
2261 }
2262#endif
2263}
2264
2265
2266static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
2267{
2268 snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
2269 struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
2270 __be16 type = *(__be16 *) psnap->ethertype;
2271 int delta;
2272 struct ethhdr *peth;
2273 UCHAR srcaddr[ADDRLEN];
2274 UCHAR destaddr[ADDRLEN];
2275 static const UCHAR org_bridge[3] = { 0, 0, 0xf8 };
2276 static const UCHAR org_1042[3] = { 0, 0, 0 };
2277
2278 memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
2279 memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
2280
2281#if 0
2282 if {
2283 print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
2284 DUMP_PREFIX_NONE, 16, 1,
2285 skb->data, 64, true);
2286 printk(KERN_DEBUG
2287 "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
2288 ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
2289 psnap->org[0], psnap->org[1], psnap->org[2]);
2290 printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
2291 }
2292#endif
2293
2294 if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
2295
2296 pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
2297 psnap->dsap, psnap->ssap, psnap->ctrl);
2298
2299 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2300 peth = (struct ethhdr *)(skb->data + delta);
2301 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2302 } else {
2303 if (memcmp(psnap->org, org_bridge, 3) == 0) {
2304
2305 pr_debug("ray_cs untranslate Bridge encap\n");
2306 delta = RX_MAC_HEADER_LENGTH
2307 + sizeof(struct snaphdr_t) - ETH_HLEN;
2308 peth = (struct ethhdr *)(skb->data + delta);
2309 peth->h_proto = type;
2310 } else if (memcmp(psnap->org, org_1042, 3) == 0) {
2311 switch (ntohs(type)) {
2312 case ETH_P_IPX:
2313 case ETH_P_AARP:
2314 pr_debug("ray_cs untranslate RFC IPX/AARP\n");
2315 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2316 peth = (struct ethhdr *)(skb->data + delta);
2317 peth->h_proto =
2318 htons(len - RX_MAC_HEADER_LENGTH);
2319 break;
2320 default:
2321 pr_debug("ray_cs untranslate RFC default\n");
2322 delta = RX_MAC_HEADER_LENGTH +
2323 sizeof(struct snaphdr_t) - ETH_HLEN;
2324 peth = (struct ethhdr *)(skb->data + delta);
2325 peth->h_proto = type;
2326 break;
2327 }
2328 } else {
2329 printk("ray_cs untranslate very confused by packet\n");
2330 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2331 peth = (struct ethhdr *)(skb->data + delta);
2332 peth->h_proto = type;
2333 }
2334 }
2335
2336 skb_pull(skb, delta);
2337 pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
2338 skb->data);
2339 memcpy(peth->h_dest, destaddr, ADDRLEN);
2340 memcpy(peth->h_source, srcaddr, ADDRLEN);
2341#if 0
2342 {
2343 int i;
2344 printk(KERN_DEBUG "skb->data after untranslate:");
2345 for (i = 0; i < 64; i++)
2346 printk("%02x ", skb->data[i]);
2347 printk("\n");
2348 }
2349#endif
2350}
2351
2352
2353
2354
2355
2356
2357
2358static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
2359 int length)
2360{
2361 int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2362 if (wrap_bytes <= 0) {
2363 memcpy_fromio(dest, local->rmem + pkt_addr, length);
2364 } else {
2365
2366 memcpy_fromio(dest, local->rmem + pkt_addr,
2367 length - wrap_bytes);
2368 memcpy_fromio(dest + length - wrap_bytes, local->rmem,
2369 wrap_bytes);
2370 }
2371 return length;
2372}
2373
2374
2375static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
2376{
2377 struct rcs __iomem *prcslink = prcs;
2378 int tmp = 17;
2379 unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2380
2381 while (tmp--) {
2382 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2383 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2384 pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
2385 rcsindex);
2386 break;
2387 }
2388 prcslink = rcs_base(local) + rcsindex;
2389 rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2390 }
2391 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2392}
2393
2394
2395static void authenticate(ray_dev_t *local)
2396{
2397 struct pcmcia_device *link = local->finder;
2398 dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
2399 if (!(pcmcia_dev_present(link))) {
2400 dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
2401 return;
2402 }
2403
2404 del_timer(&local->timer);
2405 if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2406 local->timer.function = join_net;
2407 } else {
2408 local->timer.function = authenticate_timeout;
2409 }
2410 local->timer.expires = jiffies + HZ * 2;
2411 add_timer(&local->timer);
2412 local->authentication_state = AWAITING_RESPONSE;
2413}
2414
2415
2416static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2417 unsigned int pkt_addr, int rx_len)
2418{
2419 UCHAR buff[256];
2420 struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
2421
2422 del_timer(&local->timer);
2423
2424 copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2425
2426 if (local->sparm.b4.a_network_type == ADHOC) {
2427 pr_debug("ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
2428 msg->var[0], msg->var[1], msg->var[2], msg->var[3],
2429 msg->var[4], msg->var[5]);
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 file_operations ray_cs_essid_proc_fops = {
2721 .owner = THIS_MODULE,
2722 .write = ray_cs_essid_proc_write,
2723 .llseek = noop_llseek,
2724};
2725
2726static ssize_t int_proc_write(struct file *file, const char __user *buffer,
2727 size_t count, loff_t *pos)
2728{
2729 static char proc_number[10];
2730 char *p;
2731 int nr, len;
2732
2733 if (!count)
2734 return 0;
2735
2736 if (count > 9)
2737 return -EINVAL;
2738 if (copy_from_user(proc_number, buffer, count))
2739 return -EFAULT;
2740 p = proc_number;
2741 nr = 0;
2742 len = count;
2743 do {
2744 unsigned int c = *p - '0';
2745 if (c > 9)
2746 return -EINVAL;
2747 nr = nr * 10 + c;
2748 p++;
2749 } while (--len);
2750 *(int *)PDE_DATA(file_inode(file)) = nr;
2751 return count;
2752}
2753
2754static const struct file_operations int_proc_fops = {
2755 .owner = THIS_MODULE,
2756 .write = int_proc_write,
2757 .llseek = noop_llseek,
2758};
2759#endif
2760
2761static const struct pcmcia_device_id ray_ids[] = {
2762 PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
2763 PCMCIA_DEVICE_NULL,
2764};
2765
2766MODULE_DEVICE_TABLE(pcmcia, ray_ids);
2767
2768static struct pcmcia_driver ray_driver = {
2769 .owner = THIS_MODULE,
2770 .name = "ray_cs",
2771 .probe = ray_probe,
2772 .remove = ray_detach,
2773 .id_table = ray_ids,
2774 .suspend = ray_suspend,
2775 .resume = ray_resume,
2776};
2777
2778static int __init init_ray_cs(void)
2779{
2780 int rc;
2781
2782 pr_debug("%s\n", rcsid);
2783 rc = pcmcia_register_driver(&ray_driver);
2784 pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
2785 rc);
2786 if (rc)
2787 return rc;
2788
2789#ifdef CONFIG_PROC_FS
2790 proc_mkdir("driver/ray_cs", NULL);
2791
2792 proc_create_single("driver/ray_cs/ray_cs", 0, NULL, ray_cs_proc_show);
2793 proc_create("driver/ray_cs/essid", 0200, NULL, &ray_cs_essid_proc_fops);
2794 proc_create_data("driver/ray_cs/net_type", 0200, NULL, &int_proc_fops,
2795 &net_type);
2796 proc_create_data("driver/ray_cs/translate", 0200, NULL, &int_proc_fops,
2797 &translate);
2798#endif
2799 if (translate != 0)
2800 translate = 1;
2801 return 0;
2802}
2803
2804
2805
2806static void __exit exit_ray_cs(void)
2807{
2808 pr_debug("ray_cs: cleanup_module\n");
2809
2810#ifdef CONFIG_PROC_FS
2811 remove_proc_subtree("driver/ray_cs", NULL);
2812#endif
2813
2814 pcmcia_unregister_driver(&ray_driver);
2815}
2816
2817module_init(init_ray_cs);
2818module_exit(exit_ray_cs);
2819
2820
2821