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 int 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, int, 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) >= 1536) {
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
1111
1112 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1113
1114
1115 wrqu->essid.length = strlen(extra);
1116 wrqu->essid.flags = 1;
1117
1118 return 0;
1119}
1120
1121
1122
1123
1124
1125static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1126 union iwreq_data *wrqu, char *extra)
1127{
1128 ray_dev_t *local = netdev_priv(dev);
1129
1130 memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1131 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1132
1133 return 0;
1134}
1135
1136
1137
1138
1139
1140static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1141 union iwreq_data *wrqu, char *extra)
1142{
1143 ray_dev_t *local = netdev_priv(dev);
1144
1145
1146 if (local->card_status != CARD_AWAITING_PARAM)
1147 return -EBUSY;
1148
1149
1150 if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1151 return -EINVAL;
1152
1153
1154 if ((local->fw_ver == 0x55) &&
1155 (wrqu->bitrate.value == 2000000))
1156 local->net_default_tx_rate = 3;
1157 else
1158 local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1159
1160 return 0;
1161}
1162
1163
1164
1165
1166
1167static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1168 union iwreq_data *wrqu, char *extra)
1169{
1170 ray_dev_t *local = netdev_priv(dev);
1171
1172 if (local->net_default_tx_rate == 3)
1173 wrqu->bitrate.value = 2000000;
1174 else
1175 wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1176 wrqu->bitrate.fixed = 0;
1177
1178 return 0;
1179}
1180
1181
1182
1183
1184
1185static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1186 union iwreq_data *wrqu, char *extra)
1187{
1188 ray_dev_t *local = netdev_priv(dev);
1189 int rthr = wrqu->rts.value;
1190
1191
1192 if (local->card_status != CARD_AWAITING_PARAM)
1193 return -EBUSY;
1194
1195
1196 if (wrqu->rts.disabled)
1197 rthr = 32767;
1198 else {
1199 if ((rthr < 0) || (rthr > 2347))
1200 return -EINVAL;
1201 }
1202 local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1203 local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1204
1205 return -EINPROGRESS;
1206}
1207
1208
1209
1210
1211
1212static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1213 union iwreq_data *wrqu, char *extra)
1214{
1215 ray_dev_t *local = netdev_priv(dev);
1216
1217 wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1218 + local->sparm.b5.a_rts_threshold[1];
1219 wrqu->rts.disabled = (wrqu->rts.value == 32767);
1220 wrqu->rts.fixed = 1;
1221
1222 return 0;
1223}
1224
1225
1226
1227
1228
1229static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1230 union iwreq_data *wrqu, char *extra)
1231{
1232 ray_dev_t *local = netdev_priv(dev);
1233 int fthr = wrqu->frag.value;
1234
1235
1236 if (local->card_status != CARD_AWAITING_PARAM)
1237 return -EBUSY;
1238
1239
1240 if (wrqu->frag.disabled)
1241 fthr = 32767;
1242 else {
1243 if ((fthr < 256) || (fthr > 2347))
1244 return -EINVAL;
1245 }
1246 local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1247 local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1248
1249 return -EINPROGRESS;
1250}
1251
1252
1253
1254
1255
1256static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1257 union iwreq_data *wrqu, char *extra)
1258{
1259 ray_dev_t *local = netdev_priv(dev);
1260
1261 wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1262 + local->sparm.b5.a_frag_threshold[1];
1263 wrqu->frag.disabled = (wrqu->frag.value == 32767);
1264 wrqu->frag.fixed = 1;
1265
1266 return 0;
1267}
1268
1269
1270
1271
1272
1273static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1274 union iwreq_data *wrqu, char *extra)
1275{
1276 ray_dev_t *local = netdev_priv(dev);
1277 int err = -EINPROGRESS;
1278 char card_mode = 1;
1279
1280
1281 if (local->card_status != CARD_AWAITING_PARAM)
1282 return -EBUSY;
1283
1284 switch (wrqu->mode) {
1285 case IW_MODE_ADHOC:
1286 card_mode = 0;
1287
1288 case IW_MODE_INFRA:
1289 local->sparm.b5.a_network_type = card_mode;
1290 break;
1291 default:
1292 err = -EINVAL;
1293 }
1294
1295 return err;
1296}
1297
1298
1299
1300
1301
1302static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1303 union iwreq_data *wrqu, char *extra)
1304{
1305 ray_dev_t *local = netdev_priv(dev);
1306
1307 if (local->sparm.b5.a_network_type)
1308 wrqu->mode = IW_MODE_INFRA;
1309 else
1310 wrqu->mode = IW_MODE_ADHOC;
1311
1312 return 0;
1313}
1314
1315
1316
1317
1318
1319static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1320 union iwreq_data *wrqu, char *extra)
1321{
1322 struct iw_range *range = (struct iw_range *)extra;
1323
1324 memset(range, 0, sizeof(struct iw_range));
1325
1326
1327 wrqu->data.length = sizeof(struct iw_range);
1328
1329
1330 range->we_version_compiled = WIRELESS_EXT;
1331 range->we_version_source = 9;
1332
1333
1334 range->throughput = 1.1 * 1000 * 1000;
1335 range->num_channels = hop_pattern_length[(int)country];
1336 range->num_frequency = 0;
1337 range->max_qual.qual = 0;
1338 range->max_qual.level = 255;
1339 range->max_qual.noise = 255;
1340 range->num_bitrates = 2;
1341 range->bitrate[0] = 1000000;
1342 range->bitrate[1] = 2000000;
1343 return 0;
1344}
1345
1346
1347
1348
1349
1350static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1351 union iwreq_data *wrqu, char *extra)
1352{
1353 translate = *(extra);
1354
1355 return 0;
1356}
1357
1358
1359
1360
1361
1362static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1363 union iwreq_data *wrqu, char *extra)
1364{
1365 *(extra) = translate;
1366
1367 return 0;
1368}
1369
1370
1371
1372
1373
1374static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1375 union iwreq_data *wrqu, char *extra)
1376{
1377 *(extra) = country;
1378
1379 return 0;
1380}
1381
1382
1383
1384
1385
1386static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1387 union iwreq_data *wrqu, char *extra)
1388{
1389 return 0;
1390}
1391
1392
1393
1394
1395
1396static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1397{
1398 ray_dev_t *local = netdev_priv(dev);
1399 struct pcmcia_device *link = local->finder;
1400 struct status __iomem *p = local->sram + STATUS_BASE;
1401
1402 local->wstats.status = local->card_status;
1403#ifdef WIRELESS_SPY
1404 if ((local->spy_data.spy_number > 0)
1405 && (local->sparm.b5.a_network_type == 0)) {
1406
1407 local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
1408 local->wstats.qual.level = local->spy_data.spy_stat[0].level;
1409 local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
1410 local->wstats.qual.updated =
1411 local->spy_data.spy_stat[0].updated;
1412 }
1413#endif
1414
1415 if (pcmcia_dev_present(link)) {
1416 local->wstats.qual.noise = readb(&p->rxnoise);
1417 local->wstats.qual.updated |= 4;
1418 }
1419
1420 return &local->wstats;
1421}
1422
1423
1424
1425
1426
1427
1428static const iw_handler ray_handler[] = {
1429 IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1430 IW_HANDLER(SIOCGIWNAME, ray_get_name),
1431 IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1432 IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1433 IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1434 IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1435 IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1436#ifdef WIRELESS_SPY
1437 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1438 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1439 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1440 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1441#endif
1442 IW_HANDLER(SIOCGIWAP, ray_get_wap),
1443 IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1444 IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1445 IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1446 IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1447 IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1448 IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1449 IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1450 IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1451};
1452
1453#define SIOCSIPFRAMING SIOCIWFIRSTPRIV
1454#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1
1455#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3
1456
1457static const iw_handler ray_private_handler[] = {
1458 [0] = ray_set_framing,
1459 [1] = ray_get_framing,
1460 [3] = ray_get_country,
1461};
1462
1463static const struct iw_priv_args ray_private_args[] = {
1464
1465 {SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
1466 "set_framing"},
1467 {SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1468 "get_framing"},
1469 {SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1470 "get_country"},
1471};
1472
1473static const struct iw_handler_def ray_handler_def = {
1474 .num_standard = ARRAY_SIZE(ray_handler),
1475 .num_private = ARRAY_SIZE(ray_private_handler),
1476 .num_private_args = ARRAY_SIZE(ray_private_args),
1477 .standard = ray_handler,
1478 .private = ray_private_handler,
1479 .private_args = ray_private_args,
1480 .get_wireless_stats = ray_get_wireless_stats,
1481};
1482
1483
1484static int ray_open(struct net_device *dev)
1485{
1486 ray_dev_t *local = netdev_priv(dev);
1487 struct pcmcia_device *link;
1488 link = local->finder;
1489
1490 dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
1491
1492 if (link->open == 0)
1493 local->num_multi = 0;
1494 link->open++;
1495
1496
1497 if (local->card_status == CARD_AWAITING_PARAM) {
1498 int i;
1499
1500 dev_dbg(&link->dev, "ray_open: doing init now !\n");
1501
1502
1503 if ((i = dl_startup_params(dev)) < 0) {
1504 printk(KERN_INFO
1505 "ray_dev_init dl_startup_params failed - "
1506 "returns 0x%x\n", i);
1507 return -1;
1508 }
1509 }
1510
1511 if (sniffer)
1512 netif_stop_queue(dev);
1513 else
1514 netif_start_queue(dev);
1515
1516 dev_dbg(&link->dev, "ray_open ending\n");
1517 return 0;
1518}
1519
1520
1521static int ray_dev_close(struct net_device *dev)
1522{
1523 ray_dev_t *local = netdev_priv(dev);
1524 struct pcmcia_device *link;
1525 link = local->finder;
1526
1527 dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
1528
1529 link->open--;
1530 netif_stop_queue(dev);
1531
1532
1533
1534
1535
1536
1537 return 0;
1538}
1539
1540
1541static void ray_reset(struct net_device *dev)
1542{
1543 pr_debug("ray_reset entered\n");
1544}
1545
1546
1547
1548
1549static int interrupt_ecf(ray_dev_t *local, int ccs)
1550{
1551 int i = 50;
1552 struct pcmcia_device *link = local->finder;
1553
1554 if (!(pcmcia_dev_present(link))) {
1555 dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
1556 return -1;
1557 }
1558 dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
1559
1560 while (i &&
1561 (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
1562 ECF_INTR_SET))
1563 i--;
1564 if (i == 0) {
1565 dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
1566 return -1;
1567 }
1568
1569 writeb(ccs, local->sram + SCB_BASE);
1570 writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1571 return 0;
1572}
1573
1574
1575
1576
1577static int get_free_tx_ccs(ray_dev_t *local)
1578{
1579 int i;
1580 struct ccs __iomem *pccs = ccs_base(local);
1581 struct pcmcia_device *link = local->finder;
1582
1583 if (!(pcmcia_dev_present(link))) {
1584 dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
1585 return ECARDGONE;
1586 }
1587
1588 if (test_and_set_bit(0, &local->tx_ccs_lock)) {
1589 dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
1590 return ECCSBUSY;
1591 }
1592
1593 for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
1594 if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1595 writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1596 writeb(CCS_END_LIST, &(pccs + i)->link);
1597 local->tx_ccs_lock = 0;
1598 return i;
1599 }
1600 }
1601 local->tx_ccs_lock = 0;
1602 dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
1603 return ECCSFULL;
1604}
1605
1606
1607
1608
1609static int get_free_ccs(ray_dev_t *local)
1610{
1611 int i;
1612 struct ccs __iomem *pccs = ccs_base(local);
1613 struct pcmcia_device *link = local->finder;
1614
1615 if (!(pcmcia_dev_present(link))) {
1616 dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
1617 return ECARDGONE;
1618 }
1619 if (test_and_set_bit(0, &local->ccs_lock)) {
1620 dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
1621 return ECCSBUSY;
1622 }
1623
1624 for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1625 if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1626 writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1627 writeb(CCS_END_LIST, &(pccs + i)->link);
1628 local->ccs_lock = 0;
1629 return i;
1630 }
1631 }
1632 local->ccs_lock = 0;
1633 dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
1634 return ECCSFULL;
1635}
1636
1637
1638static void authenticate_timeout(u_long data)
1639{
1640 ray_dev_t *local = (ray_dev_t *) data;
1641 del_timer(&local->timer);
1642 printk(KERN_INFO "ray_cs Authentication with access point failed"
1643 " - timeout\n");
1644 join_net((u_long) local);
1645}
1646
1647
1648static int parse_addr(char *in_str, UCHAR *out)
1649{
1650 int len;
1651 int i, j, k;
1652 int status;
1653
1654 if (in_str == NULL)
1655 return 0;
1656 if ((len = strlen(in_str)) < 2)
1657 return 0;
1658 memset(out, 0, ADDRLEN);
1659
1660 status = 1;
1661 j = len - 1;
1662 if (j > 12)
1663 j = 12;
1664 i = 5;
1665
1666 while (j > 0) {
1667 if ((k = hex_to_bin(in_str[j--])) != -1)
1668 out[i] = k;
1669 else
1670 return 0;
1671
1672 if (j == 0)
1673 break;
1674 if ((k = hex_to_bin(in_str[j--])) != -1)
1675 out[i] += k << 4;
1676 else
1677 return 0;
1678 if (!i--)
1679 break;
1680 }
1681 return status;
1682}
1683
1684
1685static struct net_device_stats *ray_get_stats(struct net_device *dev)
1686{
1687 ray_dev_t *local = netdev_priv(dev);
1688 struct pcmcia_device *link = local->finder;
1689 struct status __iomem *p = local->sram + STATUS_BASE;
1690 if (!(pcmcia_dev_present(link))) {
1691 dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
1692 return &local->stats;
1693 }
1694 if (readb(&p->mrx_overflow_for_host)) {
1695 local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
1696 writeb(0, &p->mrx_overflow);
1697 writeb(0, &p->mrx_overflow_for_host);
1698 }
1699 if (readb(&p->mrx_checksum_error_for_host)) {
1700 local->stats.rx_crc_errors +=
1701 swab16(readw(&p->mrx_checksum_error));
1702 writeb(0, &p->mrx_checksum_error);
1703 writeb(0, &p->mrx_checksum_error_for_host);
1704 }
1705 if (readb(&p->rx_hec_error_for_host)) {
1706 local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
1707 writeb(0, &p->rx_hec_error);
1708 writeb(0, &p->rx_hec_error_for_host);
1709 }
1710 return &local->stats;
1711}
1712
1713
1714static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
1715 int len)
1716{
1717 ray_dev_t *local = netdev_priv(dev);
1718 struct pcmcia_device *link = local->finder;
1719 int ccsindex;
1720 int i;
1721 struct ccs __iomem *pccs;
1722
1723 if (!(pcmcia_dev_present(link))) {
1724 dev_dbg(&link->dev, "ray_update_parm - device not present\n");
1725 return;
1726 }
1727
1728 if ((ccsindex = get_free_ccs(local)) < 0) {
1729 dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
1730 return;
1731 }
1732 pccs = ccs_base(local) + ccsindex;
1733 writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1734 writeb(objid, &pccs->var.update_param.object_id);
1735 writeb(1, &pccs->var.update_param.number_objects);
1736 writeb(0, &pccs->var.update_param.failure_cause);
1737 for (i = 0; i < len; i++) {
1738 writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1739 }
1740
1741 if (interrupt_ecf(local, ccsindex)) {
1742 dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
1743 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1744 }
1745}
1746
1747
1748static void ray_update_multi_list(struct net_device *dev, int all)
1749{
1750 int ccsindex;
1751 struct ccs __iomem *pccs;
1752 ray_dev_t *local = netdev_priv(dev);
1753 struct pcmcia_device *link = local->finder;
1754 void __iomem *p = local->sram + HOST_TO_ECF_BASE;
1755
1756 if (!(pcmcia_dev_present(link))) {
1757 dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
1758 return;
1759 } else
1760 dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
1761 if ((ccsindex = get_free_ccs(local)) < 0) {
1762 dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
1763 return;
1764 }
1765 pccs = ccs_base(local) + ccsindex;
1766 writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
1767
1768 if (all) {
1769 writeb(0xff, &pccs->var);
1770 local->num_multi = 0xff;
1771 } else {
1772 struct netdev_hw_addr *ha;
1773 int i = 0;
1774
1775
1776 netdev_for_each_mc_addr(ha, dev) {
1777 memcpy_toio(p, ha->addr, ETH_ALEN);
1778 dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
1779 ha->addr);
1780 p += ETH_ALEN;
1781 i++;
1782 }
1783 if (i > 256 / ADDRLEN)
1784 i = 256 / ADDRLEN;
1785 writeb((UCHAR) i, &pccs->var);
1786 dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
1787
1788 local->num_multi = i;
1789 }
1790 if (interrupt_ecf(local, ccsindex)) {
1791 dev_dbg(&link->dev,
1792 "ray_cs update_multi failed - ECF not ready for intr\n");
1793 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1794 }
1795}
1796
1797
1798static void set_multicast_list(struct net_device *dev)
1799{
1800 ray_dev_t *local = netdev_priv(dev);
1801 UCHAR promisc;
1802
1803 pr_debug("ray_cs set_multicast_list(%p)\n", dev);
1804
1805 if (dev->flags & IFF_PROMISC) {
1806 if (local->sparm.b5.a_promiscuous_mode == 0) {
1807 pr_debug("ray_cs set_multicast_list promisc on\n");
1808 local->sparm.b5.a_promiscuous_mode = 1;
1809 promisc = 1;
1810 ray_update_parm(dev, OBJID_promiscuous_mode,
1811 &promisc, sizeof(promisc));
1812 }
1813 } else {
1814 if (local->sparm.b5.a_promiscuous_mode == 1) {
1815 pr_debug("ray_cs set_multicast_list promisc off\n");
1816 local->sparm.b5.a_promiscuous_mode = 0;
1817 promisc = 0;
1818 ray_update_parm(dev, OBJID_promiscuous_mode,
1819 &promisc, sizeof(promisc));
1820 }
1821 }
1822
1823 if (dev->flags & IFF_ALLMULTI)
1824 ray_update_multi_list(dev, 1);
1825 else {
1826 if (local->num_multi != netdev_mc_count(dev))
1827 ray_update_multi_list(dev, 0);
1828 }
1829}
1830
1831
1832
1833
1834static irqreturn_t ray_interrupt(int irq, void *dev_id)
1835{
1836 struct net_device *dev = (struct net_device *)dev_id;
1837 struct pcmcia_device *link;
1838 ray_dev_t *local;
1839 struct ccs __iomem *pccs;
1840 struct rcs __iomem *prcs;
1841 UCHAR rcsindex;
1842 UCHAR tmp;
1843 UCHAR cmd;
1844 UCHAR status;
1845
1846 if (dev == NULL)
1847 return IRQ_NONE;
1848
1849 pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
1850
1851 local = netdev_priv(dev);
1852 link = local->finder;
1853 if (!pcmcia_dev_present(link)) {
1854 pr_debug(
1855 "ray_cs interrupt from device not present or suspended.\n");
1856 return IRQ_NONE;
1857 }
1858 rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
1859
1860 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
1861 dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
1862 clear_interrupt(local);
1863 return IRQ_HANDLED;
1864 }
1865 if (rcsindex < NUMBER_OF_CCS) {
1866 pccs = ccs_base(local) + rcsindex;
1867 cmd = readb(&pccs->cmd);
1868 status = readb(&pccs->buffer_status);
1869 switch (cmd) {
1870 case CCS_DOWNLOAD_STARTUP_PARAMS:
1871 del_timer(&local->timer);
1872 if (status == CCS_COMMAND_COMPLETE) {
1873 dev_dbg(&link->dev,
1874 "ray_cs interrupt download_startup_parameters OK\n");
1875 } else {
1876 dev_dbg(&link->dev,
1877 "ray_cs interrupt download_startup_parameters fail\n");
1878 }
1879 break;
1880 case CCS_UPDATE_PARAMS:
1881 dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
1882 if (status != CCS_COMMAND_COMPLETE) {
1883 tmp =
1884 readb(&pccs->var.update_param.
1885 failure_cause);
1886 dev_dbg(&link->dev,
1887 "ray_cs interrupt update params failed - reason %d\n",
1888 tmp);
1889 }
1890 break;
1891 case CCS_REPORT_PARAMS:
1892 dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
1893 break;
1894 case CCS_UPDATE_MULTICAST_LIST:
1895 dev_dbg(&link->dev,
1896 "ray_cs interrupt CCS Update Multicast List done\n");
1897 break;
1898 case CCS_UPDATE_POWER_SAVINGS_MODE:
1899 dev_dbg(&link->dev,
1900 "ray_cs interrupt update power save mode done\n");
1901 break;
1902 case CCS_START_NETWORK:
1903 case CCS_JOIN_NETWORK:
1904 if (status == CCS_COMMAND_COMPLETE) {
1905 if (readb
1906 (&pccs->var.start_network.net_initiated) ==
1907 1) {
1908 dev_dbg(&link->dev,
1909 "ray_cs interrupt network \"%s\" started\n",
1910 local->sparm.b4.a_current_ess_id);
1911 } else {
1912 dev_dbg(&link->dev,
1913 "ray_cs interrupt network \"%s\" joined\n",
1914 local->sparm.b4.a_current_ess_id);
1915 }
1916 memcpy_fromio(&local->bss_id,
1917 pccs->var.start_network.bssid,
1918 ADDRLEN);
1919
1920 if (local->fw_ver == 0x55)
1921 local->net_default_tx_rate = 3;
1922 else
1923 local->net_default_tx_rate =
1924 readb(&pccs->var.start_network.
1925 net_default_tx_rate);
1926 local->encryption =
1927 readb(&pccs->var.start_network.encryption);
1928 if (!sniffer && (local->net_type == INFRA)
1929 && !(local->sparm.b4.a_acting_as_ap_status)) {
1930 authenticate(local);
1931 }
1932 local->card_status = CARD_ACQ_COMPLETE;
1933 } else {
1934 local->card_status = CARD_ACQ_FAILED;
1935
1936 del_timer(&local->timer);
1937 local->timer.expires = jiffies + HZ * 5;
1938 local->timer.data = (long)local;
1939 if (status == CCS_START_NETWORK) {
1940 dev_dbg(&link->dev,
1941 "ray_cs interrupt network \"%s\" start failed\n",
1942 local->sparm.b4.a_current_ess_id);
1943 local->timer.function = start_net;
1944 } else {
1945 dev_dbg(&link->dev,
1946 "ray_cs interrupt network \"%s\" join failed\n",
1947 local->sparm.b4.a_current_ess_id);
1948 local->timer.function = join_net;
1949 }
1950 add_timer(&local->timer);
1951 }
1952 break;
1953 case CCS_START_ASSOCIATION:
1954 if (status == CCS_COMMAND_COMPLETE) {
1955 local->card_status = CARD_ASSOC_COMPLETE;
1956 dev_dbg(&link->dev, "ray_cs association successful\n");
1957 } else {
1958 dev_dbg(&link->dev, "ray_cs association failed,\n");
1959 local->card_status = CARD_ASSOC_FAILED;
1960 join_net((u_long) local);
1961 }
1962 break;
1963 case CCS_TX_REQUEST:
1964 if (status == CCS_COMMAND_COMPLETE) {
1965 dev_dbg(&link->dev,
1966 "ray_cs interrupt tx request complete\n");
1967 } else {
1968 dev_dbg(&link->dev,
1969 "ray_cs interrupt tx request failed\n");
1970 }
1971 if (!sniffer)
1972 netif_start_queue(dev);
1973 netif_wake_queue(dev);
1974 break;
1975 case CCS_TEST_MEMORY:
1976 dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
1977 break;
1978 case CCS_SHUTDOWN:
1979 dev_dbg(&link->dev,
1980 "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
1981 break;
1982 case CCS_DUMP_MEMORY:
1983 dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
1984 break;
1985 case CCS_START_TIMER:
1986 dev_dbg(&link->dev,
1987 "ray_cs interrupt DING - raylink timer expired\n");
1988 break;
1989 default:
1990 dev_dbg(&link->dev,
1991 "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
1992 rcsindex, cmd);
1993 }
1994 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1995 } else {
1996
1997 prcs = rcs_base(local) + rcsindex;
1998
1999 switch (readb(&prcs->interrupt_id)) {
2000 case PROCESS_RX_PACKET:
2001 ray_rx(dev, local, prcs);
2002 break;
2003 case REJOIN_NET_COMPLETE:
2004 dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
2005 local->card_status = CARD_ACQ_COMPLETE;
2006
2007 if (local->sparm.b4.a_network_type == ADHOC) {
2008 if (!sniffer)
2009 netif_start_queue(dev);
2010 } else {
2011 memcpy_fromio(&local->bss_id,
2012 prcs->var.rejoin_net_complete.
2013 bssid, ADDRLEN);
2014 dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
2015 local->bss_id);
2016 if (!sniffer)
2017 authenticate(local);
2018 }
2019 break;
2020 case ROAMING_INITIATED:
2021 dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
2022 netif_stop_queue(dev);
2023 local->card_status = CARD_DOING_ACQ;
2024 break;
2025 case JAPAN_CALL_SIGN_RXD:
2026 dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
2027 break;
2028 default:
2029 dev_dbg(&link->dev,
2030 "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
2031 rcsindex,
2032 (unsigned int)readb(&prcs->interrupt_id));
2033 break;
2034 }
2035 writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
2036 }
2037 clear_interrupt(local);
2038 return IRQ_HANDLED;
2039}
2040
2041
2042static void ray_rx(struct net_device *dev, ray_dev_t *local,
2043 struct rcs __iomem *prcs)
2044{
2045 int rx_len;
2046 unsigned int pkt_addr;
2047 void __iomem *pmsg;
2048 pr_debug("ray_rx process rx packet\n");
2049
2050
2051 pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
2052 + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
2053
2054 rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
2055 + readb(&prcs->var.rx_packet.rx_data_length[1]);
2056
2057 local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
2058 pmsg = local->rmem + pkt_addr;
2059 switch (readb(pmsg)) {
2060 case DATA_TYPE:
2061 pr_debug("ray_rx data type\n");
2062 rx_data(dev, prcs, pkt_addr, rx_len);
2063 break;
2064 case AUTHENTIC_TYPE:
2065 pr_debug("ray_rx authentic type\n");
2066 if (sniffer)
2067 rx_data(dev, prcs, pkt_addr, rx_len);
2068 else
2069 rx_authenticate(local, prcs, pkt_addr, rx_len);
2070 break;
2071 case DEAUTHENTIC_TYPE:
2072 pr_debug("ray_rx deauth type\n");
2073 if (sniffer)
2074 rx_data(dev, prcs, pkt_addr, rx_len);
2075 else
2076 rx_deauthenticate(local, prcs, pkt_addr, rx_len);
2077 break;
2078 case NULL_MSG_TYPE:
2079 pr_debug("ray_cs rx NULL msg\n");
2080 break;
2081 case BEACON_TYPE:
2082 pr_debug("ray_rx beacon type\n");
2083 if (sniffer)
2084 rx_data(dev, prcs, pkt_addr, rx_len);
2085
2086 copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
2087 rx_len < sizeof(struct beacon_rx) ?
2088 rx_len : sizeof(struct beacon_rx));
2089
2090 local->beacon_rxed = 1;
2091
2092 ray_get_stats(dev);
2093 break;
2094 default:
2095 pr_debug("ray_cs unknown pkt type %2x\n",
2096 (unsigned int)readb(pmsg));
2097 break;
2098 }
2099
2100}
2101
2102
2103static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2104 unsigned int pkt_addr, int rx_len)
2105{
2106 struct sk_buff *skb = NULL;
2107 struct rcs __iomem *prcslink = prcs;
2108 ray_dev_t *local = netdev_priv(dev);
2109 UCHAR *rx_ptr;
2110 int total_len;
2111 int tmp;
2112#ifdef WIRELESS_SPY
2113 int siglev = local->last_rsl;
2114 u_char linksrcaddr[ETH_ALEN];
2115#endif
2116
2117 if (!sniffer) {
2118 if (translate) {
2119
2120 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2121 rx_len >
2122 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2123 FCS_LEN)) {
2124 pr_debug(
2125 "ray_cs invalid packet length %d received\n",
2126 rx_len);
2127 return;
2128 }
2129 } else {
2130
2131 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2132 rx_len >
2133 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2134 FCS_LEN)) {
2135 pr_debug(
2136 "ray_cs invalid packet length %d received\n",
2137 rx_len);
2138 return;
2139 }
2140 }
2141 }
2142 pr_debug("ray_cs rx_data packet\n");
2143
2144 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2145 pr_debug("ray_cs rx'ed fragment\n");
2146 tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
2147 + readb(&prcs->var.rx_packet.totalpacketlength[1]);
2148 total_len = tmp;
2149 prcslink = prcs;
2150 do {
2151 tmp -=
2152 (readb(&prcslink->var.rx_packet.rx_data_length[0])
2153 << 8)
2154 + readb(&prcslink->var.rx_packet.rx_data_length[1]);
2155 if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
2156 == 0xFF || tmp < 0)
2157 break;
2158 prcslink = rcs_base(local)
2159 + readb(&prcslink->link_field);
2160 } while (1);
2161
2162 if (tmp < 0) {
2163 pr_debug(
2164 "ray_cs rx_data fragment lengths don't add up\n");
2165 local->stats.rx_dropped++;
2166 release_frag_chain(local, prcs);
2167 return;
2168 }
2169 } else {
2170 total_len = rx_len;
2171 }
2172
2173 skb = dev_alloc_skb(total_len + 5);
2174 if (skb == NULL) {
2175 pr_debug("ray_cs rx_data could not allocate skb\n");
2176 local->stats.rx_dropped++;
2177 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
2178 release_frag_chain(local, prcs);
2179 return;
2180 }
2181 skb_reserve(skb, 2);
2182
2183 pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
2184 rx_len);
2185
2186
2187
2188 rx_ptr = skb_put(skb, total_len);
2189
2190 rx_ptr +=
2191 copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
2192
2193#ifdef WIRELESS_SPY
2194 skb_copy_from_linear_data_offset(skb,
2195 offsetof(struct mac_header, addr_2),
2196 linksrcaddr, ETH_ALEN);
2197#endif
2198
2199 if (!sniffer) {
2200 if (!translate) {
2201
2202
2203 skb_pull(skb, RX_MAC_HEADER_LENGTH);
2204 } else {
2205
2206 untranslate(local, skb, total_len);
2207 }
2208 } else {
2209 };
2210
2211
2212
2213 tmp = 17;
2214 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2215 prcslink = prcs;
2216 pr_debug("ray_cs rx_data in fragment loop\n");
2217 do {
2218 prcslink = rcs_base(local)
2219 +
2220 readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2221 rx_len =
2222 ((readb(&prcslink->var.rx_packet.rx_data_length[0])
2223 << 8)
2224 +
2225 readb(&prcslink->var.rx_packet.rx_data_length[1]))
2226 & RX_BUFF_END;
2227 pkt_addr =
2228 ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
2229 8)
2230 + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
2231 & RX_BUFF_END;
2232
2233 rx_ptr +=
2234 copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
2235
2236 } while (tmp-- &&
2237 readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
2238 0xFF);
2239 release_frag_chain(local, prcs);
2240 }
2241
2242 skb->protocol = eth_type_trans(skb, dev);
2243 netif_rx(skb);
2244 local->stats.rx_packets++;
2245 local->stats.rx_bytes += total_len;
2246
2247
2248#ifdef WIRELESS_SPY
2249
2250
2251
2252 if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
2253
2254
2255 local->wstats.qual.level = siglev;
2256
2257 local->wstats.qual.updated = 0x2;
2258 }
2259
2260 {
2261 struct iw_quality wstats;
2262 wstats.level = siglev;
2263
2264
2265 wstats.updated = 0x2;
2266
2267 wireless_spy_update(dev, linksrcaddr, &wstats);
2268 }
2269#endif
2270}
2271
2272
2273static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
2274{
2275 snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
2276 struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
2277 __be16 type = *(__be16 *) psnap->ethertype;
2278 int delta;
2279 struct ethhdr *peth;
2280 UCHAR srcaddr[ADDRLEN];
2281 UCHAR destaddr[ADDRLEN];
2282 static const UCHAR org_bridge[3] = { 0, 0, 0xf8 };
2283 static const UCHAR org_1042[3] = { 0, 0, 0 };
2284
2285 memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
2286 memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
2287
2288#if 0
2289 if {
2290 print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
2291 DUMP_PREFIX_NONE, 16, 1,
2292 skb->data, 64, true);
2293 printk(KERN_DEBUG
2294 "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
2295 ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
2296 psnap->org[0], psnap->org[1], psnap->org[2]);
2297 printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
2298 }
2299#endif
2300
2301 if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
2302
2303 pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
2304 psnap->dsap, psnap->ssap, psnap->ctrl);
2305
2306 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2307 peth = (struct ethhdr *)(skb->data + delta);
2308 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2309 } else {
2310 if (memcmp(psnap->org, org_bridge, 3) == 0) {
2311
2312 pr_debug("ray_cs untranslate Bridge encap\n");
2313 delta = RX_MAC_HEADER_LENGTH
2314 + sizeof(struct snaphdr_t) - ETH_HLEN;
2315 peth = (struct ethhdr *)(skb->data + delta);
2316 peth->h_proto = type;
2317 } else if (memcmp(psnap->org, org_1042, 3) == 0) {
2318 switch (ntohs(type)) {
2319 case ETH_P_IPX:
2320 case ETH_P_AARP:
2321 pr_debug("ray_cs untranslate RFC IPX/AARP\n");
2322 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2323 peth = (struct ethhdr *)(skb->data + delta);
2324 peth->h_proto =
2325 htons(len - RX_MAC_HEADER_LENGTH);
2326 break;
2327 default:
2328 pr_debug("ray_cs untranslate RFC default\n");
2329 delta = RX_MAC_HEADER_LENGTH +
2330 sizeof(struct snaphdr_t) - ETH_HLEN;
2331 peth = (struct ethhdr *)(skb->data + delta);
2332 peth->h_proto = type;
2333 break;
2334 }
2335 } else {
2336 printk("ray_cs untranslate very confused by packet\n");
2337 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2338 peth = (struct ethhdr *)(skb->data + delta);
2339 peth->h_proto = type;
2340 }
2341 }
2342
2343 skb_pull(skb, delta);
2344 pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
2345 skb->data);
2346 memcpy(peth->h_dest, destaddr, ADDRLEN);
2347 memcpy(peth->h_source, srcaddr, ADDRLEN);
2348#if 0
2349 {
2350 int i;
2351 printk(KERN_DEBUG "skb->data after untranslate:");
2352 for (i = 0; i < 64; i++)
2353 printk("%02x ", skb->data[i]);
2354 printk("\n");
2355 }
2356#endif
2357}
2358
2359
2360
2361
2362
2363
2364
2365static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
2366 int length)
2367{
2368 int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2369 if (wrap_bytes <= 0) {
2370 memcpy_fromio(dest, local->rmem + pkt_addr, length);
2371 } else {
2372
2373 memcpy_fromio(dest, local->rmem + pkt_addr,
2374 length - wrap_bytes);
2375 memcpy_fromio(dest + length - wrap_bytes, local->rmem,
2376 wrap_bytes);
2377 }
2378 return length;
2379}
2380
2381
2382static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
2383{
2384 struct rcs __iomem *prcslink = prcs;
2385 int tmp = 17;
2386 unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2387
2388 while (tmp--) {
2389 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2390 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2391 pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
2392 rcsindex);
2393 break;
2394 }
2395 prcslink = rcs_base(local) + rcsindex;
2396 rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2397 }
2398 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2399}
2400
2401
2402static void authenticate(ray_dev_t *local)
2403{
2404 struct pcmcia_device *link = local->finder;
2405 dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
2406 if (!(pcmcia_dev_present(link))) {
2407 dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
2408 return;
2409 }
2410
2411 del_timer(&local->timer);
2412 if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2413 local->timer.function = join_net;
2414 } else {
2415 local->timer.function = authenticate_timeout;
2416 }
2417 local->timer.expires = jiffies + HZ * 2;
2418 local->timer.data = (long)local;
2419 add_timer(&local->timer);
2420 local->authentication_state = AWAITING_RESPONSE;
2421}
2422
2423
2424static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2425 unsigned int pkt_addr, int rx_len)
2426{
2427 UCHAR buff[256];
2428 struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
2429
2430 del_timer(&local->timer);
2431
2432 copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2433
2434 if (local->sparm.b4.a_network_type == ADHOC) {
2435 pr_debug("ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
2436 msg->var[0], msg->var[1], msg->var[2], msg->var[3],
2437 msg->var[4], msg->var[5]);
2438 if (msg->var[2] == 1) {
2439 pr_debug("ray_cs Sending authentication response.\n");
2440 if (!build_auth_frame
2441 (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
2442 local->authentication_state = NEED_TO_AUTH;
2443 memcpy(local->auth_id, msg->mac.addr_2,
2444 ADDRLEN);
2445 }
2446 }
2447 } else {
2448
2449 if (local->authentication_state == AWAITING_RESPONSE) {
2450
2451 if (msg->var[2] == 2) {
2452 if ((msg->var[3] | msg->var[4]) == 0) {
2453 pr_debug("Authentication successful\n");
2454 local->card_status = CARD_AUTH_COMPLETE;
2455 associate(local);
2456 local->authentication_state =
2457 AUTHENTICATED;
2458 } else {
2459 pr_debug("Authentication refused\n");
2460 local->card_status = CARD_AUTH_REFUSED;
2461 join_net((u_long) local);
2462 local->authentication_state =
2463 UNAUTHENTICATED;
2464 }
2465 }
2466 }
2467 }
2468
2469}
2470
2471
2472static void associate(ray_dev_t *local)
2473{
2474 struct ccs __iomem *pccs;
2475 struct pcmcia_device *link = local->finder;
2476 struct net_device *dev = link->priv;
2477 int ccsindex;
2478 if (!(pcmcia_dev_present(link))) {
2479 dev_dbg(&link->dev, "ray_cs associate - device not present\n");
2480 return;
2481 }
2482
2483 if ((ccsindex = get_free_ccs(local)) < 0) {
2484
2485 dev_dbg(&link->dev, "ray_cs associate - No free ccs\n");
2486 return;
2487 }
2488 dev_dbg(&link->dev, "ray_cs Starting association with access point\n");
2489 pccs = ccs_base(local) + ccsindex;
2490
2491 writeb(CCS_START_ASSOCIATION, &pccs->cmd);
2492
2493 if (interrupt_ecf(local, ccsindex)) {
2494 dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
2495 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2496
2497 del_timer(&local->timer);
2498 local->timer.expires = jiffies + HZ * 2;
2499 local->timer.data = (long)local;
2500 local->timer.function = join_net;
2501 add_timer(&local->timer);
2502 local->card_status = CARD_ASSOC_FAILED;
2503 return;
2504 }
2505 if (!sniffer)
2506 netif_start_queue(dev);
2507
2508}
2509
2510
2511static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2512 unsigned int pkt_addr, int rx_len)
2513{
2514
2515
2516
2517 pr_debug("Deauthentication frame received\n");
2518 local->authentication_state = UNAUTHENTICATED;
2519
2520
2521
2522}
2523
2524
2525static void clear_interrupt(ray_dev_t *local)
2526{
2527 writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
2528}
2529
2530
2531#ifdef CONFIG_PROC_FS
2532#define MAXDATA (PAGE_SIZE - 80)
2533
2534static const char *card_status[] = {
2535 "Card inserted - uninitialized",
2536 "Card not downloaded",
2537 "Waiting for download parameters",
2538 "Card doing acquisition",
2539 "Acquisition complete",
2540 "Authentication complete",
2541 "Association complete",
2542 "???", "???", "???", "???",
2543 "Card init error",
2544 "Download parameters error",
2545 "???",
2546 "Acquisition failed",
2547 "Authentication refused",
2548 "Association failed"
2549};
2550
2551static const char *nettype[] = { "Adhoc", "Infra " };
2552static const char *framing[] = { "Encapsulation", "Translation" }
2553
2554;
2555
2556static int ray_cs_proc_show(struct seq_file *m, void *v)
2557{
2558
2559
2560
2561 int i;
2562 struct pcmcia_device *link;
2563 struct net_device *dev;
2564 ray_dev_t *local;
2565 UCHAR *p;
2566 struct freq_hop_element *pfh;
2567 UCHAR c[33];
2568
2569 link = this_device;
2570 if (!link)
2571 return 0;
2572 dev = (struct net_device *)link->priv;
2573 if (!dev)
2574 return 0;
2575 local = netdev_priv(dev);
2576 if (!local)
2577 return 0;
2578
2579 seq_puts(m, "Raylink Wireless LAN driver status\n");
2580 seq_printf(m, "%s\n", rcsid);
2581
2582 seq_puts(m, "Firmware version = ");
2583 if (local->fw_ver == 0x55)
2584 seq_puts(m, "4 - Use dump_cis for more details\n");
2585 else
2586 seq_printf(m, "%2d.%02d.%02d\n",
2587 local->fw_ver, local->fw_bld, local->fw_var);
2588
2589 for (i = 0; i < 32; i++)
2590 c[i] = local->sparm.b5.a_current_ess_id[i];
2591 c[32] = 0;
2592 seq_printf(m, "%s network ESSID = \"%s\"\n",
2593 nettype[local->sparm.b5.a_network_type], c);
2594
2595 p = local->bss_id;
2596 seq_printf(m, "BSSID = %pM\n", p);
2597
2598 seq_printf(m, "Country code = %d\n",
2599 local->sparm.b5.a_curr_country_code);
2600
2601 i = local->card_status;
2602 if (i < 0)
2603 i = 10;
2604 if (i > 16)
2605 i = 10;
2606 seq_printf(m, "Card status = %s\n", card_status[i]);
2607
2608 seq_printf(m, "Framing mode = %s\n", framing[translate]);
2609
2610 seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
2611
2612 if (local->beacon_rxed) {
2613
2614 seq_printf(m, "Beacon Interval = %d Kus\n",
2615 local->last_bcn.beacon_intvl[0]
2616 + 256 * local->last_bcn.beacon_intvl[1]);
2617
2618 p = local->last_bcn.elements;
2619 if (p[0] == C_ESSID_ELEMENT_ID)
2620 p += p[1] + 2;
2621 else {
2622 seq_printf(m,
2623 "Parse beacon failed at essid element id = %d\n",
2624 p[0]);
2625 return 0;
2626 }
2627
2628 if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
2629 seq_puts(m, "Supported rate codes = ");
2630 for (i = 2; i < p[1] + 2; i++)
2631 seq_printf(m, "0x%02x ", p[i]);
2632 seq_putc(m, '\n');
2633 p += p[1] + 2;
2634 } else {
2635 seq_puts(m, "Parse beacon failed at rates element\n");
2636 return 0;
2637 }
2638
2639 if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
2640 pfh = (struct freq_hop_element *)p;
2641 seq_printf(m, "Hop dwell = %d Kus\n",
2642 pfh->dwell_time[0] +
2643 256 * pfh->dwell_time[1]);
2644 seq_printf(m, "Hop set = %d\n",
2645 pfh->hop_set);
2646 seq_printf(m, "Hop pattern = %d\n",
2647 pfh->hop_pattern);
2648 seq_printf(m, "Hop index = %d\n",
2649 pfh->hop_index);
2650 p += p[1] + 2;
2651 } else {
2652 seq_puts(m,
2653 "Parse beacon failed at FH param element\n");
2654 return 0;
2655 }
2656 } else {
2657 seq_puts(m, "No beacons received\n");
2658 }
2659 return 0;
2660}
2661
2662static int ray_cs_proc_open(struct inode *inode, struct file *file)
2663{
2664 return single_open(file, ray_cs_proc_show, NULL);
2665}
2666
2667static const struct file_operations ray_cs_proc_fops = {
2668 .owner = THIS_MODULE,
2669 .open = ray_cs_proc_open,
2670 .read = seq_read,
2671 .llseek = seq_lseek,
2672 .release = single_release,
2673};
2674#endif
2675
2676static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
2677{
2678 int addr;
2679 struct ccs __iomem *pccs;
2680 struct tx_msg __iomem *ptx;
2681 int ccsindex;
2682
2683
2684 if ((ccsindex = get_free_tx_ccs(local)) < 0) {
2685 pr_debug("ray_cs send authenticate - No free tx ccs\n");
2686 return -1;
2687 }
2688
2689 pccs = ccs_base(local) + ccsindex;
2690
2691
2692 addr = TX_BUF_BASE + (ccsindex << 11);
2693
2694 writeb(CCS_TX_REQUEST, &pccs->cmd);
2695 writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
2696 writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
2697 writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
2698 writeb(TX_AUTHENTICATE_LENGTH_LSB,
2699 pccs->var.tx_request.tx_data_length + 1);
2700 writeb(0, &pccs->var.tx_request.pow_sav_mode);
2701
2702 ptx = local->sram + addr;
2703
2704 writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
2705 writeb(0, &ptx->mac.frame_ctl_2);
2706
2707 memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
2708 memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
2709 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
2710
2711
2712 memset_io(ptx->var, 0, 6);
2713 writeb(auth_type & 0xff, ptx->var + 2);
2714
2715
2716 if (interrupt_ecf(local, ccsindex)) {
2717 pr_debug(
2718 "ray_cs send authentication request failed - ECF not ready for intr\n");
2719 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2720 return -1;
2721 }
2722 return 0;
2723}
2724
2725
2726#ifdef CONFIG_PROC_FS
2727static ssize_t ray_cs_essid_proc_write(struct file *file,
2728 const char __user *buffer, size_t count, loff_t *pos)
2729{
2730 static char proc_essid[33];
2731 unsigned int len = count;
2732
2733 if (len > 32)
2734 len = 32;
2735 memset(proc_essid, 0, 33);
2736 if (copy_from_user(proc_essid, buffer, len))
2737 return -EFAULT;
2738 essid = proc_essid;
2739 return count;
2740}
2741
2742static const struct file_operations ray_cs_essid_proc_fops = {
2743 .owner = THIS_MODULE,
2744 .write = ray_cs_essid_proc_write,
2745 .llseek = noop_llseek,
2746};
2747
2748static ssize_t int_proc_write(struct file *file, const char __user *buffer,
2749 size_t count, loff_t *pos)
2750{
2751 static char proc_number[10];
2752 char *p;
2753 int nr, len;
2754
2755 if (!count)
2756 return 0;
2757
2758 if (count > 9)
2759 return -EINVAL;
2760 if (copy_from_user(proc_number, buffer, count))
2761 return -EFAULT;
2762 p = proc_number;
2763 nr = 0;
2764 len = count;
2765 do {
2766 unsigned int c = *p - '0';
2767 if (c > 9)
2768 return -EINVAL;
2769 nr = nr * 10 + c;
2770 p++;
2771 } while (--len);
2772 *(int *)PDE(file->f_path.dentry->d_inode)->data = nr;
2773 return count;
2774}
2775
2776static const struct file_operations int_proc_fops = {
2777 .owner = THIS_MODULE,
2778 .write = int_proc_write,
2779 .llseek = noop_llseek,
2780};
2781#endif
2782
2783static const struct pcmcia_device_id ray_ids[] = {
2784 PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
2785 PCMCIA_DEVICE_NULL,
2786};
2787
2788MODULE_DEVICE_TABLE(pcmcia, ray_ids);
2789
2790static struct pcmcia_driver ray_driver = {
2791 .owner = THIS_MODULE,
2792 .name = "ray_cs",
2793 .probe = ray_probe,
2794 .remove = ray_detach,
2795 .id_table = ray_ids,
2796 .suspend = ray_suspend,
2797 .resume = ray_resume,
2798};
2799
2800static int __init init_ray_cs(void)
2801{
2802 int rc;
2803
2804 pr_debug("%s\n", rcsid);
2805 rc = pcmcia_register_driver(&ray_driver);
2806 pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
2807 rc);
2808
2809#ifdef CONFIG_PROC_FS
2810 proc_mkdir("driver/ray_cs", NULL);
2811
2812 proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
2813 proc_create("driver/ray_cs/essid", S_IWUSR, NULL, &ray_cs_essid_proc_fops);
2814 proc_create_data("driver/ray_cs/net_type", S_IWUSR, NULL, &int_proc_fops, &net_type);
2815 proc_create_data("driver/ray_cs/translate", S_IWUSR, NULL, &int_proc_fops, &translate);
2816#endif
2817 if (translate != 0)
2818 translate = 1;
2819 return 0;
2820}
2821
2822
2823
2824static void __exit exit_ray_cs(void)
2825{
2826 pr_debug("ray_cs: cleanup_module\n");
2827
2828#ifdef CONFIG_PROC_FS
2829 remove_proc_entry("driver/ray_cs/ray_cs", NULL);
2830 remove_proc_entry("driver/ray_cs/essid", NULL);
2831 remove_proc_entry("driver/ray_cs/net_type", NULL);
2832 remove_proc_entry("driver/ray_cs/translate", NULL);
2833 remove_proc_entry("driver/ray_cs", NULL);
2834#endif
2835
2836 pcmcia_unregister_driver(&ray_driver);
2837}
2838
2839module_init(init_ray_cs);
2840module_exit(exit_ray_cs);
2841
2842
2843