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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60#include "wavelan_cs.p.h"
61
62#ifdef WAVELAN_ROAMING
63static void wl_cell_expiry(unsigned long data);
64static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp);
65static void wv_nwid_filter(unsigned char mode, net_local *lp);
66#endif
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83static inline u_char
84hasr_read(u_long base)
85{
86 return(inb(HASR(base)));
87}
88
89
90
91
92
93static inline void
94hacr_write(u_long base,
95 u_char hacr)
96{
97 outb(hacr, HACR(base));
98}
99
100
101
102
103
104
105static void
106hacr_write_slow(u_long base,
107 u_char hacr)
108{
109 hacr_write(base, hacr);
110
111 mdelay(1);
112}
113
114
115
116
117
118static void
119psa_read(struct net_device * dev,
120 int o,
121 u_char * b,
122 int n)
123{
124 net_local *lp = netdev_priv(dev);
125 u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
126
127 while(n-- > 0)
128 {
129 *b++ = readb(ptr);
130
131
132
133
134
135 ptr += 2;
136 }
137}
138
139
140
141
142
143static void
144psa_write(struct net_device * dev,
145 int o,
146 u_char * b,
147 int n)
148{
149 net_local *lp = netdev_priv(dev);
150 u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
151 int count = 0;
152 unsigned int base = dev->base_addr;
153
154
155 volatile u_char __iomem *verify = lp->mem + PSA_ADDR +
156 (psaoff(0, psa_comp_number) << 1);
157
158
159 hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN);
160
161 while(n-- > 0)
162 {
163
164 writeb(*b++, ptr);
165 ptr += 2;
166
167
168
169 count = 0;
170 while((readb(verify) != PSA_COMP_PCMCIA_915) && (count++ < 100))
171 mdelay(1);
172 }
173
174
175 hacr_write(base, HACR_DEFAULT);
176}
177
178#ifdef SET_PSA_CRC
179
180
181
182
183
184
185
186
187
188
189static u_short
190psa_crc(unsigned char * psa,
191 int size)
192{
193 int byte_cnt;
194 u_short crc_bytes = 0;
195 int bit_cnt;
196
197 for(byte_cnt = 0; byte_cnt < size; byte_cnt++ )
198 {
199 crc_bytes ^= psa[byte_cnt];
200
201 for(bit_cnt = 1; bit_cnt < 9; bit_cnt++ )
202 {
203 if(crc_bytes & 0x0001)
204 crc_bytes = (crc_bytes >> 1) ^ 0xA001;
205 else
206 crc_bytes >>= 1 ;
207 }
208 }
209
210 return crc_bytes;
211}
212#endif
213
214
215
216
217
218static void
219update_psa_checksum(struct net_device * dev)
220{
221#ifdef SET_PSA_CRC
222 psa_t psa;
223 u_short crc;
224
225
226 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
227
228
229 crc = psa_crc((unsigned char *) &psa,
230 sizeof(psa) - sizeof(psa.psa_crc[0]) - sizeof(psa.psa_crc[1])
231 - sizeof(psa.psa_crc_status));
232
233 psa.psa_crc[0] = crc & 0xFF;
234 psa.psa_crc[1] = (crc & 0xFF00) >> 8;
235
236
237 psa_write(dev, (char *)&psa.psa_crc - (char *)&psa,
238 (unsigned char *)&psa.psa_crc, 2);
239
240#ifdef DEBUG_IOCTL_INFO
241 printk (KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
242 dev->name, psa.psa_crc[0], psa.psa_crc[1]);
243
244
245 crc = psa_crc((unsigned char *) &psa,
246 sizeof(psa) - sizeof(psa.psa_crc_status));
247
248 if(crc != 0)
249 printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name);
250#endif
251#endif
252}
253
254
255
256
257
258static void
259mmc_out(u_long base,
260 u_short o,
261 u_char d)
262{
263 int count = 0;
264
265
266 while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
267 udelay(10);
268
269 outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base));
270 outb(d, MMD(base));
271}
272
273
274
275
276
277
278static void
279mmc_write(u_long base,
280 u_char o,
281 u_char * b,
282 int n)
283{
284 o += n;
285 b += n;
286
287 while(n-- > 0 )
288 mmc_out(base, --o, *(--b));
289}
290
291
292
293
294
295
296static u_char
297mmc_in(u_long base,
298 u_short o)
299{
300 int count = 0;
301
302 while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
303 udelay(10);
304 outb(o << 1, MMR(base));
305
306 outb(0, MMD(base));
307
308 while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
309 udelay(10);
310 return (u_char) (inb(MMD(base)));
311}
312
313
314
315
316
317
318
319
320
321static void
322mmc_read(u_long base,
323 u_char o,
324 u_char * b,
325 int n)
326{
327 o += n;
328 b += n;
329
330 while(n-- > 0)
331 *(--b) = mmc_in(base, --o);
332}
333
334
335
336
337
338static inline int
339mmc_encr(u_long base)
340{
341 int temp;
342
343 temp = mmc_in(base, mmroff(0, mmr_des_avail));
344 if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
345 return 0;
346 else
347 return temp;
348}
349
350
351
352
353
354static void
355fee_wait(u_long base,
356 int delay,
357 int number)
358{
359 int count = 0;
360
361 while((count++ < number) &&
362 (mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY))
363 udelay(delay);
364}
365
366
367
368
369
370static void
371fee_read(u_long base,
372 u_short o,
373 u_short * b,
374 int n)
375{
376 b += n;
377
378
379 mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
380
381
382 while(n-- > 0)
383 {
384
385 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ);
386
387
388 fee_wait(base, 10, 100);
389
390
391 *--b = ((mmc_in(base, mmroff(0, mmr_fee_data_h)) << 8) |
392 mmc_in(base, mmroff(0, mmr_fee_data_l)));
393 }
394}
395
396
397
398
399
400
401
402
403
404static void
405fee_write(u_long base,
406 u_short o,
407 u_short * b,
408 int n)
409{
410 b += n;
411
412#ifdef EEPROM_IS_PROTECTED
413#ifdef DOESNT_SEEM_TO_WORK
414
415 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
416
417 fee_wait(base, 10, 100);
418
419
420 printk("Protected 2 : %02X-%02X\n",
421 mmc_in(base, mmroff(0, mmr_fee_data_h)),
422 mmc_in(base, mmroff(0, mmr_fee_data_l)));
423#endif
424
425
426 mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
427 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
428
429 fee_wait(base, 10, 100);
430
431
432 mmc_out(base, mmwoff(0, mmw_fee_addr), o + n);
433 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
434#ifdef DOESNT_SEEM_TO_WORK
435
436 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
437#endif
438
439 fee_wait(base, 10, 100);
440#endif
441
442
443 mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
444 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
445
446 fee_wait(base, 10, 100);
447
448
449 mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
450
451
452 while(n-- > 0)
453 {
454
455 mmc_out(base, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
456 mmc_out(base, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
457
458
459 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE);
460
461
462 mdelay(10);
463 fee_wait(base, 10, 100);
464 }
465
466
467 mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
468 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
469
470 fee_wait(base, 10, 100);
471
472#ifdef EEPROM_IS_PROTECTED
473
474 mmc_out(base, mmwoff(0, mmw_fee_addr), 0x00);
475 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
476
477 fee_wait(base, 10, 100);
478#endif
479}
480
481
482
483#ifdef WAVELAN_ROAMING
484
485static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00};
486
487static void wv_roam_init(struct net_device *dev)
488{
489 net_local *lp= netdev_priv(dev);
490
491
492 printk(KERN_NOTICE "%s: Warning, you have enabled roaming on"
493 " device %s !\n", dev->name, dev->name);
494 printk(KERN_NOTICE "Roaming is currently an experimental unsupported feature"
495 " of the Wavelan driver.\n");
496 printk(KERN_NOTICE "It may work, but may also make the driver behave in"
497 " erratic ways or crash.\n");
498
499 lp->wavepoint_table.head=NULL;
500 lp->wavepoint_table.num_wavepoints=0;
501 lp->wavepoint_table.locked=0;
502 lp->curr_point=NULL;
503 lp->cell_search=0;
504
505 lp->cell_timer.data=(long)lp;
506 lp->cell_timer.function=wl_cell_expiry;
507 lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
508 add_timer(&lp->cell_timer);
509
510 wv_nwid_filter(NWID_PROMISC,lp) ;
511
512
513 printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
514}
515
516static void wv_roam_cleanup(struct net_device *dev)
517{
518 wavepoint_history *ptr,*old_ptr;
519 net_local *lp= netdev_priv(dev);
520
521 printk(KERN_DEBUG "WaveLAN: Roaming Disabled on device %s\n",dev->name);
522
523
524 del_timer(&lp->cell_timer);
525 ptr=lp->wavepoint_table.head;
526 while(ptr!=NULL)
527 {
528 old_ptr=ptr;
529 ptr=ptr->next;
530 wl_del_wavepoint(old_ptr,lp);
531 }
532}
533
534
535static void wv_nwid_filter(unsigned char mode, net_local *lp)
536{
537 mm_t m;
538 unsigned long flags;
539
540#ifdef WAVELAN_ROAMING_DEBUG
541 printk(KERN_DEBUG "WaveLAN: NWID promisc %s, device %s\n",(mode==NWID_PROMISC) ? "on" : "off", lp->dev->name);
542#endif
543
544
545 spin_lock_irqsave(&lp->spinlock, flags);
546
547 m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
548 mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
549
550 if(mode==NWID_PROMISC)
551 lp->cell_search=1;
552 else
553 lp->cell_search=0;
554
555
556 spin_unlock_irqrestore(&lp->spinlock, flags);
557}
558
559
560static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
561{
562 wavepoint_history *ptr=lp->wavepoint_table.head;
563
564 while(ptr!=NULL){
565 if(ptr->nwid==nwid)
566 return ptr;
567 ptr=ptr->next;
568 }
569 return NULL;
570}
571
572
573static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
574{
575 wavepoint_history *new_wavepoint;
576
577#ifdef WAVELAN_ROAMING_DEBUG
578 printk(KERN_DEBUG "WaveLAN: New Wavepoint, NWID:%.4X\n",nwid);
579#endif
580
581 if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
582 return NULL;
583
584 new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
585 if(new_wavepoint==NULL)
586 return NULL;
587
588 new_wavepoint->nwid=nwid;
589 new_wavepoint->average_fast=0;
590 new_wavepoint->average_slow=0;
591 new_wavepoint->qualptr=0;
592 new_wavepoint->last_seq=seq-1;
593 memset(new_wavepoint->sigqual,0,WAVEPOINT_HISTORY);
594
595 new_wavepoint->next=lp->wavepoint_table.head;
596 new_wavepoint->prev=NULL;
597
598 if(lp->wavepoint_table.head!=NULL)
599 lp->wavepoint_table.head->prev=new_wavepoint;
600
601 lp->wavepoint_table.head=new_wavepoint;
602
603 lp->wavepoint_table.num_wavepoints++;
604
605 return new_wavepoint;
606}
607
608
609static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
610{
611 if(wavepoint==NULL)
612 return;
613
614 if(lp->curr_point==wavepoint)
615 lp->curr_point=NULL;
616
617 if(wavepoint->prev!=NULL)
618 wavepoint->prev->next=wavepoint->next;
619
620 if(wavepoint->next!=NULL)
621 wavepoint->next->prev=wavepoint->prev;
622
623 if(lp->wavepoint_table.head==wavepoint)
624 lp->wavepoint_table.head=wavepoint->next;
625
626 lp->wavepoint_table.num_wavepoints--;
627 kfree(wavepoint);
628}
629
630
631static void wl_cell_expiry(unsigned long data)
632{
633 net_local *lp=(net_local *)data;
634 wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
635
636#if WAVELAN_ROAMING_DEBUG > 1
637 printk(KERN_DEBUG "WaveLAN: Wavepoint timeout, dev %s\n",lp->dev->name);
638#endif
639
640 if(lp->wavepoint_table.locked)
641 {
642#if WAVELAN_ROAMING_DEBUG > 1
643 printk(KERN_DEBUG "WaveLAN: Wavepoint table locked...\n");
644#endif
645
646 lp->cell_timer.expires=jiffies+1;
647 add_timer(&lp->cell_timer);
648 return;
649 }
650
651 while(wavepoint!=NULL)
652 {
653 if(time_after(jiffies, wavepoint->last_seen + CELL_TIMEOUT))
654 {
655#ifdef WAVELAN_ROAMING_DEBUG
656 printk(KERN_DEBUG "WaveLAN: Bye bye %.4X\n",wavepoint->nwid);
657#endif
658
659 old_point=wavepoint;
660 wavepoint=wavepoint->next;
661 wl_del_wavepoint(old_point,lp);
662 }
663 else
664 wavepoint=wavepoint->next;
665 }
666 lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
667 add_timer(&lp->cell_timer);
668}
669
670
671static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)
672{
673 int i=0,num_missed=0,ptr=0;
674 int average_fast=0,average_slow=0;
675
676 num_missed=(seq-wavepoint->last_seq)%WAVEPOINT_HISTORY;
677
678 if(num_missed)
679 for(i=0;i<num_missed;i++)
680 {
681 wavepoint->sigqual[wavepoint->qualptr++]=0;
682 wavepoint->qualptr %=WAVEPOINT_HISTORY;
683 }
684 wavepoint->last_seen=jiffies;
685 wavepoint->last_seq=seq;
686 wavepoint->sigqual[wavepoint->qualptr++]=sigqual;
687 wavepoint->qualptr %=WAVEPOINT_HISTORY;
688 ptr=(wavepoint->qualptr-WAVEPOINT_FAST_HISTORY+WAVEPOINT_HISTORY)%WAVEPOINT_HISTORY;
689
690 for(i=0;i<WAVEPOINT_FAST_HISTORY;i++)
691 {
692 average_fast+=wavepoint->sigqual[ptr++];
693 ptr %=WAVEPOINT_HISTORY;
694 }
695
696 average_slow=average_fast;
697 for(i=WAVEPOINT_FAST_HISTORY;i<WAVEPOINT_HISTORY;i++)
698 {
699 average_slow+=wavepoint->sigqual[ptr++];
700 ptr %=WAVEPOINT_HISTORY;
701 }
702
703 wavepoint->average_fast=average_fast/WAVEPOINT_FAST_HISTORY;
704 wavepoint->average_slow=average_slow/WAVEPOINT_HISTORY;
705}
706
707
708static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
709{
710 unsigned int base = lp->dev->base_addr;
711 mm_t m;
712 unsigned long flags;
713
714 if(wavepoint==lp->curr_point)
715 {
716 wv_nwid_filter(!NWID_PROMISC,lp);
717 return;
718 }
719
720#ifdef WAVELAN_ROAMING_DEBUG
721 printk(KERN_DEBUG "WaveLAN: Doing handover to %.4X, dev %s\n",wavepoint->nwid,lp->dev->name);
722#endif
723
724
725 spin_lock_irqsave(&lp->spinlock, flags);
726
727 m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
728 m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
729
730 mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
731
732
733 spin_unlock_irqrestore(&lp->spinlock, flags);
734
735 wv_nwid_filter(!NWID_PROMISC,lp);
736 lp->curr_point=wavepoint;
737}
738
739
740static void wl_roam_gather(struct net_device * dev,
741 u_char * hdr,
742 u_char * stats)
743
744{
745 wavepoint_beacon *beacon= (wavepoint_beacon *)hdr;
746 unsigned short nwid=ntohs(beacon->nwid);
747 unsigned short sigqual=stats[2] & MMR_SGNL_QUAL;
748 wavepoint_history *wavepoint=NULL;
749 net_local *lp = netdev_priv(dev);
750
751#ifdef I_NEED_THIS_FEATURE
752
753 nwid=nwid^ntohs(beacon->domain_id);
754#endif
755
756#if WAVELAN_ROAMING_DEBUG > 1
757 printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name);
758 printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual);
759#endif
760
761 lp->wavepoint_table.locked=1;
762
763 wavepoint=wl_roam_check(nwid,lp);
764 if(wavepoint==NULL)
765 {
766 wavepoint=wl_new_wavepoint(nwid,beacon->seq,lp);
767 if(wavepoint==NULL)
768 goto out;
769 }
770 if(lp->curr_point==NULL)
771 wv_roam_handover(wavepoint, lp);
772
773 wl_update_history(wavepoint, sigqual, beacon->seq);
774
775
776 if(lp->curr_point->average_slow < SEARCH_THRESH_LOW)
777 if(!lp->cell_search)
778 wv_nwid_filter(NWID_PROMISC,lp);
779
780 if(wavepoint->average_slow >
781 lp->curr_point->average_slow + WAVELAN_ROAMING_DELTA)
782 wv_roam_handover(wavepoint, lp);
783
784 if(lp->curr_point->average_slow > SEARCH_THRESH_HIGH)
785 if(lp->cell_search)
786 wv_nwid_filter(!NWID_PROMISC,lp);
787
788out:
789 lp->wavepoint_table.locked=0;
790}
791
792
793static inline int WAVELAN_BEACON(unsigned char *data)
794{
795 wavepoint_beacon *beacon= (wavepoint_beacon *)data;
796 static const wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00};
797
798 if(memcmp(beacon,&beacon_template,9)==0)
799 return 1;
800 else
801 return 0;
802}
803#endif
804
805
806
807
808
809
810
811
812
813
814
815
816
817static int
818wv_82593_cmd(struct net_device * dev,
819 char * str,
820 int cmd,
821 int result)
822{
823 unsigned int base = dev->base_addr;
824 int status;
825 int wait_completed;
826 long spin;
827
828
829 spin = 1000;
830 do
831 {
832
833 udelay(10);
834
835
836 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
837 status = inb(LCSR(base));
838 }
839 while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
840
841
842 if (spin < 0) {
843#ifdef DEBUG_INTERRUPT_ERROR
844 printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
845 str, status);
846#endif
847 return(FALSE);
848 }
849
850
851 outb(cmd, LCCR(base));
852
853
854
855 if(result == SR0_NO_RESULT)
856 return(TRUE);
857
858
859 wait_completed = TRUE;
860
861
862 spin = 1000;
863 do
864 {
865
866 udelay(10);
867
868
869 outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
870 status = inb(LCSR(base));
871
872
873 if((status & SR0_INTERRUPT))
874 {
875
876 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
877
878
879 if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) &&
880 ((status & SR0_BOTH_RX_TX) != 0x0) &&
881 !(status & SR0_RECEPTION))
882 {
883
884 wait_completed = FALSE;
885 }
886 else
887 {
888
889
890#ifdef DEBUG_INTERRUPT_INFO
891 printk(KERN_INFO "wv_82593_cmd: not our interrupt\n");
892#endif
893 }
894 }
895 }
896 while(wait_completed && (spin-- > 0));
897
898
899 if(wait_completed)
900 {
901#ifdef DEBUG_INTERRUPT_ERROR
902 printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n",
903 str, status);
904#endif
905 return(FALSE);
906 }
907
908
909
910 if((status & SR0_EVENT_MASK) != result)
911 {
912#ifdef DEBUG_INTERRUPT_ERROR
913 printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n",
914 str, status);
915#endif
916 return(FALSE);
917 }
918
919 return(TRUE);
920}
921
922
923
924
925
926
927static inline int
928wv_diag(struct net_device * dev)
929{
930 return(wv_82593_cmd(dev, "wv_diag(): diagnose",
931 OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED));
932}
933
934
935
936
937
938
939
940static int
941read_ringbuf(struct net_device * dev,
942 int addr,
943 char * buf,
944 int len)
945{
946 unsigned int base = dev->base_addr;
947 int ring_ptr = addr;
948 int chunk_len;
949 char * buf_ptr = buf;
950
951
952 while(len > 0)
953 {
954
955 outb(ring_ptr & 0xff, PIORL(base));
956 outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base));
957
958
959
960 if((addr + len) < (RX_BASE + RX_SIZE))
961 chunk_len = len;
962 else
963 chunk_len = RX_BASE + RX_SIZE - addr;
964 insb(PIOP(base), buf_ptr, chunk_len);
965 buf_ptr += chunk_len;
966 len -= chunk_len;
967 ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE;
968 }
969 return(ring_ptr);
970}
971
972
973
974
975
976
977
978
979
980
981static void
982wv_82593_reconfig(struct net_device * dev)
983{
984 net_local * lp = netdev_priv(dev);
985 struct pcmcia_device * link = lp->link;
986 unsigned long flags;
987
988
989 lp->reconfig_82593 = TRUE;
990
991
992 if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev)))
993 {
994 spin_lock_irqsave(&lp->spinlock, flags);
995 wv_82593_config(dev);
996 spin_unlock_irqrestore(&lp->spinlock, flags);
997 }
998 else
999 {
1000#ifdef DEBUG_IOCTL_INFO
1001 printk(KERN_DEBUG
1002 "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n",
1003 dev->name, dev->state, link->open);
1004#endif
1005 }
1006}
1007
1008
1009
1010
1011
1012
1013
1014#ifdef DEBUG_PSA_SHOW
1015
1016
1017
1018
1019static void
1020wv_psa_show(psa_t * p)
1021{
1022 printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
1023 printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
1024 p->psa_io_base_addr_1,
1025 p->psa_io_base_addr_2,
1026 p->psa_io_base_addr_3,
1027 p->psa_io_base_addr_4);
1028 printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
1029 p->psa_rem_boot_addr_1,
1030 p->psa_rem_boot_addr_2,
1031 p->psa_rem_boot_addr_3);
1032 printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
1033 printk("psa_int_req_no: %d\n", p->psa_int_req_no);
1034#ifdef DEBUG_SHOW_UNUSED
1035 printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
1036#endif
1037 printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
1038 printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
1039 printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
1040 printk("psa_comp_number: %d, ", p->psa_comp_number);
1041 printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
1042 printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
1043 p->psa_feature_select);
1044 printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
1045 printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
1046 printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
1047 printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]);
1048 printk("psa_nwid_select: %d\n", p->psa_nwid_select);
1049 printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select);
1050 printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1051 p->psa_encryption_key[0],
1052 p->psa_encryption_key[1],
1053 p->psa_encryption_key[2],
1054 p->psa_encryption_key[3],
1055 p->psa_encryption_key[4],
1056 p->psa_encryption_key[5],
1057 p->psa_encryption_key[6],
1058 p->psa_encryption_key[7]);
1059 printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
1060 printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
1061 p->psa_call_code[0]);
1062 printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
1063 p->psa_call_code[0],
1064 p->psa_call_code[1],
1065 p->psa_call_code[2],
1066 p->psa_call_code[3],
1067 p->psa_call_code[4],
1068 p->psa_call_code[5],
1069 p->psa_call_code[6],
1070 p->psa_call_code[7]);
1071#ifdef DEBUG_SHOW_UNUSED
1072 printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
1073 p->psa_reserved[0],
1074 p->psa_reserved[1]);
1075#endif
1076 printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
1077 printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
1078 printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
1079}
1080#endif
1081
1082#ifdef DEBUG_MMC_SHOW
1083
1084
1085
1086
1087
1088static void
1089wv_mmc_show(struct net_device * dev)
1090{
1091 unsigned int base = dev->base_addr;
1092 net_local * lp = netdev_priv(dev);
1093 mmr_t m;
1094
1095
1096 if(hasr_read(base) & HASR_NO_CLK)
1097 {
1098 printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n",
1099 dev->name);
1100 return;
1101 }
1102
1103 spin_lock_irqsave(&lp->spinlock, flags);
1104
1105
1106 mmc_out(base, mmwoff(0, mmw_freeze), 1);
1107 mmc_read(base, 0, (u_char *)&m, sizeof(m));
1108 mmc_out(base, mmwoff(0, mmw_freeze), 0);
1109
1110
1111 lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
1112
1113 spin_unlock_irqrestore(&lp->spinlock, flags);
1114
1115 printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
1116#ifdef DEBUG_SHOW_UNUSED
1117 printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
1118 m.mmr_unused0[0],
1119 m.mmr_unused0[1],
1120 m.mmr_unused0[2],
1121 m.mmr_unused0[3],
1122 m.mmr_unused0[4],
1123 m.mmr_unused0[5],
1124 m.mmr_unused0[6],
1125 m.mmr_unused0[7]);
1126#endif
1127 printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
1128 m.mmr_des_avail, m.mmr_des_status);
1129#ifdef DEBUG_SHOW_UNUSED
1130 printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
1131 m.mmr_unused1[0],
1132 m.mmr_unused1[1],
1133 m.mmr_unused1[2],
1134 m.mmr_unused1[3],
1135 m.mmr_unused1[4]);
1136#endif
1137 printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
1138 m.mmr_dce_status,
1139 (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"",
1140 (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
1141 "loop test indicated," : "",
1142 (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "",
1143 (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
1144 "jabber timer expired," : "");
1145 printk(KERN_DEBUG "Dsp ID: %02X\n",
1146 m.mmr_dsp_id);
1147#ifdef DEBUG_SHOW_UNUSED
1148 printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
1149 m.mmr_unused2[0],
1150 m.mmr_unused2[1]);
1151#endif
1152 printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
1153 (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
1154 (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
1155 printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
1156 m.mmr_thr_pre_set & MMR_THR_PRE_SET,
1157 (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below");
1158 printk(KERN_DEBUG "signal_lvl: %d [%s], ",
1159 m.mmr_signal_lvl & MMR_SIGNAL_LVL,
1160 (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg");
1161 printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL,
1162 (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update");
1163 printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
1164 (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0");
1165#ifdef DEBUG_SHOW_UNUSED
1166 printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
1167#endif
1168}
1169#endif
1170
1171#ifdef DEBUG_I82593_SHOW
1172
1173
1174
1175
1176static void
1177wv_ru_show(struct net_device * dev)
1178{
1179 net_local *lp = netdev_priv(dev);
1180
1181 printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####\n");
1182 printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop);
1183
1184
1185
1186 printk("\n");
1187}
1188#endif
1189
1190#ifdef DEBUG_DEVICE_SHOW
1191
1192
1193
1194
1195static void
1196wv_dev_show(struct net_device * dev)
1197{
1198 printk(KERN_DEBUG "dev:");
1199 printk(" state=%lX,", dev->state);
1200 printk(" trans_start=%ld,", dev->trans_start);
1201 printk(" flags=0x%x,", dev->flags);
1202 printk("\n");
1203}
1204
1205
1206
1207
1208
1209
1210static void
1211wv_local_show(struct net_device * dev)
1212{
1213 net_local *lp = netdev_priv(dev);
1214
1215 printk(KERN_DEBUG "local:");
1216
1217
1218
1219 printk("\n");
1220}
1221#endif
1222
1223#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
1224
1225
1226
1227
1228static void
1229wv_packet_info(u_char * p,
1230 int length,
1231 char * msg1,
1232 char * msg2)
1233{
1234 int i;
1235 int maxi;
1236
1237 printk(KERN_DEBUG "%s: %s(): dest %pM, length %d\n",
1238 msg1, msg2, p, length);
1239 printk(KERN_DEBUG "%s: %s(): src %pM, type 0x%02X%02X\n",
1240 msg1, msg2, &p[6], p[12], p[13]);
1241
1242#ifdef DEBUG_PACKET_DUMP
1243
1244 printk(KERN_DEBUG "data=\"");
1245
1246 if((maxi = length) > DEBUG_PACKET_DUMP)
1247 maxi = DEBUG_PACKET_DUMP;
1248 for(i = 14; i < maxi; i++)
1249 if(p[i] >= ' ' && p[i] <= '~')
1250 printk(" %c", p[i]);
1251 else
1252 printk("%02X", p[i]);
1253 if(maxi < length)
1254 printk("..");
1255 printk("\"\n");
1256 printk(KERN_DEBUG "\n");
1257#endif
1258}
1259#endif
1260
1261
1262
1263
1264
1265
1266static void
1267wv_init_info(struct net_device * dev)
1268{
1269 unsigned int base = dev->base_addr;
1270 psa_t psa;
1271
1272
1273 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
1274
1275#ifdef DEBUG_PSA_SHOW
1276 wv_psa_show(&psa);
1277#endif
1278#ifdef DEBUG_MMC_SHOW
1279 wv_mmc_show(dev);
1280#endif
1281#ifdef DEBUG_I82593_SHOW
1282 wv_ru_show(dev);
1283#endif
1284
1285#ifdef DEBUG_BASIC_SHOW
1286
1287 printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr %pM",
1288 dev->name, base, dev->irq, dev->dev_addr);
1289
1290
1291 if(psa.psa_nwid_select)
1292 printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]);
1293 else
1294 printk(", nwid off");
1295
1296
1297 if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
1298 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
1299 {
1300 unsigned short freq;
1301
1302
1303 fee_read(base, 0x00 ,
1304 &freq, 1);
1305
1306
1307 printk(", 2.00, %ld", (freq >> 6) + 2400L);
1308
1309
1310 if(freq & 0x20)
1311 printk(".5");
1312 }
1313 else
1314 {
1315 printk(", PCMCIA, ");
1316 switch (psa.psa_subband)
1317 {
1318 case PSA_SUBBAND_915:
1319 printk("915");
1320 break;
1321 case PSA_SUBBAND_2425:
1322 printk("2425");
1323 break;
1324 case PSA_SUBBAND_2460:
1325 printk("2460");
1326 break;
1327 case PSA_SUBBAND_2484:
1328 printk("2484");
1329 break;
1330 case PSA_SUBBAND_2430_5:
1331 printk("2430.5");
1332 break;
1333 default:
1334 printk("unknown");
1335 }
1336 }
1337
1338 printk(" MHz\n");
1339#endif
1340
1341#ifdef DEBUG_VERSION_SHOW
1342
1343 printk(KERN_NOTICE "%s", version);
1344#endif
1345}
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365static void
1366wavelan_set_multicast_list(struct net_device * dev)
1367{
1368 net_local * lp = netdev_priv(dev);
1369
1370#ifdef DEBUG_IOCTL_TRACE
1371 printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", dev->name);
1372#endif
1373
1374#ifdef DEBUG_IOCTL_INFO
1375 printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
1376 dev->name, dev->flags, dev->mc_count);
1377#endif
1378
1379 if(dev->flags & IFF_PROMISC)
1380 {
1381
1382
1383
1384 if(!lp->promiscuous)
1385 {
1386 lp->promiscuous = 1;
1387 lp->allmulticast = 0;
1388 lp->mc_count = 0;
1389
1390 wv_82593_reconfig(dev);
1391 }
1392 }
1393 else
1394
1395
1396 if((dev->flags & IFF_ALLMULTI) ||
1397 (dev->mc_count > I82593_MAX_MULTICAST_ADDRESSES))
1398 {
1399
1400
1401
1402 if(!lp->allmulticast)
1403 {
1404 lp->promiscuous = 0;
1405 lp->allmulticast = 1;
1406 lp->mc_count = 0;
1407
1408 wv_82593_reconfig(dev);
1409 }
1410 }
1411 else
1412
1413 if(dev->mc_list != (struct dev_mc_list *) NULL)
1414 {
1415
1416
1417
1418
1419#ifdef MULTICAST_AVOID
1420 if(lp->promiscuous || lp->allmulticast ||
1421 (dev->mc_count != lp->mc_count))
1422#endif
1423 {
1424 lp->promiscuous = 0;
1425 lp->allmulticast = 0;
1426 lp->mc_count = dev->mc_count;
1427
1428 wv_82593_reconfig(dev);
1429 }
1430 }
1431 else
1432 {
1433
1434
1435
1436
1437 if(lp->promiscuous || lp->mc_count == 0)
1438 {
1439 lp->promiscuous = 0;
1440 lp->allmulticast = 0;
1441 lp->mc_count = 0;
1442
1443 wv_82593_reconfig(dev);
1444 }
1445 }
1446#ifdef DEBUG_IOCTL_TRACE
1447 printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name);
1448#endif
1449}
1450
1451
1452
1453
1454
1455
1456#ifdef SET_MAC_ADDRESS
1457static int
1458wavelan_set_mac_address(struct net_device * dev,
1459 void * addr)
1460{
1461 struct sockaddr * mac = addr;
1462
1463
1464 memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
1465
1466
1467 wv_82593_reconfig(dev);
1468
1469 return 0;
1470}
1471#endif
1472
1473
1474
1475
1476
1477
1478
1479static int
1480wv_set_frequency(u_long base,
1481 iw_freq * frequency)
1482{
1483 const int BAND_NUM = 10;
1484 long freq = 0L;
1485#ifdef DEBUG_IOCTL_INFO
1486 int i;
1487#endif
1488
1489
1490
1491
1492
1493
1494 if((frequency->e == 1) &&
1495 (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8))
1496 {
1497 freq = ((frequency->m / 10000) - 24000L) / 5;
1498 }
1499
1500
1501
1502
1503 if((frequency->e == 0) &&
1504 (frequency->m >= 0) && (frequency->m < BAND_NUM))
1505 {
1506
1507 freq = channel_bands[frequency->m] >> 1;
1508 }
1509
1510
1511 if(freq != 0L)
1512 {
1513 u_short table[10];
1514
1515
1516 fee_read(base, 0x71 ,
1517 table, 10);
1518
1519#ifdef DEBUG_IOCTL_INFO
1520 printk(KERN_DEBUG "Frequency table :");
1521 for(i = 0; i < 10; i++)
1522 {
1523 printk(" %04X",
1524 table[i]);
1525 }
1526 printk("\n");
1527#endif
1528
1529
1530 if(!(table[9 - ((freq - 24) / 16)] &
1531 (1 << ((freq - 24) % 16))))
1532 return -EINVAL;
1533 }
1534 else
1535 return -EINVAL;
1536
1537
1538 if(freq != 0L)
1539 {
1540 unsigned short area[16];
1541 unsigned short dac[2];
1542 unsigned short area_verify[16];
1543 unsigned short dac_verify[2];
1544
1545
1546
1547 unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
1548 int power_band = 0;
1549 unsigned short power_adjust;
1550
1551
1552 power_band = 0;
1553 while((freq > power_limit[power_band]) &&
1554 (power_limit[++power_band] != 0))
1555 ;
1556
1557
1558 fee_read(base, 0x00,
1559 area, 16);
1560
1561
1562 fee_read(base, 0x60,
1563 dac, 2);
1564
1565
1566 fee_read(base, 0x6B - (power_band >> 1),
1567 &power_adjust, 1);
1568 if(power_band & 0x1)
1569 power_adjust >>= 8;
1570 else
1571 power_adjust &= 0xFF;
1572
1573#ifdef DEBUG_IOCTL_INFO
1574 printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
1575 for(i = 0; i < 16; i++)
1576 {
1577 printk(" %04X",
1578 area[i]);
1579 }
1580 printk("\n");
1581
1582 printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
1583 dac[0], dac[1]);
1584#endif
1585
1586
1587 area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
1588
1589
1590 area[3] = (freq >> 1) + 2400L - 352L;
1591 area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
1592
1593
1594 area[13] = (freq >> 1) + 2400L;
1595 area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
1596
1597
1598
1599
1600 dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
1601 dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
1602
1603
1604 fee_write(base, 0x00,
1605 area, 16);
1606
1607
1608 fee_write(base, 0x60,
1609 dac, 2);
1610
1611
1612
1613
1614 fee_read(base, 0x00,
1615 area_verify, 16);
1616
1617
1618 fee_read(base, 0x60,
1619 dac_verify, 2);
1620
1621
1622 if(memcmp(area, area_verify, 16 * 2) ||
1623 memcmp(dac, dac_verify, 2 * 2))
1624 {
1625#ifdef DEBUG_IOCTL_ERROR
1626 printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (?)\n");
1627#endif
1628 return -EOPNOTSUPP;
1629 }
1630
1631
1632
1633
1634
1635 mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F);
1636 mmc_out(base, mmwoff(0, mmw_fee_ctrl),
1637 MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
1638
1639
1640 fee_wait(base, 100, 100);
1641
1642
1643
1644 mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61);
1645 mmc_out(base, mmwoff(0, mmw_fee_ctrl),
1646 MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
1647
1648
1649 fee_wait(base, 100, 100);
1650
1651#ifdef DEBUG_IOCTL_INFO
1652
1653
1654 printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
1655 for(i = 0; i < 16; i++)
1656 {
1657 printk(" %04X",
1658 area_verify[i]);
1659 }
1660 printk("\n");
1661
1662 printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
1663 dac_verify[0], dac_verify[1]);
1664#endif
1665
1666 return 0;
1667 }
1668 else
1669 return -EINVAL;
1670}
1671
1672
1673
1674
1675
1676static int
1677wv_frequency_list(u_long base,
1678 iw_freq * list,
1679 int max)
1680{
1681 u_short table[10];
1682 long freq = 0L;
1683 int i;
1684 const int BAND_NUM = 10;
1685 int c = 0;
1686
1687
1688 fee_read(base, 0x71 ,
1689 table, 10);
1690
1691
1692 i = 0;
1693 for(freq = 0; freq < 150; freq++)
1694
1695 if(table[9 - (freq / 16)] & (1 << (freq % 16)))
1696 {
1697
1698 while((((channel_bands[c] >> 1) - 24) < freq) &&
1699 (c < BAND_NUM))
1700 c++;
1701 list[i].i = c;
1702
1703
1704 list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
1705 list[i++].e = 1;
1706
1707
1708 if(i >= max)
1709 return(i);
1710 }
1711
1712 return(i);
1713}
1714
1715#ifdef IW_WIRELESS_SPY
1716
1717
1718
1719
1720
1721
1722static inline void
1723wl_spy_gather(struct net_device * dev,
1724 u_char * mac,
1725 u_char * stats)
1726{
1727 struct iw_quality wstats;
1728
1729 wstats.qual = stats[2] & MMR_SGNL_QUAL;
1730 wstats.level = stats[0] & MMR_SIGNAL_LVL;
1731 wstats.noise = stats[1] & MMR_SILENCE_LVL;
1732 wstats.updated = 0x7;
1733
1734
1735 wireless_spy_update(dev, mac, &wstats);
1736}
1737#endif
1738
1739#ifdef HISTOGRAM
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749static inline void
1750wl_his_gather(struct net_device * dev,
1751 u_char * stats)
1752{
1753 net_local * lp = netdev_priv(dev);
1754 u_char level = stats[0] & MMR_SIGNAL_LVL;
1755 int i;
1756
1757
1758 i = 0;
1759 while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++]))
1760 ;
1761
1762
1763 (lp->his_sum[i])++;
1764}
1765#endif
1766
1767static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1768{
1769 strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1);
1770}
1771
1772static const struct ethtool_ops ops = {
1773 .get_drvinfo = wl_get_drvinfo
1774};
1775
1776
1777
1778
1779
1780static int wavelan_get_name(struct net_device *dev,
1781 struct iw_request_info *info,
1782 union iwreq_data *wrqu,
1783 char *extra)
1784{
1785 strcpy(wrqu->name, "WaveLAN");
1786 return 0;
1787}
1788
1789
1790
1791
1792
1793static int wavelan_set_nwid(struct net_device *dev,
1794 struct iw_request_info *info,
1795 union iwreq_data *wrqu,
1796 char *extra)
1797{
1798 unsigned int base = dev->base_addr;
1799 net_local *lp = netdev_priv(dev);
1800 psa_t psa;
1801 mm_t m;
1802 unsigned long flags;
1803 int ret = 0;
1804
1805
1806 spin_lock_irqsave(&lp->spinlock, flags);
1807
1808
1809 if (!wrqu->nwid.disabled) {
1810
1811 psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
1812 psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
1813 psa.psa_nwid_select = 0x01;
1814 psa_write(dev,
1815 (char *) psa.psa_nwid - (char *) &psa,
1816 (unsigned char *) psa.psa_nwid, 3);
1817
1818
1819 m.w.mmw_netw_id_l = psa.psa_nwid[1];
1820 m.w.mmw_netw_id_h = psa.psa_nwid[0];
1821 mmc_write(base,
1822 (char *) &m.w.mmw_netw_id_l -
1823 (char *) &m,
1824 (unsigned char *) &m.w.mmw_netw_id_l, 2);
1825 mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
1826 } else {
1827
1828 psa.psa_nwid_select = 0x00;
1829 psa_write(dev,
1830 (char *) &psa.psa_nwid_select -
1831 (char *) &psa,
1832 (unsigned char *) &psa.psa_nwid_select,
1833 1);
1834
1835
1836 mmc_out(base, mmwoff(0, mmw_loopt_sel),
1837 MMW_LOOPT_SEL_DIS_NWID);
1838 }
1839
1840 update_psa_checksum(dev);
1841
1842
1843 spin_unlock_irqrestore(&lp->spinlock, flags);
1844
1845 return ret;
1846}
1847
1848
1849
1850
1851
1852static int wavelan_get_nwid(struct net_device *dev,
1853 struct iw_request_info *info,
1854 union iwreq_data *wrqu,
1855 char *extra)
1856{
1857 net_local *lp = netdev_priv(dev);
1858 psa_t psa;
1859 unsigned long flags;
1860 int ret = 0;
1861
1862
1863 spin_lock_irqsave(&lp->spinlock, flags);
1864
1865
1866 psa_read(dev,
1867 (char *) psa.psa_nwid - (char *) &psa,
1868 (unsigned char *) psa.psa_nwid, 3);
1869 wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
1870 wrqu->nwid.disabled = !(psa.psa_nwid_select);
1871 wrqu->nwid.fixed = 1;
1872
1873
1874 spin_unlock_irqrestore(&lp->spinlock, flags);
1875
1876 return ret;
1877}
1878
1879
1880
1881
1882
1883static int wavelan_set_freq(struct net_device *dev,
1884 struct iw_request_info *info,
1885 union iwreq_data *wrqu,
1886 char *extra)
1887{
1888 unsigned int base = dev->base_addr;
1889 net_local *lp = netdev_priv(dev);
1890 unsigned long flags;
1891 int ret;
1892
1893
1894 spin_lock_irqsave(&lp->spinlock, flags);
1895
1896
1897 if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
1898 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
1899 ret = wv_set_frequency(base, &(wrqu->freq));
1900 else
1901 ret = -EOPNOTSUPP;
1902
1903
1904 spin_unlock_irqrestore(&lp->spinlock, flags);
1905
1906 return ret;
1907}
1908
1909
1910
1911
1912
1913static int wavelan_get_freq(struct net_device *dev,
1914 struct iw_request_info *info,
1915 union iwreq_data *wrqu,
1916 char *extra)
1917{
1918 unsigned int base = dev->base_addr;
1919 net_local *lp = netdev_priv(dev);
1920 psa_t psa;
1921 unsigned long flags;
1922 int ret = 0;
1923
1924
1925 spin_lock_irqsave(&lp->spinlock, flags);
1926
1927
1928
1929 if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
1930 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
1931 unsigned short freq;
1932
1933
1934 fee_read(base, 0x00, &freq, 1);
1935 wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
1936 wrqu->freq.e = 1;
1937 } else {
1938 psa_read(dev,
1939 (char *) &psa.psa_subband - (char *) &psa,
1940 (unsigned char *) &psa.psa_subband, 1);
1941
1942 if (psa.psa_subband <= 4) {
1943 wrqu->freq.m = fixed_bands[psa.psa_subband];
1944 wrqu->freq.e = (psa.psa_subband != 0);
1945 } else
1946 ret = -EOPNOTSUPP;
1947 }
1948
1949
1950 spin_unlock_irqrestore(&lp->spinlock, flags);
1951
1952 return ret;
1953}
1954
1955
1956
1957
1958
1959static int wavelan_set_sens(struct net_device *dev,
1960 struct iw_request_info *info,
1961 union iwreq_data *wrqu,
1962 char *extra)
1963{
1964 unsigned int base = dev->base_addr;
1965 net_local *lp = netdev_priv(dev);
1966 psa_t psa;
1967 unsigned long flags;
1968 int ret = 0;
1969
1970
1971 spin_lock_irqsave(&lp->spinlock, flags);
1972
1973
1974
1975
1976 psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
1977 psa_write(dev,
1978 (char *) &psa.psa_thr_pre_set - (char *) &psa,
1979 (unsigned char *) &psa.psa_thr_pre_set, 1);
1980
1981 update_psa_checksum(dev);
1982 mmc_out(base, mmwoff(0, mmw_thr_pre_set),
1983 psa.psa_thr_pre_set);
1984
1985
1986 spin_unlock_irqrestore(&lp->spinlock, flags);
1987
1988 return ret;
1989}
1990
1991
1992
1993
1994
1995static int wavelan_get_sens(struct net_device *dev,
1996 struct iw_request_info *info,
1997 union iwreq_data *wrqu,
1998 char *extra)
1999{
2000 net_local *lp = netdev_priv(dev);
2001 psa_t psa;
2002 unsigned long flags;
2003 int ret = 0;
2004
2005
2006 spin_lock_irqsave(&lp->spinlock, flags);
2007
2008
2009 psa_read(dev,
2010 (char *) &psa.psa_thr_pre_set - (char *) &psa,
2011 (unsigned char *) &psa.psa_thr_pre_set, 1);
2012 wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
2013 wrqu->sens.fixed = 1;
2014
2015
2016 spin_unlock_irqrestore(&lp->spinlock, flags);
2017
2018 return ret;
2019}
2020
2021
2022
2023
2024
2025static int wavelan_set_encode(struct net_device *dev,
2026 struct iw_request_info *info,
2027 union iwreq_data *wrqu,
2028 char *extra)
2029{
2030 unsigned int base = dev->base_addr;
2031 net_local *lp = netdev_priv(dev);
2032 unsigned long flags;
2033 psa_t psa;
2034 int ret = 0;
2035
2036
2037 spin_lock_irqsave(&lp->spinlock, flags);
2038
2039
2040 if (!mmc_encr(base)) {
2041 ret = -EOPNOTSUPP;
2042 }
2043
2044
2045 if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
2046 ret = -EINVAL;
2047 }
2048
2049 if(!ret) {
2050
2051 if (wrqu->encoding.length == 8) {
2052
2053 memcpy(psa.psa_encryption_key, extra,
2054 wrqu->encoding.length);
2055 psa.psa_encryption_select = 1;
2056
2057 psa_write(dev,
2058 (char *) &psa.psa_encryption_select -
2059 (char *) &psa,
2060 (unsigned char *) &psa.
2061 psa_encryption_select, 8 + 1);
2062
2063 mmc_out(base, mmwoff(0, mmw_encr_enable),
2064 MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
2065 mmc_write(base, mmwoff(0, mmw_encr_key),
2066 (unsigned char *) &psa.
2067 psa_encryption_key, 8);
2068 }
2069
2070
2071 if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
2072 psa.psa_encryption_select = 0;
2073 psa_write(dev,
2074 (char *) &psa.psa_encryption_select -
2075 (char *) &psa,
2076 (unsigned char *) &psa.
2077 psa_encryption_select, 1);
2078
2079 mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
2080 }
2081
2082 update_psa_checksum(dev);
2083 }
2084
2085
2086 spin_unlock_irqrestore(&lp->spinlock, flags);
2087
2088 return ret;
2089}
2090
2091
2092
2093
2094
2095static int wavelan_get_encode(struct net_device *dev,
2096 struct iw_request_info *info,
2097 union iwreq_data *wrqu,
2098 char *extra)
2099{
2100 unsigned int base = dev->base_addr;
2101 net_local *lp = netdev_priv(dev);
2102 psa_t psa;
2103 unsigned long flags;
2104 int ret = 0;
2105
2106
2107 spin_lock_irqsave(&lp->spinlock, flags);
2108
2109
2110 if (!mmc_encr(base)) {
2111 ret = -EOPNOTSUPP;
2112 } else {
2113
2114 psa_read(dev,
2115 (char *) &psa.psa_encryption_select -
2116 (char *) &psa,
2117 (unsigned char *) &psa.
2118 psa_encryption_select, 1 + 8);
2119
2120
2121 if (psa.psa_encryption_select)
2122 wrqu->encoding.flags = IW_ENCODE_ENABLED;
2123 else
2124 wrqu->encoding.flags = IW_ENCODE_DISABLED;
2125 wrqu->encoding.flags |= mmc_encr(base);
2126
2127
2128 wrqu->encoding.length = 8;
2129 memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
2130 }
2131
2132
2133 spin_unlock_irqrestore(&lp->spinlock, flags);
2134
2135 return ret;
2136}
2137
2138#ifdef WAVELAN_ROAMING_EXT
2139
2140
2141
2142
2143static int wavelan_set_essid(struct net_device *dev,
2144 struct iw_request_info *info,
2145 union iwreq_data *wrqu,
2146 char *extra)
2147{
2148 net_local *lp = netdev_priv(dev);
2149 unsigned long flags;
2150 int ret = 0;
2151
2152
2153 spin_lock_irqsave(&lp->spinlock, flags);
2154
2155
2156 if(wrqu->data.flags == 0)
2157 lp->filter_domains = 0;
2158 else {
2159 char essid[IW_ESSID_MAX_SIZE + 1];
2160 char * endp;
2161
2162
2163 memcpy(essid, extra, wrqu->data.length);
2164 essid[IW_ESSID_MAX_SIZE] = '\0';
2165
2166#ifdef DEBUG_IOCTL_INFO
2167 printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);
2168#endif
2169
2170
2171 lp->domain_id = simple_strtoul(essid, &endp, 16);
2172
2173 if(endp > essid)
2174 lp->filter_domains = 1;
2175 else {
2176 lp->filter_domains = 0;
2177 ret = -EINVAL;
2178 }
2179 }
2180
2181
2182 spin_unlock_irqrestore(&lp->spinlock, flags);
2183
2184 return ret;
2185}
2186
2187
2188
2189
2190
2191static int wavelan_get_essid(struct net_device *dev,
2192 struct iw_request_info *info,
2193 union iwreq_data *wrqu,
2194 char *extra)
2195{
2196 net_local *lp = netdev_priv(dev);
2197
2198
2199 wrqu->data.flags = lp->filter_domains;
2200
2201
2202
2203 sprintf(extra, "%lX", lp->domain_id);
2204 extra[IW_ESSID_MAX_SIZE] = '\0';
2205
2206
2207 wrqu->data.length = strlen(extra);
2208
2209 return 0;
2210}
2211
2212
2213
2214
2215
2216static int wavelan_set_wap(struct net_device *dev,
2217 struct iw_request_info *info,
2218 union iwreq_data *wrqu,
2219 char *extra)
2220{
2221#ifdef DEBUG_IOCTL_INFO
2222 printk(KERN_DEBUG "Set AP to : %pM\n", wrqu->ap_addr.sa_data);
2223#endif
2224
2225 return -EOPNOTSUPP;
2226}
2227
2228
2229
2230
2231
2232static int wavelan_get_wap(struct net_device *dev,
2233 struct iw_request_info *info,
2234 union iwreq_data *wrqu,
2235 char *extra)
2236{
2237
2238 memcpy(wrqu->ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
2239 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
2240
2241 return -EOPNOTSUPP;
2242}
2243#endif
2244
2245#ifdef WAVELAN_ROAMING
2246
2247
2248
2249
2250static int wavelan_set_mode(struct net_device *dev,
2251 struct iw_request_info *info,
2252 union iwreq_data *wrqu,
2253 char *extra)
2254{
2255 net_local *lp = netdev_priv(dev);
2256 unsigned long flags;
2257 int ret = 0;
2258
2259
2260 spin_lock_irqsave(&lp->spinlock, flags);
2261
2262
2263 switch(wrqu->mode) {
2264 case IW_MODE_ADHOC:
2265 if(do_roaming) {
2266 wv_roam_cleanup(dev);
2267 do_roaming = 0;
2268 }
2269 break;
2270 case IW_MODE_INFRA:
2271 if(!do_roaming) {
2272 wv_roam_init(dev);
2273 do_roaming = 1;
2274 }
2275 break;
2276 default:
2277 ret = -EINVAL;
2278 }
2279
2280
2281 spin_unlock_irqrestore(&lp->spinlock, flags);
2282
2283 return ret;
2284}
2285
2286
2287
2288
2289
2290static int wavelan_get_mode(struct net_device *dev,
2291 struct iw_request_info *info,
2292 union iwreq_data *wrqu,
2293 char *extra)
2294{
2295 if(do_roaming)
2296 wrqu->mode = IW_MODE_INFRA;
2297 else
2298 wrqu->mode = IW_MODE_ADHOC;
2299
2300 return 0;
2301}
2302#endif
2303
2304
2305
2306
2307
2308static int wavelan_get_range(struct net_device *dev,
2309 struct iw_request_info *info,
2310 union iwreq_data *wrqu,
2311 char *extra)
2312{
2313 unsigned int base = dev->base_addr;
2314 net_local *lp = netdev_priv(dev);
2315 struct iw_range *range = (struct iw_range *) extra;
2316 unsigned long flags;
2317 int ret = 0;
2318
2319
2320 wrqu->data.length = sizeof(struct iw_range);
2321
2322
2323 memset(range, 0, sizeof(struct iw_range));
2324
2325
2326 range->we_version_compiled = WIRELESS_EXT;
2327 range->we_version_source = 9;
2328
2329
2330 range->throughput = 1.4 * 1000 * 1000;
2331 range->min_nwid = 0x0000;
2332 range->max_nwid = 0xFFFF;
2333
2334 range->sensitivity = 0x3F;
2335 range->max_qual.qual = MMR_SGNL_QUAL;
2336 range->max_qual.level = MMR_SIGNAL_LVL;
2337 range->max_qual.noise = MMR_SILENCE_LVL;
2338 range->avg_qual.qual = MMR_SGNL_QUAL;
2339
2340 range->avg_qual.level = 30;
2341 range->avg_qual.noise = 8;
2342
2343 range->num_bitrates = 1;
2344 range->bitrate[0] = 2000000;
2345
2346
2347 range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
2348 IW_EVENT_CAPA_MASK(0x8B04) |
2349 IW_EVENT_CAPA_MASK(0x8B06));
2350 range->event_capa[1] = IW_EVENT_CAPA_K_1;
2351
2352
2353 spin_lock_irqsave(&lp->spinlock, flags);
2354
2355
2356 if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
2357 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
2358 range->num_channels = 10;
2359 range->num_frequency = wv_frequency_list(base, range->freq,
2360 IW_MAX_FREQUENCIES);
2361 } else
2362 range->num_channels = range->num_frequency = 0;
2363
2364
2365 if (mmc_encr(base)) {
2366 range->encoding_size[0] = 8;
2367 range->num_encoding_sizes = 1;
2368 range->max_encoding_tokens = 1;
2369 } else {
2370 range->num_encoding_sizes = 0;
2371 range->max_encoding_tokens = 0;
2372 }
2373
2374
2375 spin_unlock_irqrestore(&lp->spinlock, flags);
2376
2377 return ret;
2378}
2379
2380
2381
2382
2383
2384static int wavelan_set_qthr(struct net_device *dev,
2385 struct iw_request_info *info,
2386 union iwreq_data *wrqu,
2387 char *extra)
2388{
2389 unsigned int base = dev->base_addr;
2390 net_local *lp = netdev_priv(dev);
2391 psa_t psa;
2392 unsigned long flags;
2393
2394
2395 spin_lock_irqsave(&lp->spinlock, flags);
2396
2397 psa.psa_quality_thr = *(extra) & 0x0F;
2398 psa_write(dev,
2399 (char *) &psa.psa_quality_thr - (char *) &psa,
2400 (unsigned char *) &psa.psa_quality_thr, 1);
2401
2402 update_psa_checksum(dev);
2403 mmc_out(base, mmwoff(0, mmw_quality_thr),
2404 psa.psa_quality_thr);
2405
2406
2407 spin_unlock_irqrestore(&lp->spinlock, flags);
2408
2409 return 0;
2410}
2411
2412
2413
2414
2415
2416static int wavelan_get_qthr(struct net_device *dev,
2417 struct iw_request_info *info,
2418 union iwreq_data *wrqu,
2419 char *extra)
2420{
2421 net_local *lp = netdev_priv(dev);
2422 psa_t psa;
2423 unsigned long flags;
2424
2425
2426 spin_lock_irqsave(&lp->spinlock, flags);
2427
2428 psa_read(dev,
2429 (char *) &psa.psa_quality_thr - (char *) &psa,
2430 (unsigned char *) &psa.psa_quality_thr, 1);
2431 *(extra) = psa.psa_quality_thr & 0x0F;
2432
2433
2434 spin_unlock_irqrestore(&lp->spinlock, flags);
2435
2436 return 0;
2437}
2438
2439#ifdef WAVELAN_ROAMING
2440
2441
2442
2443
2444static int wavelan_set_roam(struct net_device *dev,
2445 struct iw_request_info *info,
2446 union iwreq_data *wrqu,
2447 char *extra)
2448{
2449 net_local *lp = netdev_priv(dev);
2450 unsigned long flags;
2451
2452
2453 spin_lock_irqsave(&lp->spinlock, flags);
2454
2455
2456 if(do_roaming && (*extra)==0)
2457 wv_roam_cleanup(dev);
2458 else if(do_roaming==0 && (*extra)!=0)
2459 wv_roam_init(dev);
2460
2461 do_roaming = (*extra);
2462
2463
2464 spin_unlock_irqrestore(&lp->spinlock, flags);
2465
2466 return 0;
2467}
2468
2469
2470
2471
2472
2473static int wavelan_get_roam(struct net_device *dev,
2474 struct iw_request_info *info,
2475 union iwreq_data *wrqu,
2476 char *extra)
2477{
2478 *(extra) = do_roaming;
2479
2480 return 0;
2481}
2482#endif
2483
2484#ifdef HISTOGRAM
2485
2486
2487
2488
2489static int wavelan_set_histo(struct net_device *dev,
2490 struct iw_request_info *info,
2491 union iwreq_data *wrqu,
2492 char *extra)
2493{
2494 net_local *lp = netdev_priv(dev);
2495
2496
2497 if (wrqu->data.length > 16) {
2498 return(-E2BIG);
2499 }
2500
2501
2502
2503 lp->his_number = 0;
2504
2505
2506 if (wrqu->data.length > 0) {
2507
2508 memcpy(lp->his_range, extra, wrqu->data.length);
2509
2510 {
2511 int i;
2512 printk(KERN_DEBUG "Histo :");
2513 for(i = 0; i < wrqu->data.length; i++)
2514 printk(" %d", lp->his_range[i]);
2515 printk("\n");
2516 }
2517
2518
2519 memset(lp->his_sum, 0x00, sizeof(long) * 16);
2520 }
2521
2522
2523 lp->his_number = wrqu->data.length;
2524
2525 return(0);
2526}
2527
2528
2529
2530
2531
2532static int wavelan_get_histo(struct net_device *dev,
2533 struct iw_request_info *info,
2534 union iwreq_data *wrqu,
2535 char *extra)
2536{
2537 net_local *lp = netdev_priv(dev);
2538
2539
2540 wrqu->data.length = lp->his_number;
2541
2542
2543 if(lp->his_number > 0)
2544 memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
2545
2546 return(0);
2547}
2548#endif
2549
2550
2551
2552
2553
2554
2555static const struct iw_priv_args wavelan_private_args[] = {
2556
2557 { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
2558 { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
2559 { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setroam" },
2560 { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
2561 { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
2562 { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },
2563};
2564
2565static const iw_handler wavelan_handler[] =
2566{
2567 NULL,
2568 wavelan_get_name,
2569 wavelan_set_nwid,
2570 wavelan_get_nwid,
2571 wavelan_set_freq,
2572 wavelan_get_freq,
2573#ifdef WAVELAN_ROAMING
2574 wavelan_set_mode,
2575 wavelan_get_mode,
2576#else
2577 NULL,
2578 NULL,
2579#endif
2580 wavelan_set_sens,
2581 wavelan_get_sens,
2582 NULL,
2583 wavelan_get_range,
2584 NULL,
2585 NULL,
2586 NULL,
2587 NULL,
2588 iw_handler_set_spy,
2589 iw_handler_get_spy,
2590 iw_handler_set_thrspy,
2591 iw_handler_get_thrspy,
2592#ifdef WAVELAN_ROAMING_EXT
2593 wavelan_set_wap,
2594 wavelan_get_wap,
2595 NULL,
2596 NULL,
2597 NULL,
2598 NULL,
2599 wavelan_set_essid,
2600 wavelan_get_essid,
2601#else
2602 NULL,
2603 NULL,
2604 NULL,
2605 NULL,
2606 NULL,
2607 NULL,
2608 NULL,
2609 NULL,
2610#endif
2611 NULL,
2612 NULL,
2613 NULL,
2614 NULL,
2615 NULL,
2616 NULL,
2617 NULL,
2618 NULL,
2619 NULL,
2620 NULL,
2621 NULL,
2622 NULL,
2623 NULL,
2624 NULL,
2625 wavelan_set_encode,
2626 wavelan_get_encode,
2627};
2628
2629static const iw_handler wavelan_private_handler[] =
2630{
2631 wavelan_set_qthr,
2632 wavelan_get_qthr,
2633#ifdef WAVELAN_ROAMING
2634 wavelan_set_roam,
2635 wavelan_get_roam,
2636#else
2637 NULL,
2638 NULL,
2639#endif
2640#ifdef HISTOGRAM
2641 wavelan_set_histo,
2642 wavelan_get_histo,
2643#endif
2644};
2645
2646static const struct iw_handler_def wavelan_handler_def =
2647{
2648 .num_standard = ARRAY_SIZE(wavelan_handler),
2649 .num_private = ARRAY_SIZE(wavelan_private_handler),
2650 .num_private_args = ARRAY_SIZE(wavelan_private_args),
2651 .standard = wavelan_handler,
2652 .private = wavelan_private_handler,
2653 .private_args = wavelan_private_args,
2654 .get_wireless_stats = wavelan_get_wireless_stats,
2655};
2656
2657
2658
2659
2660
2661
2662static iw_stats *
2663wavelan_get_wireless_stats(struct net_device * dev)
2664{
2665 unsigned int base = dev->base_addr;
2666 net_local * lp = netdev_priv(dev);
2667 mmr_t m;
2668 iw_stats * wstats;
2669 unsigned long flags;
2670
2671#ifdef DEBUG_IOCTL_TRACE
2672 printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name);
2673#endif
2674
2675
2676 spin_lock_irqsave(&lp->spinlock, flags);
2677
2678 wstats = &lp->wstats;
2679
2680
2681 mmc_out(base, mmwoff(0, mmw_freeze), 1);
2682
2683 mmc_read(base, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
2684 mmc_read(base, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, 2);
2685 mmc_read(base, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, 4);
2686
2687 mmc_out(base, mmwoff(0, mmw_freeze), 0);
2688
2689
2690 wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
2691 wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
2692 wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
2693 wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
2694 wstats->qual.updated = (((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) |
2695 ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) |
2696 ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
2697 wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
2698 wstats->discard.code = 0L;
2699 wstats->discard.misc = 0L;
2700
2701
2702 spin_unlock_irqrestore(&lp->spinlock, flags);
2703
2704#ifdef DEBUG_IOCTL_TRACE
2705 printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name);
2706#endif
2707 return &lp->wstats;
2708}
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723static int
2724wv_start_of_frame(struct net_device * dev,
2725 int rfp,
2726 int wrap)
2727{
2728 unsigned int base = dev->base_addr;
2729 int rp;
2730 int len;
2731
2732 rp = (rfp - 5 + RX_SIZE) % RX_SIZE;
2733 outb(rp & 0xff, PIORL(base));
2734 outb(((rp >> 8) & PIORH_MASK), PIORH(base));
2735 len = inb(PIOP(base));
2736 len |= inb(PIOP(base)) << 8;
2737
2738
2739
2740 if(len > MAXDATAZ + 100)
2741 {
2742#ifdef DEBUG_RX_ERROR
2743 printk(KERN_INFO "%s: wv_start_of_frame: Received frame too large, rfp %d len 0x%x\n",
2744 dev->name, rfp, len);
2745#endif
2746 return(-1);
2747 }
2748
2749
2750 if(len < 7)
2751 {
2752#ifdef DEBUG_RX_ERROR
2753 printk(KERN_INFO "%s: wv_start_of_frame: Received null frame, rfp %d len 0x%x\n",
2754 dev->name, rfp, len);
2755#endif
2756 return(-1);
2757 }
2758
2759
2760 if(len > ((wrap - (rfp - len) + RX_SIZE) % RX_SIZE))
2761 {
2762#ifdef DEBUG_RX_ERROR
2763 printk(KERN_INFO "%s: wv_start_of_frame: wrap around buffer, wrap %d rfp %d len 0x%x\n",
2764 dev->name, wrap, rfp, len);
2765#endif
2766 return(-1);
2767 }
2768
2769 return((rp - len + RX_SIZE) % RX_SIZE);
2770}
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785static void
2786wv_packet_read(struct net_device * dev,
2787 int fd_p,
2788 int sksize)
2789{
2790 net_local * lp = netdev_priv(dev);
2791 struct sk_buff * skb;
2792
2793#ifdef DEBUG_RX_TRACE
2794 printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
2795 dev->name, fd_p, sksize);
2796#endif
2797
2798
2799 if((skb = dev_alloc_skb(sksize+2)) == (struct sk_buff *) NULL)
2800 {
2801#ifdef DEBUG_RX_ERROR
2802 printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
2803 dev->name, sksize);
2804#endif
2805 dev->stats.rx_dropped++;
2806
2807
2808
2809
2810 return;
2811 }
2812
2813 skb_reserve(skb, 2);
2814 fd_p = read_ringbuf(dev, fd_p, (char *) skb_put(skb, sksize), sksize);
2815 skb->protocol = eth_type_trans(skb, dev);
2816
2817#ifdef DEBUG_RX_INFO
2818 wv_packet_info(skb_mac_header(skb), sksize, dev->name, "wv_packet_read");
2819#endif
2820
2821
2822
2823 if(
2824#ifdef IW_WIRELESS_SPY
2825 (lp->spy_data.spy_number > 0) ||
2826#endif
2827#ifdef HISTOGRAM
2828 (lp->his_number > 0) ||
2829#endif
2830#ifdef WAVELAN_ROAMING
2831 (do_roaming) ||
2832#endif
2833 0)
2834 {
2835 u_char stats[3];
2836
2837
2838 fd_p = read_ringbuf(dev, (fd_p + 4) % RX_SIZE + RX_BASE,
2839 stats, 3);
2840#ifdef DEBUG_RX_INFO
2841 printk(KERN_DEBUG "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
2842 dev->name, stats[0] & 0x3F, stats[1] & 0x3F, stats[2] & 0x0F);
2843#endif
2844
2845#ifdef WAVELAN_ROAMING
2846 if(do_roaming)
2847 if(WAVELAN_BEACON(skb->data))
2848 wl_roam_gather(dev, skb->data, stats);
2849#endif
2850
2851#ifdef WIRELESS_SPY
2852 wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE, stats);
2853#endif
2854#ifdef HISTOGRAM
2855 wl_his_gather(dev, stats);
2856#endif
2857 }
2858
2859
2860
2861
2862 netif_rx(skb);
2863
2864
2865 dev->stats.rx_packets++;
2866 dev->stats.rx_bytes += sksize;
2867
2868#ifdef DEBUG_RX_TRACE
2869 printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
2870#endif
2871 return;
2872}
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885static void
2886wv_packet_rcv(struct net_device * dev)
2887{
2888 unsigned int base = dev->base_addr;
2889 net_local * lp = netdev_priv(dev);
2890 int newrfp;
2891 int rp;
2892 int len;
2893 int f_start;
2894 int status;
2895 int i593_rfp;
2896 int stat_ptr;
2897 u_char c[4];
2898
2899#ifdef DEBUG_RX_TRACE
2900 printk(KERN_DEBUG "%s: ->wv_packet_rcv()\n", dev->name);
2901#endif
2902
2903
2904 outb(CR0_STATUS_2 | OP0_NOP, LCCR(base));
2905 i593_rfp = inb(LCSR(base));
2906 i593_rfp |= inb(LCSR(base)) << 8;
2907 i593_rfp %= RX_SIZE;
2908
2909
2910
2911
2912
2913
2914 newrfp = inb(RPLL(base));
2915 newrfp |= inb(RPLH(base)) << 8;
2916 newrfp %= RX_SIZE;
2917
2918#ifdef DEBUG_RX_INFO
2919 printk(KERN_DEBUG "%s: wv_packet_rcv(): i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
2920 dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
2921#endif
2922
2923#ifdef DEBUG_RX_ERROR
2924
2925 if(lp->overrunning || newrfp == lp->rfp)
2926 printk(KERN_INFO "%s: wv_packet_rcv(): no new frame: i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
2927 dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
2928#endif
2929
2930
2931 while(newrfp != lp->rfp)
2932 {
2933
2934
2935
2936
2937
2938
2939 rp = newrfp;
2940 while(((f_start = wv_start_of_frame(dev, rp, newrfp)) != lp->rfp) &&
2941 (f_start != -1))
2942 rp = f_start;
2943
2944
2945 if(f_start == -1)
2946 {
2947#ifdef DEBUG_RX_ERROR
2948 printk(KERN_INFO "wavelan_cs: cannot find start of frame ");
2949 printk(" i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
2950 i593_rfp, lp->stop, newrfp, lp->rfp);
2951#endif
2952 lp->rfp = rp;
2953 continue;
2954 }
2955
2956
2957
2958
2959
2960 stat_ptr = (rp - 7 + RX_SIZE) % RX_SIZE;
2961 stat_ptr = read_ringbuf(dev, stat_ptr, c, 4);
2962 status = c[0] | (c[1] << 8);
2963 len = c[2] | (c[3] << 8);
2964
2965
2966 if((status & RX_RCV_OK) != RX_RCV_OK)
2967 {
2968 dev->stats.rx_errors++;
2969 if(status & RX_NO_SFD)
2970 dev->stats.rx_frame_errors++;
2971 if(status & RX_CRC_ERR)
2972 dev->stats.rx_crc_errors++;
2973 if(status & RX_OVRRUN)
2974 dev->stats.rx_over_errors++;
2975
2976#ifdef DEBUG_RX_FAIL
2977 printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
2978 dev->name, status);
2979#endif
2980 }
2981 else
2982
2983 wv_packet_read(dev, f_start, len - 2);
2984
2985
2986 lp->rfp = rp;
2987 }
2988
2989
2990
2991
2992
2993
2994 lp->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
2995 outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
2996 outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
2997 outb(OP1_SWIT_TO_PORT_0, LCCR(base));
2998
2999#ifdef DEBUG_RX_TRACE
3000 printk(KERN_DEBUG "%s: <-wv_packet_rcv()\n", dev->name);
3001#endif
3002}
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019static void
3020wv_packet_write(struct net_device * dev,
3021 void * buf,
3022 short length)
3023{
3024 net_local * lp = netdev_priv(dev);
3025 unsigned int base = dev->base_addr;
3026 unsigned long flags;
3027 int clen = length;
3028 register u_short xmtdata_base = TX_BASE;
3029
3030#ifdef DEBUG_TX_TRACE
3031 printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length);
3032#endif
3033
3034 spin_lock_irqsave(&lp->spinlock, flags);
3035
3036
3037 outb(xmtdata_base & 0xff, PIORL(base));
3038 outb(((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3039 outb(clen & 0xff, PIOP(base));
3040 outb(clen >> 8, PIOP(base));
3041
3042
3043 outsb(PIOP(base), buf, clen);
3044
3045
3046 outb(OP0_NOP, PIOP(base));
3047
3048 outb(OP0_NOP, PIOP(base));
3049
3050
3051 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3052 hacr_write(base, HACR_DEFAULT);
3053
3054 wv_82593_cmd(dev, "wv_packet_write(): transmit",
3055 OP0_TRANSMIT, SR0_NO_RESULT);
3056
3057
3058 dev->trans_start = jiffies;
3059
3060
3061 dev->stats.tx_bytes += length;
3062
3063 spin_unlock_irqrestore(&lp->spinlock, flags);
3064
3065#ifdef DEBUG_TX_INFO
3066 wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write");
3067#endif
3068
3069#ifdef DEBUG_TX_TRACE
3070 printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
3071#endif
3072}
3073
3074
3075
3076
3077
3078
3079
3080
3081static int
3082wavelan_packet_xmit(struct sk_buff * skb,
3083 struct net_device * dev)
3084{
3085 net_local * lp = netdev_priv(dev);
3086 unsigned long flags;
3087
3088#ifdef DEBUG_TX_TRACE
3089 printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
3090 (unsigned) skb);
3091#endif
3092
3093
3094
3095
3096
3097 netif_stop_queue(dev);
3098
3099
3100
3101 if(lp->reconfig_82593)
3102 {
3103 spin_lock_irqsave(&lp->spinlock, flags);
3104 wv_82593_config(dev);
3105 spin_unlock_irqrestore(&lp->spinlock, flags);
3106
3107
3108 }
3109
3110#ifdef DEBUG_TX_ERROR
3111 if (skb->next)
3112 printk(KERN_INFO "skb has next\n");
3113#endif
3114
3115
3116
3117
3118
3119
3120 if (skb_padto(skb, ETH_ZLEN))
3121 return 0;
3122
3123 wv_packet_write(dev, skb->data, skb->len);
3124
3125 dev_kfree_skb(skb);
3126
3127#ifdef DEBUG_TX_TRACE
3128 printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
3129#endif
3130 return(0);
3131}
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143static int
3144wv_mmc_init(struct net_device * dev)
3145{
3146 unsigned int base = dev->base_addr;
3147 psa_t psa;
3148 mmw_t m;
3149 int configured;
3150 int i;
3151
3152#ifdef DEBUG_CONFIG_TRACE
3153 printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
3154#endif
3155
3156
3157 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
3158
3159
3160
3161
3162
3163
3164
3165 for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
3166 if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
3167 (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
3168 (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
3169 break;
3170
3171
3172 if (i == ARRAY_SIZE(MAC_ADDRESSES))
3173 {
3174#ifdef DEBUG_CONFIG_ERRORS
3175 printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
3176 dev->name, psa.psa_univ_mac_addr[0],
3177 psa.psa_univ_mac_addr[1], psa.psa_univ_mac_addr[2]);
3178#endif
3179 return FALSE;
3180 }
3181
3182
3183 memcpy(&dev->dev_addr[0], &psa.psa_univ_mac_addr[0], WAVELAN_ADDR_SIZE);
3184
3185#ifdef USE_PSA_CONFIG
3186 configured = psa.psa_conf_status & 1;
3187#else
3188 configured = 0;
3189#endif
3190
3191
3192 if(!configured)
3193 {
3194
3195 psa.psa_nwid[0] = 0;
3196 psa.psa_nwid[1] = 0;
3197
3198
3199 psa.psa_nwid_select = 0;
3200
3201
3202 psa.psa_encryption_select = 0;
3203
3204
3205
3206
3207
3208
3209 if (psa.psa_comp_number & 1)
3210 psa.psa_thr_pre_set = 0x01;
3211 else
3212 psa.psa_thr_pre_set = 0x04;
3213 psa.psa_quality_thr = 0x03;
3214
3215
3216 psa.psa_conf_status |= 1;
3217
3218#ifdef USE_PSA_CONFIG
3219
3220 psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,
3221 (unsigned char *)psa.psa_nwid, 4);
3222 psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
3223 (unsigned char *)&psa.psa_thr_pre_set, 1);
3224 psa_write(dev, (char *)&psa.psa_quality_thr - (char *)&psa,
3225 (unsigned char *)&psa.psa_quality_thr, 1);
3226 psa_write(dev, (char *)&psa.psa_conf_status - (char *)&psa,
3227 (unsigned char *)&psa.psa_conf_status, 1);
3228
3229 update_psa_checksum(dev);
3230#endif
3231 }
3232
3233
3234 memset(&m, 0x00, sizeof(m));
3235
3236
3237 m.mmw_netw_id_l = psa.psa_nwid[1];
3238 m.mmw_netw_id_h = psa.psa_nwid[0];
3239
3240 if(psa.psa_nwid_select & 1)
3241 m.mmw_loopt_sel = 0x00;
3242 else
3243 m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
3244
3245 memcpy(&m.mmw_encr_key, &psa.psa_encryption_key,
3246 sizeof(m.mmw_encr_key));
3247
3248 if(psa.psa_encryption_select)
3249 m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
3250 else
3251 m.mmw_encr_enable = 0;
3252
3253 m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
3254 m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
3255
3256
3257
3258
3259
3260 m.mmw_jabber_enable = 0x01;
3261 m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
3262 m.mmw_ifs = 0x20;
3263 m.mmw_mod_delay = 0x04;
3264 m.mmw_jam_time = 0x38;
3265
3266 m.mmw_des_io_invert = 0;
3267 m.mmw_freeze = 0;
3268 m.mmw_decay_prm = 0;
3269 m.mmw_decay_updat_prm = 0;
3270
3271
3272 mmc_write(base, 0, (u_char *)&m, sizeof(m));
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288 if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
3289 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
3290 {
3291
3292
3293
3294
3295 m.mmw_fee_addr = 0x0F;
3296 m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
3297 mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
3298 (unsigned char *)&m.mmw_fee_ctrl, 2);
3299
3300
3301 fee_wait(base, 100, 100);
3302
3303#ifdef DEBUG_CONFIG_INFO
3304
3305 mmc_read(base, (char *)&m.mmw_fee_data_l - (char *)&m,
3306 (unsigned char *)&m.mmw_fee_data_l, 2);
3307
3308
3309 printk(KERN_DEBUG "%s: Wavelan 2.00 recognised (frequency select) : Current frequency = %ld\n",
3310 dev->name,
3311 ((m.mmw_fee_data_h << 4) |
3312 (m.mmw_fee_data_l >> 4)) * 5 / 2 + 24000L);
3313#endif
3314
3315
3316
3317 m.mmw_fee_addr = 0x61;
3318 m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
3319 mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
3320 (unsigned char *)&m.mmw_fee_ctrl, 2);
3321
3322
3323 }
3324
3325#ifdef DEBUG_CONFIG_TRACE
3326 printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
3327#endif
3328 return TRUE;
3329}
3330
3331
3332
3333
3334
3335
3336
3337static int
3338wv_ru_stop(struct net_device * dev)
3339{
3340 unsigned int base = dev->base_addr;
3341 net_local * lp = netdev_priv(dev);
3342 unsigned long flags;
3343 int status;
3344 int spin;
3345
3346#ifdef DEBUG_CONFIG_TRACE
3347 printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name);
3348#endif
3349
3350 spin_lock_irqsave(&lp->spinlock, flags);
3351
3352
3353 wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv",
3354 OP0_STOP_RCV, SR0_NO_RESULT);
3355
3356
3357 spin = 300;
3358 do
3359 {
3360 udelay(10);
3361 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
3362 status = inb(LCSR(base));
3363 }
3364 while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0));
3365
3366
3367 do
3368 {
3369 udelay(10);
3370 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
3371 status = inb(LCSR(base));
3372 }
3373 while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
3374
3375 spin_unlock_irqrestore(&lp->spinlock, flags);
3376
3377
3378 if(spin <= 0)
3379 {
3380#ifdef DEBUG_CONFIG_ERRORS
3381 printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
3382 dev->name);
3383#endif
3384 return FALSE;
3385 }
3386
3387#ifdef DEBUG_CONFIG_TRACE
3388 printk(KERN_DEBUG "%s: <-wv_ru_stop()\n", dev->name);
3389#endif
3390 return TRUE;
3391}
3392
3393
3394
3395
3396
3397
3398
3399
3400static int
3401wv_ru_start(struct net_device * dev)
3402{
3403 unsigned int base = dev->base_addr;
3404 net_local * lp = netdev_priv(dev);
3405 unsigned long flags;
3406
3407#ifdef DEBUG_CONFIG_TRACE
3408 printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
3409#endif
3410
3411
3412
3413
3414
3415
3416 if(!wv_ru_stop(dev))
3417 return FALSE;
3418
3419 spin_lock_irqsave(&lp->spinlock, flags);
3420
3421
3422
3423
3424 lp->rfp = 0;
3425 outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
3426
3427
3428 outb(OP1_RESET_RING_MNGMT, LCCR(base));
3429
3430#if 0
3431
3432
3433
3434#elif 0
3435
3436 lp->stop = 0;
3437#else
3438
3439 lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
3440#endif
3441 outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
3442 outb(OP1_INT_ENABLE, LCCR(base));
3443 outb(OP1_SWIT_TO_PORT_0, LCCR(base));
3444
3445
3446 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3447 hacr_write_slow(base, HACR_DEFAULT);
3448
3449
3450 wv_82593_cmd(dev, "wv_ru_start(): rcv-enable",
3451 CR0_CHNL | OP0_RCV_ENABLE, SR0_NO_RESULT);
3452
3453#ifdef DEBUG_I82593_SHOW
3454 {
3455 int status;
3456 int opri;
3457 int spin = 10000;
3458
3459
3460 do
3461 {
3462 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
3463 status = inb(LCSR(base));
3464 if(spin-- <= 0)
3465 break;
3466 }
3467 while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) &&
3468 ((status & SR3_RCV_STATE_MASK) != SR3_RCV_READY));
3469 printk(KERN_DEBUG "rcv status is 0x%x [i:%d]\n",
3470 (status & SR3_RCV_STATE_MASK), i);
3471 }
3472#endif
3473
3474 spin_unlock_irqrestore(&lp->spinlock, flags);
3475
3476#ifdef DEBUG_CONFIG_TRACE
3477 printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
3478#endif
3479 return TRUE;
3480}
3481
3482
3483
3484
3485
3486
3487
3488static int
3489wv_82593_config(struct net_device * dev)
3490{
3491 unsigned int base = dev->base_addr;
3492 net_local * lp = netdev_priv(dev);
3493 struct i82593_conf_block cfblk;
3494 int ret = TRUE;
3495
3496#ifdef DEBUG_CONFIG_TRACE
3497 printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name);
3498#endif
3499
3500
3501
3502
3503
3504 memset(&cfblk, 0x00, sizeof(struct i82593_conf_block));
3505 cfblk.d6mod = FALSE;
3506 cfblk.fifo_limit = 5;
3507 cfblk.forgnesi = FALSE;
3508 cfblk.fifo_32 = 1;
3509 cfblk.throttle_enb = FALSE;
3510 cfblk.contin = TRUE;
3511 cfblk.cntrxint = FALSE;
3512 cfblk.addr_len = WAVELAN_ADDR_SIZE;
3513 cfblk.acloc = TRUE;
3514 cfblk.preamb_len = 0;
3515 cfblk.loopback = FALSE;
3516 cfblk.lin_prio = 0;
3517 cfblk.exp_prio = 5;
3518 cfblk.bof_met = 1;
3519 cfblk.ifrm_spc = 0x20 >> 4;
3520 cfblk.slottim_low = 0x20 >> 5;
3521 cfblk.slottim_hi = 0x0;
3522 cfblk.max_retr = 15;
3523 cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE);
3524 cfblk.bc_dis = FALSE;
3525 cfblk.crs_1 = TRUE;
3526 cfblk.nocrc_ins = FALSE;
3527 cfblk.crc_1632 = FALSE;
3528 cfblk.crs_cdt = FALSE;
3529 cfblk.cs_filter = 0;
3530 cfblk.crs_src = FALSE;
3531 cfblk.cd_filter = 0;
3532 cfblk.min_fr_len = ETH_ZLEN >> 2;
3533 cfblk.lng_typ = FALSE;
3534 cfblk.lng_fld = TRUE;
3535 cfblk.rxcrc_xf = TRUE;
3536 cfblk.artx = TRUE;
3537 cfblk.sarec = TRUE;
3538 cfblk.tx_jabber = TRUE;
3539 cfblk.hash_1 = FALSE;
3540 cfblk.lbpkpol = TRUE;
3541 cfblk.fdx = FALSE;
3542 cfblk.dummy_6 = 0x3f;
3543 cfblk.mult_ia = FALSE;
3544 cfblk.dis_bof = FALSE;
3545 cfblk.dummy_1 = TRUE;
3546 cfblk.tx_ifs_retrig = 3;
3547#ifdef MULTICAST_ALL
3548 cfblk.mc_all = (lp->allmulticast ? TRUE: FALSE);
3549#else
3550 cfblk.mc_all = FALSE;
3551#endif
3552 cfblk.rcv_mon = 0;
3553 cfblk.frag_acpt = TRUE;
3554 cfblk.tstrttrs = FALSE;
3555 cfblk.fretx = TRUE;
3556 cfblk.syncrqs = FALSE;
3557 cfblk.sttlen = TRUE;
3558 cfblk.rx_eop = TRUE;
3559 cfblk.tx_eop = TRUE;
3560 cfblk.rbuf_size = RX_SIZE>>11;
3561 cfblk.rcvstop = TRUE;
3562
3563#ifdef DEBUG_I82593_SHOW
3564 {
3565 u_char *c = (u_char *) &cfblk;
3566 int i;
3567 printk(KERN_DEBUG "wavelan_cs: config block:");
3568 for(i = 0; i < sizeof(struct i82593_conf_block); i++,c++)
3569 {
3570 if((i % 16) == 0) printk("\n" KERN_DEBUG);
3571 printk("%02x ", *c);
3572 }
3573 printk("\n");
3574 }
3575#endif
3576
3577
3578 outb(TX_BASE & 0xff, PIORL(base));
3579 outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3580 outb(sizeof(struct i82593_conf_block) & 0xff, PIOP(base));
3581 outb(sizeof(struct i82593_conf_block) >> 8, PIOP(base));
3582 outsb(PIOP(base), (char *) &cfblk, sizeof(struct i82593_conf_block));
3583
3584
3585 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3586 hacr_write(base, HACR_DEFAULT);
3587 if(!wv_82593_cmd(dev, "wv_82593_config(): configure",
3588 OP0_CONFIGURE, SR0_CONFIGURE_DONE))
3589 ret = FALSE;
3590
3591
3592 outb(TX_BASE & 0xff, PIORL(base));
3593 outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3594 outb(WAVELAN_ADDR_SIZE, PIOP(base));
3595 outb(0, PIOP(base));
3596 outsb(PIOP(base), &dev->dev_addr[0], WAVELAN_ADDR_SIZE);
3597
3598
3599 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3600 hacr_write(base, HACR_DEFAULT);
3601 if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup",
3602 OP0_IA_SETUP, SR0_IA_SETUP_DONE))
3603 ret = FALSE;
3604
3605#ifdef WAVELAN_ROAMING
3606
3607
3608 if(do_roaming)
3609 dev_mc_add(dev,WAVELAN_BEACON_ADDRESS, WAVELAN_ADDR_SIZE, 1);
3610#endif
3611
3612
3613 if(lp->mc_count)
3614 {
3615 struct dev_mc_list * dmi;
3616 int addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
3617
3618#ifdef DEBUG_CONFIG_INFO
3619 printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
3620 dev->name, lp->mc_count);
3621 for(dmi=dev->mc_list; dmi; dmi=dmi->next)
3622 printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
3623#endif
3624
3625
3626 outb(TX_BASE & 0xff, PIORL(base));
3627 outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3628 outb(addrs_len & 0xff, PIOP(base));
3629 outb((addrs_len >> 8), PIOP(base));
3630 for(dmi=dev->mc_list; dmi; dmi=dmi->next)
3631 outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen);
3632
3633
3634 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3635 hacr_write(base, HACR_DEFAULT);
3636 if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup",
3637 OP0_MC_SETUP, SR0_MC_SETUP_DONE))
3638 ret = FALSE;
3639 lp->mc_count = dev->mc_count;
3640 }
3641
3642
3643 lp->reconfig_82593 = FALSE;
3644
3645#ifdef DEBUG_CONFIG_TRACE
3646 printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name);
3647#endif
3648 return(ret);
3649}
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660static int
3661wv_pcmcia_reset(struct net_device * dev)
3662{
3663 int i;
3664 conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 };
3665 struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link;
3666
3667#ifdef DEBUG_CONFIG_TRACE
3668 printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name);
3669#endif
3670
3671 i = pcmcia_access_configuration_register(link, ®);
3672 if (i != 0)
3673 {
3674 cs_error(link, AccessConfigurationRegister, i);
3675 return FALSE;
3676 }
3677
3678#ifdef DEBUG_CONFIG_INFO
3679 printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
3680 dev->name, (u_int) reg.Value);
3681#endif
3682
3683 reg.Action = CS_WRITE;
3684 reg.Value = reg.Value | COR_SW_RESET;
3685 i = pcmcia_access_configuration_register(link, ®);
3686 if (i != 0)
3687 {
3688 cs_error(link, AccessConfigurationRegister, i);
3689 return FALSE;
3690 }
3691
3692 reg.Action = CS_WRITE;
3693 reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
3694 i = pcmcia_access_configuration_register(link, ®);
3695 if (i != 0)
3696 {
3697 cs_error(link, AccessConfigurationRegister, i);
3698 return FALSE;
3699 }
3700
3701#ifdef DEBUG_CONFIG_TRACE
3702 printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
3703#endif
3704 return TRUE;
3705}
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722static int
3723wv_hw_config(struct net_device * dev)
3724{
3725 net_local * lp = netdev_priv(dev);
3726 unsigned int base = dev->base_addr;
3727 unsigned long flags;
3728 int ret = FALSE;
3729
3730#ifdef DEBUG_CONFIG_TRACE
3731 printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
3732#endif
3733
3734
3735 BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
3736 BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
3737 BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
3738
3739
3740 if(wv_pcmcia_reset(dev) == FALSE)
3741 return FALSE;
3742
3743
3744 spin_lock_irqsave(&lp->spinlock, flags);
3745
3746
3747 do
3748 {
3749
3750
3751 hacr_write_slow(base, HACR_RESET);
3752 hacr_write(base, HACR_DEFAULT);
3753
3754
3755 if(hasr_read(base) & HASR_NO_CLK)
3756 {
3757#ifdef DEBUG_CONFIG_ERRORS
3758 printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n",
3759 dev->name);
3760#endif
3761 break;
3762 }
3763
3764
3765 if(wv_mmc_init(dev) == FALSE)
3766 {
3767#ifdef DEBUG_CONFIG_ERRORS
3768 printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n",
3769 dev->name);
3770#endif
3771 break;
3772 }
3773
3774
3775 outb(OP0_RESET, LCCR(base));
3776 mdelay(1);
3777
3778
3779 if(wv_82593_config(dev) == FALSE)
3780 {
3781#ifdef DEBUG_CONFIG_ERRORS
3782 printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n",
3783 dev->name);
3784#endif
3785 break;
3786 }
3787
3788
3789 if(wv_diag(dev) == FALSE)
3790 {
3791#ifdef DEBUG_CONFIG_ERRORS
3792 printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n",
3793 dev->name);
3794#endif
3795 break;
3796 }
3797
3798
3799
3800
3801
3802
3803 lp->configured = 1;
3804 ret = TRUE;
3805 }
3806 while(0);
3807
3808
3809 spin_unlock_irqrestore(&lp->spinlock, flags);
3810
3811#ifdef DEBUG_CONFIG_TRACE
3812 printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name);
3813#endif
3814 return(ret);
3815}
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825static void
3826wv_hw_reset(struct net_device * dev)
3827{
3828 net_local * lp = netdev_priv(dev);
3829
3830#ifdef DEBUG_CONFIG_TRACE
3831 printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name);
3832#endif
3833
3834 lp->nresets++;
3835 lp->configured = 0;
3836
3837
3838 if(wv_hw_config(dev) == FALSE)
3839 return;
3840
3841
3842 wv_ru_start(dev);
3843
3844#ifdef DEBUG_CONFIG_TRACE
3845 printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
3846#endif
3847}
3848
3849
3850
3851
3852
3853
3854
3855
3856static int
3857wv_pcmcia_config(struct pcmcia_device * link)
3858{
3859 struct net_device * dev = (struct net_device *) link->priv;
3860 int i;
3861 win_req_t req;
3862 memreq_t mem;
3863 net_local * lp = netdev_priv(dev);
3864
3865
3866#ifdef DEBUG_CONFIG_TRACE
3867 printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
3868#endif
3869
3870 do
3871 {
3872 i = pcmcia_request_io(link, &link->io);
3873 if (i != 0)
3874 {
3875 cs_error(link, RequestIO, i);
3876 break;
3877 }
3878
3879
3880
3881
3882
3883 i = pcmcia_request_irq(link, &link->irq);
3884 if (i != 0)
3885 {
3886 cs_error(link, RequestIRQ, i);
3887 break;
3888 }
3889
3890
3891
3892
3893
3894 link->conf.ConfigIndex = 1;
3895 i = pcmcia_request_configuration(link, &link->conf);
3896 if (i != 0)
3897 {
3898 cs_error(link, RequestConfiguration, i);
3899 break;
3900 }
3901
3902
3903
3904
3905
3906
3907
3908 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
3909 req.Base = req.Size = 0;
3910 req.AccessSpeed = mem_speed;
3911 i = pcmcia_request_window(&link, &req, &link->win);
3912 if (i != 0)
3913 {
3914 cs_error(link, RequestWindow, i);
3915 break;
3916 }
3917
3918 lp->mem = ioremap(req.Base, req.Size);
3919 dev->mem_start = (u_long)lp->mem;
3920 dev->mem_end = dev->mem_start + req.Size;
3921
3922 mem.CardOffset = 0; mem.Page = 0;
3923 i = pcmcia_map_mem_page(link->win, &mem);
3924 if (i != 0)
3925 {
3926 cs_error(link, MapMemPage, i);
3927 break;
3928 }
3929
3930
3931 dev->irq = link->irq.AssignedIRQ;
3932 dev->base_addr = link->io.BasePort1;
3933 netif_start_queue(dev);
3934
3935#ifdef DEBUG_CONFIG_INFO
3936 printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n",
3937 lp->mem, dev->irq, (u_int) dev->base_addr);
3938#endif
3939
3940 SET_NETDEV_DEV(dev, &handle_to_dev(link));
3941 i = register_netdev(dev);
3942 if(i != 0)
3943 {
3944#ifdef DEBUG_CONFIG_ERRORS
3945 printk(KERN_INFO "wv_pcmcia_config(): register_netdev() failed\n");
3946#endif
3947 break;
3948 }
3949 }
3950 while(0);
3951
3952
3953 if(i != 0)
3954 {
3955 wv_pcmcia_release(link);
3956 return FALSE;
3957 }
3958
3959 strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
3960 link->dev_node = &((net_local *) netdev_priv(dev))->node;
3961
3962#ifdef DEBUG_CONFIG_TRACE
3963 printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
3964#endif
3965 return TRUE;
3966}
3967
3968
3969
3970
3971
3972
3973
3974static void
3975wv_pcmcia_release(struct pcmcia_device *link)
3976{
3977 struct net_device * dev = (struct net_device *) link->priv;
3978 net_local * lp = netdev_priv(dev);
3979
3980#ifdef DEBUG_CONFIG_TRACE
3981 printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
3982#endif
3983
3984 iounmap(lp->mem);
3985 pcmcia_disable_device(link);
3986
3987#ifdef DEBUG_CONFIG_TRACE
3988 printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
3989#endif
3990}
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002static irqreturn_t
4003wavelan_interrupt(int irq,
4004 void * dev_id)
4005{
4006 struct net_device * dev = dev_id;
4007 net_local * lp;
4008 unsigned int base;
4009 int status0;
4010 u_int tx_status;
4011
4012#ifdef DEBUG_INTERRUPT_TRACE
4013 printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
4014#endif
4015
4016 lp = netdev_priv(dev);
4017 base = dev->base_addr;
4018
4019#ifdef DEBUG_INTERRUPT_INFO
4020
4021 if(spin_is_locked(&lp->spinlock))
4022 printk(KERN_DEBUG
4023 "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
4024 dev->name);
4025#endif
4026
4027
4028
4029
4030
4031 spin_lock(&lp->spinlock);
4032
4033
4034 while(1)
4035 {
4036
4037
4038
4039
4040 outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
4041 status0 = inb(LCSR(base));
4042
4043#ifdef DEBUG_INTERRUPT_INFO
4044 printk(KERN_DEBUG "status0 0x%x [%s => 0x%x]", status0,
4045 (status0&SR0_INTERRUPT)?"int":"no int",status0&~SR0_INTERRUPT);
4046 if(status0&SR0_INTERRUPT)
4047 {
4048 printk(" [%s => %d]\n", (status0 & SR0_CHNL) ? "chnl" :
4049 ((status0 & SR0_EXECUTION) ? "cmd" :
4050 ((status0 & SR0_RECEPTION) ? "recv" : "unknown")),
4051 (status0 & SR0_EVENT_MASK));
4052 }
4053 else
4054 printk("\n");
4055#endif
4056
4057
4058 if(!(status0 & SR0_INTERRUPT))
4059 break;
4060
4061
4062
4063
4064 if(((status0 & SR0_BOTH_RX_TX) == SR0_BOTH_RX_TX) ||
4065 ((status0 & SR0_BOTH_RX_TX) == 0x0))
4066 {
4067#ifdef DEBUG_INTERRUPT_INFO
4068 printk(KERN_INFO "%s: wv_interrupt(): bogus interrupt (or from dead card) : %X\n",
4069 dev->name, status0);
4070#endif
4071
4072 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
4073 break;
4074 }
4075
4076
4077
4078
4079
4080
4081
4082 if(status0 & SR0_RECEPTION)
4083 {
4084#ifdef DEBUG_INTERRUPT_INFO
4085 printk(KERN_DEBUG "%s: wv_interrupt(): receive\n", dev->name);
4086#endif
4087
4088 if((status0 & SR0_EVENT_MASK) == SR0_STOP_REG_HIT)
4089 {
4090#ifdef DEBUG_INTERRUPT_ERROR
4091 printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
4092 dev->name);
4093#endif
4094 dev->stats.rx_over_errors++;
4095 lp->overrunning = 1;
4096 }
4097
4098
4099 wv_packet_rcv(dev);
4100 lp->overrunning = 0;
4101
4102
4103 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
4104 continue;
4105 }
4106
4107
4108
4109
4110
4111
4112
4113
4114 if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
4115 (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
4116 (status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
4117 {
4118#ifdef DEBUG_TX_ERROR
4119 if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
4120 printk(KERN_INFO "%s: wv_interrupt(): packet transmitted without CRC.\n",
4121 dev->name);
4122#endif
4123
4124
4125 tx_status = inb(LCSR(base));
4126 tx_status |= (inb(LCSR(base)) << 8);
4127#ifdef DEBUG_INTERRUPT_INFO
4128 printk(KERN_DEBUG "%s: wv_interrupt(): transmission done\n",
4129 dev->name);
4130 {
4131 u_int rcv_bytes;
4132 u_char status3;
4133 rcv_bytes = inb(LCSR(base));
4134 rcv_bytes |= (inb(LCSR(base)) << 8);
4135 status3 = inb(LCSR(base));
4136 printk(KERN_DEBUG "tx_status 0x%02x rcv_bytes 0x%02x status3 0x%x\n",
4137 tx_status, rcv_bytes, (u_int) status3);
4138 }
4139#endif
4140
4141 if((tx_status & TX_OK) != TX_OK)
4142 {
4143 dev->stats.tx_errors++;
4144
4145 if(tx_status & TX_FRTL)
4146 {
4147#ifdef DEBUG_TX_ERROR
4148 printk(KERN_INFO "%s: wv_interrupt(): frame too long\n",
4149 dev->name);
4150#endif
4151 }
4152 if(tx_status & TX_UND_RUN)
4153 {
4154#ifdef DEBUG_TX_FAIL
4155 printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
4156 dev->name);
4157#endif
4158 dev->stats.tx_aborted_errors++;
4159 }
4160 if(tx_status & TX_LOST_CTS)
4161 {
4162#ifdef DEBUG_TX_FAIL
4163 printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name);
4164#endif
4165 dev->stats.tx_carrier_errors++;
4166 }
4167 if(tx_status & TX_LOST_CRS)
4168 {
4169#ifdef DEBUG_TX_FAIL
4170 printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
4171 dev->name);
4172#endif
4173 dev->stats.tx_carrier_errors++;
4174 }
4175 if(tx_status & TX_HRT_BEAT)
4176 {
4177#ifdef DEBUG_TX_FAIL
4178 printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name);
4179#endif
4180 dev->stats.tx_heartbeat_errors++;
4181 }
4182 if(tx_status & TX_DEFER)
4183 {
4184#ifdef DEBUG_TX_FAIL
4185 printk(KERN_DEBUG "%s: wv_interrupt(): channel jammed\n",
4186 dev->name);
4187#endif
4188 }
4189
4190
4191
4192
4193
4194 if(tx_status & TX_COLL)
4195 {
4196 if(tx_status & TX_MAX_COL)
4197 {
4198#ifdef DEBUG_TX_FAIL
4199 printk(KERN_DEBUG "%s: wv_interrupt(): channel congestion\n",
4200 dev->name);
4201#endif
4202 if(!(tx_status & TX_NCOL_MASK))
4203 {
4204 dev->stats.collisions += 0x10;
4205 }
4206 }
4207 }
4208 }
4209
4210 dev->stats.collisions += (tx_status & TX_NCOL_MASK);
4211 dev->stats.tx_packets++;
4212
4213 netif_wake_queue(dev);
4214 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
4215 }
4216 else
4217 {
4218#ifdef DEBUG_INTERRUPT_ERROR
4219 printk(KERN_INFO "wavelan_cs: unknown interrupt, status0 = %02x\n",
4220 status0);
4221#endif
4222 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
4223 }
4224 }
4225
4226 spin_unlock(&lp->spinlock);
4227
4228#ifdef DEBUG_INTERRUPT_TRACE
4229 printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
4230#endif
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248 return IRQ_HANDLED;
4249}
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263static void
4264wavelan_watchdog(struct net_device * dev)
4265{
4266 net_local * lp = netdev_priv(dev);
4267 unsigned int base = dev->base_addr;
4268 unsigned long flags;
4269 int aborted = FALSE;
4270
4271#ifdef DEBUG_INTERRUPT_TRACE
4272 printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
4273#endif
4274
4275#ifdef DEBUG_INTERRUPT_ERROR
4276 printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
4277 dev->name);
4278#endif
4279
4280 spin_lock_irqsave(&lp->spinlock, flags);
4281
4282
4283 outb(OP0_ABORT, LCCR(base));
4284
4285
4286 if(wv_82593_cmd(dev, "wavelan_watchdog(): abort",
4287 OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED))
4288 aborted = TRUE;
4289
4290
4291 spin_unlock_irqrestore(&lp->spinlock, flags);
4292
4293
4294 if(!aborted)
4295 {
4296
4297#ifdef DEBUG_INTERRUPT_ERROR
4298 printk(KERN_INFO "%s: wavelan_watchdog: abort failed, trying reset\n",
4299 dev->name);
4300#endif
4301 wv_hw_reset(dev);
4302 }
4303
4304#ifdef DEBUG_PSA_SHOW
4305 {
4306 psa_t psa;
4307 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
4308 wv_psa_show(&psa);
4309 }
4310#endif
4311#ifdef DEBUG_MMC_SHOW
4312 wv_mmc_show(dev);
4313#endif
4314#ifdef DEBUG_I82593_SHOW
4315 wv_ru_show(dev);
4316#endif
4317
4318
4319 netif_wake_queue(dev);
4320
4321#ifdef DEBUG_INTERRUPT_TRACE
4322 printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
4323#endif
4324}
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338static int
4339wavelan_open(struct net_device * dev)
4340{
4341 net_local * lp = netdev_priv(dev);
4342 struct pcmcia_device * link = lp->link;
4343 unsigned int base = dev->base_addr;
4344
4345#ifdef DEBUG_CALLBACK_TRACE
4346 printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
4347 (unsigned int) dev);
4348#endif
4349
4350
4351 if(hasr_read(base) & HASR_NO_CLK)
4352 {
4353
4354 hacr_write(base, HACR_DEFAULT);
4355
4356
4357 if(hasr_read(base) & HASR_NO_CLK)
4358 {
4359#ifdef DEBUG_CONFIG_ERRORS
4360 printk(KERN_WARNING "%s: wavelan_open(): modem not connected\n",
4361 dev->name);
4362#endif
4363 return FALSE;
4364 }
4365 }
4366
4367
4368 if(!lp->configured)
4369 return FALSE;
4370 if(!wv_ru_start(dev))
4371 wv_hw_reset(dev);
4372 netif_start_queue(dev);
4373
4374
4375 link->open++;
4376
4377#ifdef WAVELAN_ROAMING
4378 if(do_roaming)
4379 wv_roam_init(dev);
4380#endif
4381
4382#ifdef DEBUG_CALLBACK_TRACE
4383 printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
4384#endif
4385 return 0;
4386}
4387
4388
4389
4390
4391
4392
4393static int
4394wavelan_close(struct net_device * dev)
4395{
4396 struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link;
4397 unsigned int base = dev->base_addr;
4398
4399#ifdef DEBUG_CALLBACK_TRACE
4400 printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
4401 (unsigned int) dev);
4402#endif
4403
4404
4405 if(!link->open)
4406 {
4407#ifdef DEBUG_CONFIG_INFO
4408 printk(KERN_DEBUG "%s: wavelan_close(): device not open\n", dev->name);
4409#endif
4410 return 0;
4411 }
4412
4413#ifdef WAVELAN_ROAMING
4414
4415 if(do_roaming)
4416 wv_roam_cleanup(dev);
4417#endif
4418
4419 link->open--;
4420
4421
4422 if(netif_running(dev))
4423 {
4424 netif_stop_queue(dev);
4425
4426
4427 wv_ru_stop(dev);
4428
4429
4430 hacr_write(base, HACR_DEFAULT & (~HACR_PWR_STAT));
4431 }
4432
4433#ifdef DEBUG_CALLBACK_TRACE
4434 printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
4435#endif
4436 return 0;
4437}
4438
4439static const struct net_device_ops wavelan_netdev_ops = {
4440 .ndo_open = wavelan_open,
4441 .ndo_stop = wavelan_close,
4442 .ndo_start_xmit = wavelan_packet_xmit,
4443 .ndo_set_multicast_list = wavelan_set_multicast_list,
4444#ifdef SET_MAC_ADDRESS
4445 .ndo_set_mac_address = wavelan_set_mac_address,
4446#endif
4447 .ndo_tx_timeout = wavelan_watchdog,
4448 .ndo_change_mtu = eth_change_mtu,
4449 .ndo_validate_addr = eth_validate_addr,
4450};
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462static int
4463wavelan_probe(struct pcmcia_device *p_dev)
4464{
4465 struct net_device * dev;
4466 net_local * lp;
4467 int ret;
4468
4469#ifdef DEBUG_CALLBACK_TRACE
4470 printk(KERN_DEBUG "-> wavelan_attach()\n");
4471#endif
4472
4473
4474 p_dev->io.NumPorts1 = 8;
4475 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
4476 p_dev->io.IOAddrLines = 3;
4477
4478
4479 p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
4480 p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
4481 p_dev->irq.Handler = wavelan_interrupt;
4482
4483
4484 p_dev->conf.Attributes = CONF_ENABLE_IRQ;
4485 p_dev->conf.IntType = INT_MEMORY_AND_IO;
4486
4487
4488 dev = alloc_etherdev(sizeof(net_local));
4489 if (!dev)
4490 return -ENOMEM;
4491
4492 p_dev->priv = p_dev->irq.Instance = dev;
4493
4494 lp = netdev_priv(dev);
4495
4496
4497 lp->configured = 0;
4498 lp->reconfig_82593 = FALSE;
4499 lp->nresets = 0;
4500
4501 lp->promiscuous = 0;
4502 lp->allmulticast = 0;
4503 lp->mc_count = 0;
4504
4505
4506 spin_lock_init(&lp->spinlock);
4507
4508
4509 lp->dev = dev;
4510
4511
4512 dev->netdev_ops = &wavelan_netdev_ops;
4513 dev->watchdog_timeo = WATCHDOG_JIFFIES;
4514 SET_ETHTOOL_OPS(dev, &ops);
4515
4516 dev->wireless_handlers = &wavelan_handler_def;
4517 lp->wireless_data.spy_data = &lp->spy_data;
4518 dev->wireless_data = &lp->wireless_data;
4519
4520
4521 dev->mtu = WAVELAN_MTU;
4522
4523 ret = wv_pcmcia_config(p_dev);
4524 if (ret)
4525 return ret;
4526
4527 ret = wv_hw_config(dev);
4528 if (ret) {
4529 dev->irq = 0;
4530 pcmcia_disable_device(p_dev);
4531 return ret;
4532 }
4533
4534 wv_init_info(dev);
4535
4536#ifdef DEBUG_CALLBACK_TRACE
4537 printk(KERN_DEBUG "<- wavelan_attach()\n");
4538#endif
4539
4540 return 0;
4541}
4542
4543
4544
4545
4546
4547
4548
4549
4550static void
4551wavelan_detach(struct pcmcia_device *link)
4552{
4553#ifdef DEBUG_CALLBACK_TRACE
4554 printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
4555#endif
4556
4557
4558 wv_pcmcia_release(link);
4559
4560
4561 if(link->priv)
4562 {
4563 struct net_device * dev = (struct net_device *) link->priv;
4564
4565
4566
4567 if (link->dev_node)
4568 unregister_netdev(dev);
4569 link->dev_node = NULL;
4570 ((net_local *)netdev_priv(dev))->link = NULL;
4571 ((net_local *)netdev_priv(dev))->dev = NULL;
4572 free_netdev(dev);
4573 }
4574
4575#ifdef DEBUG_CALLBACK_TRACE
4576 printk(KERN_DEBUG "<- wavelan_detach()\n");
4577#endif
4578}
4579
4580static int wavelan_suspend(struct pcmcia_device *link)
4581{
4582 struct net_device * dev = (struct net_device *) link->priv;
4583
4584
4585
4586
4587
4588
4589
4590
4591 wv_ru_stop(dev);
4592
4593 if (link->open)
4594 netif_device_detach(dev);
4595
4596
4597 hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
4598
4599 return 0;
4600}
4601
4602static int wavelan_resume(struct pcmcia_device *link)
4603{
4604 struct net_device * dev = (struct net_device *) link->priv;
4605
4606 if (link->open) {
4607 wv_hw_reset(dev);
4608 netif_device_attach(dev);
4609 }
4610
4611 return 0;
4612}
4613
4614
4615static struct pcmcia_device_id wavelan_ids[] = {
4616 PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
4617 PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
4618 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/PCMCIA", 0x23eb9949, 0x1bc50975),
4619 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/PCMCIA", 0x24358cd4, 0x1bc50975),
4620 PCMCIA_DEVICE_NULL,
4621};
4622MODULE_DEVICE_TABLE(pcmcia, wavelan_ids);
4623
4624static struct pcmcia_driver wavelan_driver = {
4625 .owner = THIS_MODULE,
4626 .drv = {
4627 .name = "wavelan_cs",
4628 },
4629 .probe = wavelan_probe,
4630 .remove = wavelan_detach,
4631 .id_table = wavelan_ids,
4632 .suspend = wavelan_suspend,
4633 .resume = wavelan_resume,
4634};
4635
4636static int __init
4637init_wavelan_cs(void)
4638{
4639 return pcmcia_register_driver(&wavelan_driver);
4640}
4641
4642static void __exit
4643exit_wavelan_cs(void)
4644{
4645 pcmcia_unregister_driver(&wavelan_driver);
4646}
4647
4648module_init(init_wavelan_cs);
4649module_exit(exit_wavelan_cs);
4650