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