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