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
61#define USE_PROBE 1
62#undef USE_PROBE
63
64
65#define PROBE_VERBOSE 1
66
67
68
69#undef DUMP_PACKETS
70
71
72
73#define USE_MIR
74
75
76
77
78#define OPTIMIZE_TX
79
80
81
82
83
84#define RING_SIZE (OBOE_RING_SIZE_RX8 | OBOE_RING_SIZE_TX8)
85#define TX_SLOTS 8
86#define RX_SLOTS 8
87
88
89
90
91
92
93
94
95
96
97
98
99#define TT_LEN 0x80
100#define TX_LEN 0xc00
101#define RX_LEN 0xc04
102
103
104
105
106#define BUF_SAFETY 0x7a
107#define RX_BUF_SZ (RX_LEN)
108#define TX_BUF_SZ (TX_LEN+BUF_SAFETY)
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145#include <linux/module.h>
146
147#include <linux/kernel.h>
148#include <linux/types.h>
149#include <linux/skbuff.h>
150#include <linux/netdevice.h>
151#include <linux/ioport.h>
152#include <linux/delay.h>
153#include <linux/slab.h>
154#include <linux/init.h>
155#include <linux/interrupt.h>
156#include <linux/pci.h>
157#include <linux/rtnetlink.h>
158
159#include <asm/system.h>
160#include <asm/io.h>
161
162#include <net/irda/wrapper.h>
163#include <net/irda/irda.h>
164
165
166#include <net/irda/irda_device.h>
167#include <net/irda/crc.h>
168
169#include "donauboe.h"
170
171#define INB(port) inb_p(port)
172#define OUTB(val,port) outb_p(val,port)
173#define OUTBP(val,port) outb_p(val,port)
174
175#define PROMPT OUTB(OBOE_PROMPT_BIT,OBOE_PROMPT);
176
177#if PROBE_VERBOSE
178#define PROBE_DEBUG(args...) (printk (args))
179#else
180#define PROBE_DEBUG(args...) ;
181#endif
182
183
184#define CONFIG0H_DMA_OFF OBOE_CONFIG0H_RCVANY
185#define CONFIG0H_DMA_ON_NORX CONFIG0H_DMA_OFF| OBOE_CONFIG0H_ENDMAC
186#define CONFIG0H_DMA_ON CONFIG0H_DMA_ON_NORX | OBOE_CONFIG0H_ENRX
187
188static DEFINE_PCI_DEVICE_TABLE(toshoboe_pci_tbl) = {
189 { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },
190 { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIRD01, PCI_ANY_ID, PCI_ANY_ID, },
191 { }
192};
193MODULE_DEVICE_TABLE(pci, toshoboe_pci_tbl);
194
195#define DRIVER_NAME "toshoboe"
196static char *driver_name = DRIVER_NAME;
197
198static int max_baud = 4000000;
199#ifdef USE_PROBE
200static int do_probe = 0;
201#endif
202
203
204
205static int
206toshoboe_checkfcs (unsigned char *buf, int len)
207{
208 int i;
209 union
210 {
211 __u16 value;
212 __u8 bytes[2];
213 }
214 fcs;
215
216 fcs.value = INIT_FCS;
217
218 for (i = 0; i < len; ++i)
219 fcs.value = irda_fcs (fcs.value, *(buf++));
220
221 return fcs.value == GOOD_FCS;
222}
223
224
225
226#ifdef DUMP_PACKETS
227static unsigned char dump[50];
228static void
229_dumpbufs (unsigned char *data, int len, char tete)
230{
231int i,j;
232char head=tete;
233for (i=0;i<len;i+=16) {
234 for (j=0;j<16 && i+j<len;j++) { sprintf(&dump[3*j],"%02x.",data[i+j]); }
235 dump [3*j]=0;
236 IRDA_DEBUG (2, "%c%s\n",head , dump);
237 head='+';
238 }
239}
240#endif
241
242#ifdef USE_PROBE
243
244static void
245toshoboe_dumpregs (struct toshoboe_cb *self)
246{
247 __u32 ringbase;
248
249 IRDA_DEBUG (4, "%s()\n", __func__);
250
251 ringbase = INB (OBOE_RING_BASE0) << 10;
252 ringbase |= INB (OBOE_RING_BASE1) << 18;
253 ringbase |= INB (OBOE_RING_BASE2) << 26;
254
255 printk (KERN_ERR DRIVER_NAME ": Register dump:\n");
256 printk (KERN_ERR "Interrupts: Tx:%d Rx:%d TxUnder:%d RxOver:%d Sip:%d\n",
257 self->int_tx, self->int_rx, self->int_txunder, self->int_rxover,
258 self->int_sip);
259 printk (KERN_ERR "RX %02x TX %02x RingBase %08x\n",
260 INB (OBOE_RXSLOT), INB (OBOE_TXSLOT), ringbase);
261 printk (KERN_ERR "RING_SIZE %02x IER %02x ISR %02x\n",
262 INB (OBOE_RING_SIZE), INB (OBOE_IER), INB (OBOE_ISR));
263 printk (KERN_ERR "CONFIG1 %02x STATUS %02x\n",
264 INB (OBOE_CONFIG1), INB (OBOE_STATUS));
265 printk (KERN_ERR "CONFIG0 %02x%02x ENABLE %02x%02x\n",
266 INB (OBOE_CONFIG0H), INB (OBOE_CONFIG0L),
267 INB (OBOE_ENABLEH), INB (OBOE_ENABLEL));
268 printk (KERN_ERR "NEW_PCONFIG %02x%02x CURR_PCONFIG %02x%02x\n",
269 INB (OBOE_NEW_PCONFIGH), INB (OBOE_NEW_PCONFIGL),
270 INB (OBOE_CURR_PCONFIGH), INB (OBOE_CURR_PCONFIGL));
271 printk (KERN_ERR "MAXLEN %02x%02x RXCOUNT %02x%02x\n",
272 INB (OBOE_MAXLENH), INB (OBOE_MAXLENL),
273 INB (OBOE_RXCOUNTL), INB (OBOE_RXCOUNTH));
274
275 if (self->ring)
276 {
277 int i;
278 ringbase = virt_to_bus (self->ring);
279 printk (KERN_ERR "Ring at %08x:\n", ringbase);
280 printk (KERN_ERR "RX:");
281 for (i = 0; i < RX_SLOTS; ++i)
282 printk (" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
283 printk ("\n");
284 printk (KERN_ERR "TX:");
285 for (i = 0; i < RX_SLOTS; ++i)
286 printk (" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
287 printk ("\n");
288 }
289}
290#endif
291
292
293static void
294toshoboe_disablebm (struct toshoboe_cb *self)
295{
296 __u8 command;
297 IRDA_DEBUG (4, "%s()\n", __func__);
298
299 pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
300 command &= ~PCI_COMMAND_MASTER;
301 pci_write_config_byte (self->pdev, PCI_COMMAND, command);
302
303}
304
305
306static void
307toshoboe_stopchip (struct toshoboe_cb *self)
308{
309 IRDA_DEBUG (4, "%s()\n", __func__);
310
311
312 OUTB (0x0, OBOE_IER);
313
314 OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
315
316 OUTB (0x00, OBOE_ENABLEH);
317
318 OUTB (0x3f, OBOE_RING_BASE2);
319 OUTB (0xff, OBOE_RING_BASE1);
320 OUTB (0xff, OBOE_RING_BASE0);
321
322 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
323 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
324
325
326 OUTB (0xff, OBOE_ISR);
327
328
329 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
330
331
332 OUTB (OBOE_CONFIG1_OFF, OBOE_CONFIG1);
333
334 toshoboe_disablebm (self);
335}
336
337
338static void
339toshoboe_start_DMA (struct toshoboe_cb *self, int opts)
340{
341 OUTB (0x0, OBOE_ENABLEH);
342 OUTB (CONFIG0H_DMA_ON | opts, OBOE_CONFIG0H);
343 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
344 PROMPT;
345}
346
347
348static void
349toshoboe_setbaud (struct toshoboe_cb *self)
350{
351 __u16 pconfig = 0;
352 __u8 config0l = 0;
353
354 IRDA_DEBUG (2, "%s(%d/%d)\n", __func__, self->speed, self->io.speed);
355
356 switch (self->speed)
357 {
358 case 2400:
359 case 4800:
360 case 9600:
361 case 19200:
362 case 38400:
363 case 57600:
364 case 115200:
365#ifdef USE_MIR
366 case 1152000:
367#endif
368 case 4000000:
369 break;
370 default:
371
372 printk (KERN_ERR DRIVER_NAME ": switch to unsupported baudrate %d\n",
373 self->speed);
374 return;
375 }
376
377 switch (self->speed)
378 {
379
380
381
382 case 2400:
383 pconfig |= 47 << OBOE_PCONFIG_BAUDSHIFT;
384 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
385 break;
386 case 4800:
387 pconfig |= 23 << OBOE_PCONFIG_BAUDSHIFT;
388 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
389 break;
390 case 9600:
391 pconfig |= 11 << OBOE_PCONFIG_BAUDSHIFT;
392 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
393 break;
394 case 19200:
395 pconfig |= 5 << OBOE_PCONFIG_BAUDSHIFT;
396 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
397 break;
398 case 38400:
399 pconfig |= 2 << OBOE_PCONFIG_BAUDSHIFT;
400 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
401 break;
402 case 57600:
403 pconfig |= 1 << OBOE_PCONFIG_BAUDSHIFT;
404 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
405 break;
406 case 115200:
407 pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
408 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
409 break;
410 default:
411
412 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
413 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
414 break;
415 }
416
417 switch (self->speed)
418 {
419 case 2400:
420 case 4800:
421 case 9600:
422 case 19200:
423 case 38400:
424 case 57600:
425 case 115200:
426 config0l = OBOE_CONFIG0L_ENSIR;
427 if (self->async)
428 {
429
430
431
432 OUTB (0x01, OBOE_MAXLENH);
433 OUTB (0x01, OBOE_MAXLENL);
434 OUTB (0x00, OBOE_MAXLENH);
435 }
436 else
437 {
438
439 config0l |= OBOE_CONFIG0L_ENSIRF;
440 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
441 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
442 }
443 break;
444
445#ifdef USE_MIR
446
447
448
449 case 1152000:
450 pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
451 pconfig |= 8 << OBOE_PCONFIG_WIDTHSHIFT;
452 pconfig |= 1 << OBOE_PCONFIG_PREAMBLESHIFT;
453 config0l = OBOE_CONFIG0L_CRC16 | OBOE_CONFIG0L_ENMIR;
454 break;
455#endif
456
457
458
459 case 4000000:
460 pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
461
462 pconfig |= 15 << OBOE_PCONFIG_PREAMBLESHIFT;
463 config0l = OBOE_CONFIG0L_ENFIR;
464 break;
465 }
466
467
468 OUTBP (pconfig >> 8, OBOE_NEW_PCONFIGH);
469 OUTB (pconfig & 0xff, OBOE_NEW_PCONFIGL);
470 OUTB (config0l, OBOE_CONFIG0L);
471
472
473 OUTB (0x0, OBOE_ENABLEH);
474 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
475 PROMPT;
476
477
478 self->new_speed = 0;
479 self->io.speed = self->speed;
480}
481
482
483static void
484toshoboe_enablebm (struct toshoboe_cb *self)
485{
486 IRDA_DEBUG (4, "%s()\n", __func__);
487 pci_set_master (self->pdev);
488}
489
490
491static void
492toshoboe_initring (struct toshoboe_cb *self)
493{
494 int i;
495
496 IRDA_DEBUG (4, "%s()\n", __func__);
497
498 for (i = 0; i < TX_SLOTS; ++i)
499 {
500 self->ring->tx[i].len = 0;
501 self->ring->tx[i].control = 0x00;
502 self->ring->tx[i].address = virt_to_bus (self->tx_bufs[i]);
503 }
504
505 for (i = 0; i < RX_SLOTS; ++i)
506 {
507 self->ring->rx[i].len = RX_LEN;
508 self->ring->rx[i].len = 0;
509 self->ring->rx[i].address = virt_to_bus (self->rx_bufs[i]);
510 self->ring->rx[i].control = OBOE_CTL_RX_HW_OWNS;
511 }
512}
513
514static void
515toshoboe_resetptrs (struct toshoboe_cb *self)
516{
517
518 OUTB (0x0, OBOE_ENABLEH);
519 OUTBP (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
520 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
521
522 self->rxs = inb_p (OBOE_RXSLOT) & OBOE_SLOT_MASK;
523 self->txs = inb_p (OBOE_TXSLOT) & OBOE_SLOT_MASK;
524}
525
526
527static void
528toshoboe_initptrs (struct toshoboe_cb *self)
529{
530
531
532
533
534
535 toshoboe_resetptrs (self);
536
537 OUTB (0x0, OBOE_ENABLEH);
538 OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
539 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
540
541 self->txpending = 0;
542
543
544
545}
546
547
548
549static void
550toshoboe_startchip (struct toshoboe_cb *self)
551{
552 __u32 physaddr;
553
554 IRDA_DEBUG (4, "%s()\n", __func__);
555
556 toshoboe_initring (self);
557 toshoboe_enablebm (self);
558 OUTBP (OBOE_CONFIG1_RESET, OBOE_CONFIG1);
559 OUTBP (OBOE_CONFIG1_ON, OBOE_CONFIG1);
560
561
562 OUTB (0, OBOE_ENABLEH);
563
564
565 OUTB (RING_SIZE, OBOE_RING_SIZE);
566
567
568 OUTB (0xff, OBOE_ISR);
569
570
571 OUTB (OBOE_INT_TXDONE | OBOE_INT_RXDONE |
572 OBOE_INT_TXUNDER | OBOE_INT_RXOVER | OBOE_INT_SIP , OBOE_IER);
573
574
575 OUTB (0xff, OBOE_ISR);
576
577
578 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
579 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
580
581
582 OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
583
584
585 physaddr = virt_to_bus (self->ring);
586
587 IRDA_ASSERT ((physaddr & 0x3ff) == 0,
588 printk (KERN_ERR DRIVER_NAME "ring not correctly aligned\n");
589 return;);
590
591 OUTB ((physaddr >> 10) & 0xff, OBOE_RING_BASE0);
592 OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);
593 OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);
594
595
596 OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
597
598
599 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
600
601
602 self->speed = 9600;
603 toshoboe_setbaud (self);
604 toshoboe_initptrs (self);
605}
606
607static void
608toshoboe_isntstuck (struct toshoboe_cb *self)
609{
610}
611
612static void
613toshoboe_checkstuck (struct toshoboe_cb *self)
614{
615 unsigned long flags;
616
617 if (0)
618 {
619 spin_lock_irqsave(&self->spinlock, flags);
620
621
622 printk (KERN_ERR DRIVER_NAME ": Resetting chip\n");
623
624 toshoboe_stopchip (self);
625 toshoboe_startchip (self);
626 spin_unlock_irqrestore(&self->spinlock, flags);
627 }
628}
629
630
631static int
632toshoboe_makemttpacket (struct toshoboe_cb *self, void *buf, int mtt)
633{
634 int xbofs;
635
636 xbofs = ((int) (mtt/100)) * (int) (self->speed);
637 xbofs=xbofs/80000;
638 xbofs++;
639
640 IRDA_DEBUG (2, DRIVER_NAME
641 ": generated mtt of %d bytes for %d us at %d baud\n"
642 , xbofs,mtt,self->speed);
643
644 if (xbofs > TX_LEN)
645 {
646 printk (KERN_ERR DRIVER_NAME ": wanted %d bytes MTT but TX_LEN is %d\n",
647 xbofs, TX_LEN);
648 xbofs = TX_LEN;
649 }
650
651
652 memset (buf, XBOF, xbofs);
653
654 return xbofs;
655}
656
657#ifdef USE_PROBE
658
659
660
661static void
662toshoboe_dumptx (struct toshoboe_cb *self)
663{
664 int i;
665 PROBE_DEBUG(KERN_WARNING "TX:");
666 for (i = 0; i < RX_SLOTS; ++i)
667 PROBE_DEBUG(" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
668 PROBE_DEBUG(" [%d]\n",self->speed);
669}
670
671static void
672toshoboe_dumprx (struct toshoboe_cb *self, int score)
673{
674 int i;
675 PROBE_DEBUG(" %d\nRX:",score);
676 for (i = 0; i < RX_SLOTS; ++i)
677 PROBE_DEBUG(" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
678 PROBE_DEBUG("\n");
679}
680
681static inline int
682stuff_byte (__u8 byte, __u8 * buf)
683{
684 switch (byte)
685 {
686 case BOF:
687 case EOF:
688 case CE:
689
690 buf[0] = CE;
691 buf[1] = byte ^ IRDA_TRANS;
692 return 2;
693
694 default:
695
696 buf[0] = byte;
697 return 1;
698
699 }
700}
701
702static irqreturn_t
703toshoboe_probeinterrupt (int irq, void *dev_id)
704{
705 struct toshoboe_cb *self = dev_id;
706 __u8 irqstat;
707
708 irqstat = INB (OBOE_ISR);
709
710
711 if (!(irqstat & OBOE_INT_MASK))
712 return IRQ_NONE;
713
714
715 OUTB (irqstat, OBOE_ISR);
716
717 if (irqstat & OBOE_INT_TXDONE)
718 {
719 int txp;
720
721 self->int_tx++;
722 PROBE_DEBUG("T");
723
724 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
725 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
726 {
727 self->int_tx+=100;
728 PROBE_DEBUG("S");
729 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
730 }
731 }
732
733 if (irqstat & OBOE_INT_RXDONE) {
734 self->int_rx++;
735 PROBE_DEBUG("R"); }
736 if (irqstat & OBOE_INT_TXUNDER) {
737 self->int_txunder++;
738 PROBE_DEBUG("U"); }
739 if (irqstat & OBOE_INT_RXOVER) {
740 self->int_rxover++;
741 PROBE_DEBUG("O"); }
742 if (irqstat & OBOE_INT_SIP) {
743 self->int_sip++;
744 PROBE_DEBUG("I"); }
745 return IRQ_HANDLED;
746}
747
748static int
749toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir)
750{
751 int i;
752 int len = 0;
753 union
754 {
755 __u16 value;
756 __u8 bytes[2];
757 }
758 fcs;
759
760 if (fir)
761 {
762 memset (buf, 0, TT_LEN);
763 return TT_LEN;
764 }
765
766 fcs.value = INIT_FCS;
767
768 memset (buf, XBOF, 10);
769 len += 10;
770 buf[len++] = BOF;
771
772 for (i = 0; i < TT_LEN; ++i)
773 {
774 len += stuff_byte (i, buf + len);
775 fcs.value = irda_fcs (fcs.value, i);
776 }
777
778 len += stuff_byte (fcs.bytes[0] ^ badcrc, buf + len);
779 len += stuff_byte (fcs.bytes[1] ^ badcrc, buf + len);
780 buf[len++] = EOF;
781 len++;
782 return len;
783}
784
785static int
786toshoboe_probefail (struct toshoboe_cb *self, char *msg)
787{
788 printk (KERN_ERR DRIVER_NAME "probe(%d) failed %s\n",self-> speed, msg);
789 toshoboe_dumpregs (self);
790 toshoboe_stopchip (self);
791 free_irq (self->io.irq, (void *) self);
792 return 0;
793}
794
795static int
796toshoboe_numvalidrcvs (struct toshoboe_cb *self)
797{
798 int i, ret = 0;
799 for (i = 0; i < RX_SLOTS; ++i)
800 if ((self->ring->rx[i].control & 0xe0) == 0)
801 ret++;
802
803 return ret;
804}
805
806static int
807toshoboe_numrcvs (struct toshoboe_cb *self)
808{
809 int i, ret = 0;
810 for (i = 0; i < RX_SLOTS; ++i)
811 if (!(self->ring->rx[i].control & OBOE_CTL_RX_HW_OWNS))
812 ret++;
813
814 return ret;
815}
816
817static int
818toshoboe_probe (struct toshoboe_cb *self)
819{
820 int i, j, n;
821#ifdef USE_MIR
822 static const int bauds[] = { 9600, 115200, 4000000, 1152000 };
823#else
824 static const int bauds[] = { 9600, 115200, 4000000 };
825#endif
826 unsigned long flags;
827
828 IRDA_DEBUG (4, "%s()\n", __func__);
829
830 if (request_irq (self->io.irq, toshoboe_probeinterrupt,
831 self->io.irqflags, "toshoboe", (void *) self))
832 {
833 printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n",
834 self->io.irq);
835 return 0;
836 }
837
838
839
840 for (j = 0; j < ARRAY_SIZE(bauds); ++j)
841 {
842 int fir = (j > 1);
843 toshoboe_stopchip (self);
844
845
846 spin_lock_irqsave(&self->spinlock, flags);
847
848 toshoboe_startchip (self);
849 self->int_rx = self->int_tx = 0;
850 self->speed = bauds[j];
851 toshoboe_setbaud (self);
852 toshoboe_initptrs (self);
853 spin_unlock_irqrestore(&self->spinlock, flags);
854
855 self->ring->tx[self->txs].control =
856
857
858 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
859 : OBOE_CTL_TX_HW_OWNS ;
860 self->ring->tx[self->txs].len =
861 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
862 self->txs++;
863 self->txs %= TX_SLOTS;
864
865 self->ring->tx[self->txs].control =
866 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_SIP
867 : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
868 self->ring->tx[self->txs].len =
869 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
870 self->txs++;
871 self->txs %= TX_SLOTS;
872
873 self->ring->tx[self->txs].control =
874 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
875 : OBOE_CTL_TX_HW_OWNS ;
876 self->ring->tx[self->txs].len =
877 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
878 self->txs++;
879 self->txs %= TX_SLOTS;
880
881 self->ring->tx[self->txs].control =
882 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
883 | OBOE_CTL_TX_SIP | OBOE_CTL_TX_BAD_CRC
884 : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
885 self->ring->tx[self->txs].len =
886 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
887 self->txs++;
888 self->txs %= TX_SLOTS;
889
890 toshoboe_dumptx (self);
891
892 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
893
894 i = 0;
895 n = fir ? 1 : 4;
896 while (toshoboe_numvalidrcvs (self) != n)
897 {
898 if (i > 4800)
899 return toshoboe_probefail (self, "filter test");
900 udelay ((9600*(TT_LEN+16))/self->speed);
901 i++;
902 }
903
904 n = fir ? 203 : 102;
905 while ((toshoboe_numrcvs(self) != self->int_rx) || (self->int_tx != n))
906 {
907 if (i > 4800)
908 return toshoboe_probefail (self, "interrupt test");
909 udelay ((9600*(TT_LEN+16))/self->speed);
910 i++;
911 }
912 toshoboe_dumprx (self,i);
913
914 }
915
916
917
918 toshoboe_stopchip (self);
919 self->int_rx = self->int_tx = 0;
920
921 spin_lock_irqsave(&self->spinlock, flags);
922 toshoboe_startchip (self);
923 spin_unlock_irqrestore(&self->spinlock, flags);
924
925 self->async = 1;
926 self->speed = 115200;
927 toshoboe_setbaud (self);
928 self->ring->tx[self->txs].control =
929 OBOE_CTL_TX_RTCENTX | OBOE_CTL_TX_HW_OWNS;
930 self->ring->tx[self->txs].len = 4;
931
932 ((unsigned char *) self->tx_bufs[self->txs])[0] = 'f';
933 ((unsigned char *) self->tx_bufs[self->txs])[1] = 'i';
934 ((unsigned char *) self->tx_bufs[self->txs])[2] = 's';
935 ((unsigned char *) self->tx_bufs[self->txs])[3] = 'h';
936 toshoboe_dumptx (self);
937 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
938
939 i = 0;
940 while (toshoboe_numvalidrcvs (self) != 4)
941 {
942 if (i > 100)
943 return toshoboe_probefail (self, "Async test");
944 udelay (100);
945 i++;
946 }
947
948 while ((toshoboe_numrcvs (self) != self->int_rx) || (self->int_tx != 1))
949 {
950 if (i > 100)
951 return toshoboe_probefail (self, "Async interrupt test");
952 udelay (100);
953 i++;
954 }
955 toshoboe_dumprx (self,i);
956
957 self->async = 0;
958 self->speed = 9600;
959 toshoboe_setbaud (self);
960 toshoboe_stopchip (self);
961
962 free_irq (self->io.irq, (void *) self);
963
964 printk (KERN_WARNING DRIVER_NAME ": Self test passed ok\n");
965
966 return 1;
967}
968#endif
969
970
971
972
973
974static netdev_tx_t
975toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
976{
977 struct toshoboe_cb *self;
978 __s32 speed;
979 int mtt, len, ctl;
980 unsigned long flags;
981 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
982
983 self = netdev_priv(dev);
984
985 IRDA_ASSERT (self != NULL, return NETDEV_TX_OK; );
986
987 IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __func__
988 ,skb->len,self->txpending,INB (OBOE_ENABLEH));
989 if (!cb->magic) {
990 IRDA_DEBUG (2, "%s.Not IrLAP:%x\n", __func__, cb->magic);
991#ifdef DUMP_PACKETS
992 _dumpbufs(skb->data,skb->len,'>');
993#endif
994 }
995
996
997 if (self->new_speed)
998 return NETDEV_TX_BUSY;
999
1000
1001 if (self->stopped)
1002 return NETDEV_TX_BUSY;
1003
1004 toshoboe_checkstuck (self);
1005
1006
1007
1008 speed=irda_get_next_speed(skb);
1009 if ((speed != self->io.speed) && (speed != -1))
1010 {
1011 spin_lock_irqsave(&self->spinlock, flags);
1012
1013 if (self->txpending || skb->len)
1014 {
1015 self->new_speed = speed;
1016 IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" ,
1017 __func__, speed);
1018
1019 if (!skb->len)
1020 {
1021 spin_unlock_irqrestore(&self->spinlock, flags);
1022 dev_kfree_skb (skb);
1023 return NETDEV_TX_OK;
1024 }
1025
1026
1027 netif_stop_queue(dev);
1028
1029 spin_unlock_irqrestore(&self->spinlock, flags);
1030 }
1031 else
1032 {
1033
1034 self->speed = speed;
1035 toshoboe_setbaud (self);
1036 spin_unlock_irqrestore(&self->spinlock, flags);
1037 dev_kfree_skb (skb);
1038 return NETDEV_TX_OK;
1039 }
1040
1041 }
1042
1043 if ((mtt = irda_get_mtt(skb)))
1044 {
1045
1046 spin_lock_irqsave(&self->spinlock, flags);
1047
1048 if (self->txpending)
1049 {
1050 spin_unlock_irqrestore(&self->spinlock, flags);
1051 return NETDEV_TX_BUSY;
1052 }
1053
1054
1055
1056
1057
1058 mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt);
1059 IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __func__
1060 ,skb->len,mtt,self->txpending);
1061 if (mtt)
1062 {
1063 self->ring->tx[self->txs].len = mtt & 0xfff;
1064
1065 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1066 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1067 {
1068 ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ;
1069 }
1070#ifdef USE_MIR
1071 else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON)
1072 {
1073 ctl |= OBOE_CTL_TX_BAD_CRC;
1074 }
1075#endif
1076 self->ring->tx[self->txs].control = ctl;
1077
1078 OUTB (0x0, OBOE_ENABLEH);
1079
1080 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
1081
1082 self->txpending++;
1083
1084 self->txs++;
1085 self->txs %= TX_SLOTS;
1086
1087 }
1088 else
1089 {
1090 printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n");
1091 }
1092 spin_unlock_irqrestore(&self->spinlock, flags);
1093 }
1094
1095#ifdef DUMP_PACKETS
1096dumpbufs(skb->data,skb->len,'>');
1097#endif
1098
1099 spin_lock_irqsave(&self->spinlock, flags);
1100
1101 if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS)
1102 {
1103 IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __func__
1104 ,skb->len, self->ring->tx[self->txs].control, self->txpending);
1105 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1106 spin_unlock_irqrestore(&self->spinlock, flags);
1107 return NETDEV_TX_BUSY;
1108 }
1109
1110 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
1111 {
1112 len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ);
1113 }
1114 else
1115 {
1116 len = skb->len;
1117 skb_copy_from_linear_data(skb, self->tx_bufs[self->txs], len);
1118 }
1119 self->ring->tx[self->txs].len = len & 0x0fff;
1120
1121
1122
1123
1124
1125 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1126 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1127 {
1128 ctl |= OBOE_CTL_TX_SIP ;
1129 }
1130 self->ring->tx[self->txs].control = ctl;
1131
1132
1133
1134 if (!self->txpending)
1135 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1136
1137 self->txpending++;
1138
1139 self->txs++;
1140 self->txs %= TX_SLOTS;
1141
1142 spin_unlock_irqrestore(&self->spinlock, flags);
1143 dev_kfree_skb (skb);
1144
1145 return NETDEV_TX_OK;
1146}
1147
1148
1149static irqreturn_t
1150toshoboe_interrupt (int irq, void *dev_id)
1151{
1152 struct toshoboe_cb *self = dev_id;
1153 __u8 irqstat;
1154 struct sk_buff *skb = NULL;
1155
1156 irqstat = INB (OBOE_ISR);
1157
1158
1159 if (!(irqstat & OBOE_INT_MASK))
1160 return IRQ_NONE;
1161
1162
1163 OUTB (irqstat, OBOE_ISR);
1164
1165 toshoboe_isntstuck (self);
1166
1167
1168 if (irqstat & OBOE_INT_TXDONE)
1169 {
1170 int txp, txpc;
1171 int i;
1172
1173 txp = self->txpending;
1174 self->txpending = 0;
1175
1176 for (i = 0; i < TX_SLOTS; ++i)
1177 {
1178 if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS)
1179 self->txpending++;
1180 }
1181 IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __func__
1182 ,irqstat,txp,self->txpending);
1183
1184 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
1185
1186
1187 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
1188 {
1189 txpc = txp;
1190#ifdef OPTIMIZE_TX
1191 while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1192 {
1193 txp = txpc;
1194 txpc++;
1195 txpc %= TX_SLOTS;
1196 self->netdev->stats.tx_packets++;
1197 if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1198 self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
1199 }
1200 self->netdev->stats.tx_packets--;
1201#else
1202 self->netdev->stats.tx_packets++;
1203#endif
1204 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1205 }
1206
1207 if ((!self->txpending) && (self->new_speed))
1208 {
1209 self->speed = self->new_speed;
1210 IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n",
1211 __func__, self->speed);
1212 toshoboe_setbaud (self);
1213 }
1214
1215
1216 if (!self->new_speed)
1217 netif_wake_queue(self->netdev);
1218 }
1219
1220 if (irqstat & OBOE_INT_RXDONE)
1221 {
1222 while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS))
1223 {
1224 int len = self->ring->rx[self->rxs].len;
1225 skb = NULL;
1226 IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __func__
1227 ,len,self->ring->rx[self->rxs].control);
1228
1229#ifdef DUMP_PACKETS
1230dumpbufs(self->rx_bufs[self->rxs],len,'<');
1231#endif
1232
1233 if (self->ring->rx[self->rxs].control == 0)
1234 {
1235 __u8 enable = INB (OBOE_ENABLEH);
1236
1237
1238
1239 if (enable & OBOE_ENABLEH_SIRON)
1240 {
1241 if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len))
1242 len = 0;
1243
1244 if (len > 1)
1245 len -= 2;
1246 else
1247 len = 0;
1248 IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __func__, len,enable);
1249 }
1250
1251#ifdef USE_MIR
1252 else if (enable & OBOE_ENABLEH_MIRON)
1253 {
1254 if (len > 1)
1255 len -= 2;
1256 else
1257 len = 0;
1258 IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __func__, len,enable);
1259 }
1260#endif
1261 else if (enable & OBOE_ENABLEH_FIRON)
1262 {
1263 if (len > 3)
1264 len -= 4;
1265 else
1266 len = 0;
1267 IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __func__, len,enable);
1268 }
1269 else
1270 IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __func__, len,enable);
1271
1272 if (len)
1273 {
1274 skb = dev_alloc_skb (len + 1);
1275 if (skb)
1276 {
1277 skb_reserve (skb, 1);
1278
1279 skb_put (skb, len);
1280 skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs],
1281 len);
1282 self->netdev->stats.rx_packets++;
1283 skb->dev = self->netdev;
1284 skb_reset_mac_header(skb);
1285 skb->protocol = htons (ETH_P_IRDA);
1286 }
1287 else
1288 {
1289 printk (KERN_INFO
1290 "%s(), memory squeeze, dropping frame.\n",
1291 __func__);
1292 }
1293 }
1294 }
1295 else
1296 {
1297
1298
1299
1300
1301
1302
1303 IRDA_DEBUG (0, "%s.err:%x(%x)\n", __func__
1304 ,len,self->ring->rx[self->rxs].control);
1305 }
1306
1307 self->ring->rx[self->rxs].len = 0x0;
1308 self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS;
1309
1310 self->rxs++;
1311 self->rxs %= RX_SLOTS;
1312
1313 if (skb)
1314 netif_rx (skb);
1315
1316 }
1317 }
1318
1319 if (irqstat & OBOE_INT_TXUNDER)
1320 {
1321 printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n");
1322 }
1323 if (irqstat & OBOE_INT_RXOVER)
1324 {
1325 printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n");
1326 }
1327
1328 if (irqstat & OBOE_INT_SIP)
1329 {
1330 self->int_sip++;
1331 IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __func__
1332 ,self->int_sip,irqstat,self->txpending);
1333 }
1334 return IRQ_HANDLED;
1335}
1336
1337
1338static int
1339toshoboe_net_open (struct net_device *dev)
1340{
1341 struct toshoboe_cb *self;
1342 unsigned long flags;
1343 int rc;
1344
1345 IRDA_DEBUG (4, "%s()\n", __func__);
1346
1347 self = netdev_priv(dev);
1348
1349 if (self->async)
1350 return -EBUSY;
1351
1352 if (self->stopped)
1353 return 0;
1354
1355 rc = request_irq (self->io.irq, toshoboe_interrupt,
1356 IRQF_SHARED | IRQF_DISABLED, dev->name, self);
1357 if (rc)
1358 return rc;
1359
1360 spin_lock_irqsave(&self->spinlock, flags);
1361 toshoboe_startchip (self);
1362 spin_unlock_irqrestore(&self->spinlock, flags);
1363
1364
1365 netif_start_queue(dev);
1366
1367
1368
1369
1370
1371 self->irlap = irlap_open (dev, &self->qos, driver_name);
1372
1373 self->irdad = 1;
1374
1375 return 0;
1376}
1377
1378static int
1379toshoboe_net_close (struct net_device *dev)
1380{
1381 struct toshoboe_cb *self;
1382
1383 IRDA_DEBUG (4, "%s()\n", __func__);
1384
1385 IRDA_ASSERT (dev != NULL, return -1; );
1386 self = netdev_priv(dev);
1387
1388
1389 netif_stop_queue(dev);
1390
1391
1392 if (self->irlap)
1393 irlap_close (self->irlap);
1394 self->irlap = NULL;
1395
1396 self->irdad = 0;
1397
1398 free_irq (self->io.irq, (void *) self);
1399
1400 if (!self->stopped)
1401 {
1402 toshoboe_stopchip (self);
1403 }
1404
1405 return 0;
1406}
1407
1408
1409
1410
1411
1412
1413
1414static int
1415toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1416{
1417 struct if_irda_req *irq = (struct if_irda_req *) rq;
1418 struct toshoboe_cb *self;
1419 unsigned long flags;
1420 int ret = 0;
1421
1422 IRDA_ASSERT (dev != NULL, return -1; );
1423
1424 self = netdev_priv(dev);
1425
1426 IRDA_ASSERT (self != NULL, return -1; );
1427
1428 IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
1429
1430
1431 spin_lock_irqsave(&self->spinlock, flags);
1432
1433 switch (cmd)
1434 {
1435 case SIOCSBANDWIDTH:
1436
1437
1438
1439
1440 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __func__
1441 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1442 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1443 ret = -EPERM;
1444 goto out;
1445 }
1446
1447
1448
1449
1450 self->new_speed = irq->ifr_baudrate;
1451 break;
1452 case SIOCSMEDIABUSY:
1453 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __func__
1454 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1455 if (!capable (CAP_NET_ADMIN)) {
1456 ret = -EPERM;
1457 goto out;
1458 }
1459 irda_device_set_media_busy (self->netdev, TRUE);
1460 break;
1461 case SIOCGRECEIVING:
1462 irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0;
1463 IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __func__
1464 ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving );
1465 break;
1466 default:
1467 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
1468 ret = -EOPNOTSUPP;
1469 }
1470out:
1471 spin_unlock_irqrestore(&self->spinlock, flags);
1472 return ret;
1473
1474}
1475
1476MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
1477MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
1478MODULE_LICENSE("GPL");
1479
1480module_param (max_baud, int, 0);
1481MODULE_PARM_DESC(max_baud, "Maximum baud rate");
1482
1483#ifdef USE_PROBE
1484module_param (do_probe, bool, 0);
1485MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
1486#endif
1487
1488static void
1489toshoboe_close (struct pci_dev *pci_dev)
1490{
1491 int i;
1492 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1493
1494 IRDA_DEBUG (4, "%s()\n", __func__);
1495
1496 IRDA_ASSERT (self != NULL, return; );
1497
1498 if (!self->stopped)
1499 {
1500 toshoboe_stopchip (self);
1501 }
1502
1503 release_region (self->io.fir_base, self->io.fir_ext);
1504
1505 for (i = 0; i < TX_SLOTS; ++i)
1506 {
1507 kfree (self->tx_bufs[i]);
1508 self->tx_bufs[i] = NULL;
1509 }
1510
1511 for (i = 0; i < RX_SLOTS; ++i)
1512 {
1513 kfree (self->rx_bufs[i]);
1514 self->rx_bufs[i] = NULL;
1515 }
1516
1517 unregister_netdev(self->netdev);
1518
1519 kfree (self->ringbuf);
1520 self->ringbuf = NULL;
1521 self->ring = NULL;
1522
1523 free_netdev(self->netdev);
1524}
1525
1526static const struct net_device_ops toshoboe_netdev_ops = {
1527 .ndo_open = toshoboe_net_open,
1528 .ndo_stop = toshoboe_net_close,
1529 .ndo_start_xmit = toshoboe_hard_xmit,
1530 .ndo_do_ioctl = toshoboe_net_ioctl,
1531};
1532
1533static int
1534toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
1535{
1536 struct toshoboe_cb *self;
1537 struct net_device *dev;
1538 int i = 0;
1539 int ok = 0;
1540 int err;
1541
1542 IRDA_DEBUG (4, "%s()\n", __func__);
1543
1544 if ((err=pci_enable_device(pci_dev)))
1545 return err;
1546
1547 dev = alloc_irdadev(sizeof (struct toshoboe_cb));
1548 if (dev == NULL)
1549 {
1550 printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
1551 "IrDA control block\n");
1552 return -ENOMEM;
1553 }
1554
1555 self = netdev_priv(dev);
1556 self->netdev = dev;
1557 self->pdev = pci_dev;
1558 self->base = pci_resource_start(pci_dev,0);
1559
1560 self->io.fir_base = self->base;
1561 self->io.fir_ext = OBOE_IO_EXTENT;
1562 self->io.irq = pci_dev->irq;
1563 self->io.irqflags = IRQF_SHARED | IRQF_DISABLED;
1564
1565 self->speed = self->io.speed = 9600;
1566 self->async = 0;
1567
1568
1569 if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name))
1570 {
1571 printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n"
1572 ,self->io.fir_base);
1573 err = -EBUSY;
1574 goto freeself;
1575 }
1576
1577 spin_lock_init(&self->spinlock);
1578
1579 irda_init_max_qos_capabilies (&self->qos);
1580 self->qos.baud_rate.bits = 0;
1581
1582 if (max_baud >= 2400)
1583 self->qos.baud_rate.bits |= IR_2400;
1584
1585 if (max_baud >= 9600)
1586 self->qos.baud_rate.bits |= IR_9600;
1587 if (max_baud >= 19200)
1588 self->qos.baud_rate.bits |= IR_19200;
1589 if (max_baud >= 115200)
1590 self->qos.baud_rate.bits |= IR_115200;
1591#ifdef USE_MIR
1592 if (max_baud >= 1152000)
1593 {
1594 self->qos.baud_rate.bits |= IR_1152000;
1595 }
1596#endif
1597 if (max_baud >= 4000000)
1598 {
1599 self->qos.baud_rate.bits |= (IR_4000000 << 8);
1600 }
1601
1602
1603 self->qos.min_turn_time.bits = 0xff;
1604
1605 irda_qos_bits_to_value (&self->qos);
1606
1607
1608 self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL);
1609 if (!self->ringbuf)
1610 {
1611 printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
1612 err = -ENOMEM;
1613 goto freeregion;
1614 }
1615
1616#if (BITS_PER_LONG == 64)
1617#error broken on 64-bit: casts pointer to 32-bit, and then back to pointer.
1618#endif
1619
1620
1621 {
1622 unsigned long addr;
1623
1624 addr = (__u32) self->ringbuf;
1625 addr &= ~(OBOE_RING_LEN - 1);
1626 addr += OBOE_RING_LEN;
1627 self->ring = (struct OboeRing *) addr;
1628 }
1629
1630 memset (self->ring, 0, OBOE_RING_LEN);
1631 self->io.mem_base = (__u32) self->ring;
1632
1633 ok = 1;
1634 for (i = 0; i < TX_SLOTS; ++i)
1635 {
1636 self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL);
1637 if (!self->tx_bufs[i])
1638 ok = 0;
1639 }
1640
1641 for (i = 0; i < RX_SLOTS; ++i)
1642 {
1643 self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL);
1644 if (!self->rx_bufs[i])
1645 ok = 0;
1646 }
1647
1648 if (!ok)
1649 {
1650 printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n");
1651 err = -ENOMEM;
1652 goto freebufs;
1653 }
1654
1655
1656#ifdef USE_PROBE
1657 if (do_probe)
1658 if (!toshoboe_probe (self))
1659 {
1660 err = -ENODEV;
1661 goto freebufs;
1662 }
1663#endif
1664
1665 SET_NETDEV_DEV(dev, &pci_dev->dev);
1666 dev->netdev_ops = &toshoboe_netdev_ops;
1667
1668 err = register_netdev(dev);
1669 if (err)
1670 {
1671 printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
1672 err = -ENOMEM;
1673 goto freebufs;
1674 }
1675 printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
1676
1677 pci_set_drvdata(pci_dev,self);
1678
1679 printk (KERN_INFO DRIVER_NAME ": Using multiple tasks\n");
1680
1681 return 0;
1682
1683freebufs:
1684 for (i = 0; i < TX_SLOTS; ++i)
1685 kfree (self->tx_bufs[i]);
1686 for (i = 0; i < RX_SLOTS; ++i)
1687 kfree (self->rx_bufs[i]);
1688 kfree(self->ringbuf);
1689
1690freeregion:
1691 release_region (self->io.fir_base, self->io.fir_ext);
1692
1693freeself:
1694 free_netdev(dev);
1695
1696 return err;
1697}
1698
1699static int
1700toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
1701{
1702 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1703 unsigned long flags;
1704 int i = 10;
1705
1706 IRDA_DEBUG (4, "%s()\n", __func__);
1707
1708 if (!self || self->stopped)
1709 return 0;
1710
1711 if ((!self->irdad) && (!self->async))
1712 return 0;
1713
1714
1715 while ((i--) && (self->txpending))
1716 udelay (10000);
1717
1718 spin_lock_irqsave(&self->spinlock, flags);
1719
1720 toshoboe_stopchip (self);
1721 self->stopped = 1;
1722 self->txpending = 0;
1723
1724 spin_unlock_irqrestore(&self->spinlock, flags);
1725 return 0;
1726}
1727
1728static int
1729toshoboe_wakeup (struct pci_dev *pci_dev)
1730{
1731 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1732 unsigned long flags;
1733
1734 IRDA_DEBUG (4, "%s()\n", __func__);
1735
1736 if (!self || !self->stopped)
1737 return 0;
1738
1739 if ((!self->irdad) && (!self->async))
1740 return 0;
1741
1742 spin_lock_irqsave(&self->spinlock, flags);
1743
1744 toshoboe_startchip (self);
1745 self->stopped = 0;
1746
1747 netif_wake_queue(self->netdev);
1748 spin_unlock_irqrestore(&self->spinlock, flags);
1749 return 0;
1750}
1751
1752static struct pci_driver donauboe_pci_driver = {
1753 .name = "donauboe",
1754 .id_table = toshoboe_pci_tbl,
1755 .probe = toshoboe_open,
1756 .remove = toshoboe_close,
1757 .suspend = toshoboe_gotosleep,
1758 .resume = toshoboe_wakeup
1759};
1760
1761static int __init
1762donauboe_init (void)
1763{
1764 return pci_register_driver(&donauboe_pci_driver);
1765}
1766
1767static void __exit
1768donauboe_cleanup (void)
1769{
1770 pci_unregister_driver(&donauboe_pci_driver);
1771}
1772
1773module_init(donauboe_init);
1774module_exit(donauboe_cleanup);
1775