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