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