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