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