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