IRQ: Maintain regs pointer globally rather than passing to IRQ handlers
[linux-2.6.git] / drivers / net / irda / donauboe.c
1 /*****************************************************************
2  *
3  * Filename:            donauboe.c
4  * Version:             2.17
5  * Description:   Driver for the Toshiba OBOE (or type-O or 701)
6  *                FIR Chipset, also supports the DONAUOBOE (type-DO
7  *                or d01) FIR chipset which as far as I know is
8  *                register compatible.
9  * Documentation: http://libxg.free.fr/irda/lib-irda.html
10  * Status:        Experimental.
11  * Author:        James McKenzie <james@fishsoup.dhs.org>
12  * Created at:    Sat May 8  12:35:27 1999
13  * Modified:      Paul Bristow <paul.bristow@technologist.com>
14  * Modified:      Mon Nov 11 19:10:05 1999
15  * Modified:      James McKenzie <james@fishsoup.dhs.org>
16  * Modified:      Thu Mar 16 12:49:00 2000 (Substantial rewrite)
17  * Modified:      Sat Apr 29 00:23:03 2000 (Added DONAUOBOE support)
18  * Modified:      Wed May 24 23:45:02 2000 (Fixed chipio_t structure)
19  * Modified: 2.13 Christian Gennerat <christian.gennerat@polytechnique.org>
20  * Modified: 2.13 dim jan 07 21:57:39 2001 (tested with kernel 2.4 & irnet/ppp)
21  * Modified: 2.14 Christian Gennerat <christian.gennerat@polytechnique.org>
22  * Modified: 2.14 lun fev 05 17:55:59 2001 (adapted to patch-2.4.1-pre8-irda1)
23  * Modified: 2.15 Martin Lucina <mato@kotelna.sk>
24  * Modified: 2.15 Fri Jun 21 20:40:59 2002 (sync with 2.4.18, substantial fixes)
25  * Modified: 2.16 Martin Lucina <mato@kotelna.sk>
26  * Modified: 2.16 Sat Jun 22 18:54:29 2002 (fix freeregion, default to verbose)
27  * Modified: 2.17 Christian Gennerat <christian.gennerat@polytechnique.org>
28  * Modified: 2.17 jeu sep 12 08:50:20 2002 (save_flags();cli(); replaced by spinlocks)
29  * Modified: 2.18 Christian Gennerat <christian.gennerat@polytechnique.org>
30  * Modified: 2.18 ven jan 10 03:14:16 2003 Change probe default options
31  *
32  *     Copyright (c) 1999 James McKenzie, All Rights Reserved.
33  *
34  *     This program is free software; you can redistribute it and/or
35  *     modify it under the terms of the GNU General Public License as
36  *     published by the Free Software Foundation; either version 2 of
37  *     the License, or (at your option) any later version.
38  *
39  *     Neither James McKenzie nor Cambridge University admit liability nor
40  *     provide warranty for any of this software. This material is
41  *     provided "AS-IS" and at no charge.
42  *
43  *     Applicable Models : Libretto 100/110CT and many more.
44  *     Toshiba refers to this chip as the type-O IR port,
45  *     or the type-DO IR port.
46  *
47  ********************************************************************/
48
49 /* Look at toshoboe.h (currently in include/net/irda) for details of */
50 /* Where to get documentation on the chip         */
51
52
53 static char *rcsid =
54   "$Id: donauboe.c V2.18 ven jan 10 03:14:16 2003$";
55
56 /* See below for a description of the logic in this driver */
57
58 /* User servicable parts */
59 /* USE_PROBE Create the code which probes the chip and does a few tests */
60 /* do_probe module parameter Enable this code */
61 /* Probe code is very useful for understanding how the hardware works */
62 /* Use it with various combinations of TT_LEN, RX_LEN */
63 /* Strongly recomended, disable if the probe fails on your machine */
64 /* and send me <james@fishsoup.dhs.org> the output of dmesg */
65 #define USE_PROBE 1
66 #undef  USE_PROBE
67
68 /* Trace Transmit ring, interrupts, Receive ring or not ? */
69 #define PROBE_VERBOSE 1
70
71 /* Debug option, examine sent and received raw data */
72 /* Irdadump is better, but does not see all packets. enable it if you want. */
73 #undef DUMP_PACKETS
74
75 /* MIR mode has not been tested. Some behaviour is different */
76 /* Seems to work against an Ericsson R520 for me. -Martin */
77 #define USE_MIR
78
79 /* Schedule back to back hardware transmits wherever possible, otherwise */
80 /* we need an interrupt for every frame, unset if oboe works for a bit and */
81 /* then hangs */
82 #define OPTIMIZE_TX
83
84 /* Set the number of slots in the rings */
85 /* If you get rx/tx fifo overflows at high bitrates, you can try increasing */
86 /* these */
87
88 #define RING_SIZE (OBOE_RING_SIZE_RX8 | OBOE_RING_SIZE_TX8)
89 #define TX_SLOTS    8
90 #define RX_SLOTS    8
91
92
93 /* Less user servicable parts below here */
94
95 /* Test, Transmit and receive buffer sizes, adjust at your peril */
96 /* remarks: nfs usually needs 1k blocks */
97 /* remarks: in SIR mode, CRC is received, -> RX_LEN=TX_LEN+2 */
98 /* remarks: test accepts large blocks. Standard is 0x80 */
99 /* When TT_LEN > RX_LEN (SIR mode) data is stored in successive slots. */
100 /* When 3 or more slots are needed for each test packet, */
101 /* data received in the first slots is overwritten, even */
102 /* if OBOE_CTL_RX_HW_OWNS is not set, without any error! */
103 #define TT_LEN      0x80
104 #define TX_LEN      0xc00
105 #define RX_LEN      0xc04
106 /* Real transmitted length (SIR mode) is about 14+(2%*TX_LEN) more */
107 /* long than user-defined length (see async_wrap_skb) and is less then 4K */
108 /* Real received length is (max RX_LEN) differs from user-defined */
109 /* length only b the CRC (2 or 4 bytes) */
110 #define BUF_SAFETY  0x7a
111 #define RX_BUF_SZ   (RX_LEN)
112 #define TX_BUF_SZ   (TX_LEN+BUF_SAFETY)
113
114
115 /* Logic of the netdev part of this driver                             */
116
117 /* The RX ring is filled with buffers, when a packet arrives           */
118 /* it is DMA'd into the buffer which is marked used and RxDone called  */
119 /* RxDone forms an skb (and checks the CRC if in SIR mode) and ships   */
120 /* the packet off upstairs */
121
122 /* The transmitter on the oboe chip can work in one of two modes       */
123 /* for each ring->tx[] the transmitter can either                      */
124 /* a) transmit the packet, leave the trasmitter enabled and proceed to */
125 /*    the next ring                                                    */
126 /* OR                                                                  */
127 /* b) transmit the packet, switch off the transmitter and issue TxDone */
128
129 /* All packets are entered into the ring in mode b), if the ring was   */
130 /* empty the transmitter is started.                                   */
131
132 /* If OPTIMIZE_TX is defined then in TxDone if the ring contains       */
133 /* more than one packet, all but the last are set to mode a) [HOWEVER  */
134 /* the hardware may not notice this, this is why we start in mode b) ] */
135 /* then restart the transmitter                                        */
136
137 /* If OPTIMIZE_TX is not defined then we just restart the transmitter  */
138 /* if the ring isn't empty */
139
140 /* Speed changes are delayed until the TxRing is empty                 */
141 /* mtt is handled by generating packets with bad CRCs, before the data */
142
143 /* TODO: */
144 /* check the mtt works ok      */
145 /* finish the watchdog         */
146
147 /* No user servicable parts below here */
148
149 #include <linux/module.h>
150
151 #include <linux/kernel.h>
152 #include <linux/types.h>
153 #include <linux/skbuff.h>
154 #include <linux/netdevice.h>
155 #include <linux/ioport.h>
156 #include <linux/delay.h>
157 #include <linux/slab.h>
158 #include <linux/init.h>
159 #include <linux/pci.h>
160 #include <linux/rtnetlink.h>
161
162 #include <asm/system.h>
163 #include <asm/io.h>
164
165 #include <net/irda/wrapper.h>
166 #include <net/irda/irda.h>
167 //#include <net/irda/irmod.h>
168 //#include <net/irda/irlap_frame.h>
169 #include <net/irda/irda_device.h>
170 #include <net/irda/crc.h>
171
172 #include "donauboe.h"
173
174 #define INB(port)       inb_p(port)
175 #define OUTB(val,port)  outb_p(val,port)
176 #define OUTBP(val,port) outb_p(val,port)
177
178 #define PROMPT  OUTB(OBOE_PROMPT_BIT,OBOE_PROMPT);
179
180 #if PROBE_VERBOSE
181 #define PROBE_DEBUG(args...) (printk (args))
182 #else
183 #define PROBE_DEBUG(args...) ;
184 #endif
185
186 /* Set the DMA to be byte at a time */
187 #define CONFIG0H_DMA_OFF OBOE_CONFIG0H_RCVANY
188 #define CONFIG0H_DMA_ON_NORX CONFIG0H_DMA_OFF| OBOE_CONFIG0H_ENDMAC
189 #define CONFIG0H_DMA_ON CONFIG0H_DMA_ON_NORX | OBOE_CONFIG0H_ENRX
190
191 static struct pci_device_id toshoboe_pci_tbl[] = {
192         { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },
193         { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIRD01, PCI_ANY_ID, PCI_ANY_ID, },
194         { }                     /* Terminating entry */
195 };
196 MODULE_DEVICE_TABLE(pci, toshoboe_pci_tbl);
197
198 #define DRIVER_NAME "toshoboe"
199 static char *driver_name = DRIVER_NAME;
200
201 static int max_baud = 4000000;
202 #ifdef USE_PROBE
203 static int do_probe = 0;
204 #endif
205
206
207 /**********************************************************************/
208 static int
209 toshoboe_checkfcs (unsigned char *buf, int len)
210 {
211   int i;
212   union
213   {
214     __u16 value;
215     __u8 bytes[2];
216   }
217   fcs;
218
219   fcs.value = INIT_FCS;
220
221   for (i = 0; i < len; ++i)
222     fcs.value = irda_fcs (fcs.value, *(buf++));
223
224   return (fcs.value == GOOD_FCS);
225 }
226
227 /***********************************************************************/
228 /* Generic chip handling code */
229 #ifdef DUMP_PACKETS
230 static unsigned char dump[50];
231 static void
232 _dumpbufs (unsigned char *data, int len, char tete)
233 {
234 int i,j;
235 char head=tete;
236 for (i=0;i<len;i+=16) {
237     for (j=0;j<16 && i+j<len;j++) { sprintf(&dump[3*j],"%02x.",data[i+j]); }
238     dump [3*j]=0;
239     IRDA_DEBUG (2, "%c%s\n",head , dump);
240     head='+';
241     }
242 }
243 #endif
244
245 #ifdef USE_PROBE
246 /* Dump the registers */
247 static void
248 toshoboe_dumpregs (struct toshoboe_cb *self)
249 {
250   __u32 ringbase;
251
252   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
253
254   ringbase = INB (OBOE_RING_BASE0) << 10;
255   ringbase |= INB (OBOE_RING_BASE1) << 18;
256   ringbase |= INB (OBOE_RING_BASE2) << 26;
257
258   printk (KERN_ERR DRIVER_NAME ": Register dump:\n");
259   printk (KERN_ERR "Interrupts: Tx:%d Rx:%d TxUnder:%d RxOver:%d Sip:%d\n",
260           self->int_tx, self->int_rx, self->int_txunder, self->int_rxover,
261           self->int_sip);
262   printk (KERN_ERR "RX %02x TX %02x RingBase %08x\n",
263           INB (OBOE_RXSLOT), INB (OBOE_TXSLOT), ringbase);
264   printk (KERN_ERR "RING_SIZE %02x IER %02x ISR %02x\n",
265           INB (OBOE_RING_SIZE), INB (OBOE_IER), INB (OBOE_ISR));
266   printk (KERN_ERR "CONFIG1 %02x STATUS %02x\n",
267           INB (OBOE_CONFIG1), INB (OBOE_STATUS));
268   printk (KERN_ERR "CONFIG0 %02x%02x ENABLE %02x%02x\n",
269           INB (OBOE_CONFIG0H), INB (OBOE_CONFIG0L),
270           INB (OBOE_ENABLEH), INB (OBOE_ENABLEL));
271   printk (KERN_ERR "NEW_PCONFIG %02x%02x CURR_PCONFIG %02x%02x\n",
272           INB (OBOE_NEW_PCONFIGH), INB (OBOE_NEW_PCONFIGL),
273           INB (OBOE_CURR_PCONFIGH), INB (OBOE_CURR_PCONFIGL));
274   printk (KERN_ERR "MAXLEN %02x%02x RXCOUNT %02x%02x\n",
275           INB (OBOE_MAXLENH), INB (OBOE_MAXLENL),
276           INB (OBOE_RXCOUNTL), INB (OBOE_RXCOUNTH));
277
278   if (self->ring)
279     {
280       int i;
281       ringbase = virt_to_bus (self->ring);
282       printk (KERN_ERR "Ring at %08x:\n", ringbase);
283       printk (KERN_ERR "RX:");
284       for (i = 0; i < RX_SLOTS; ++i)
285         printk (" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
286       printk ("\n");
287       printk (KERN_ERR "TX:");
288       for (i = 0; i < RX_SLOTS; ++i)
289         printk (" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
290       printk ("\n");
291     }
292 }
293 #endif
294
295 /*Don't let the chip look at memory */
296 static void
297 toshoboe_disablebm (struct toshoboe_cb *self)
298 {
299   __u8 command;
300   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
301
302   pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
303   command &= ~PCI_COMMAND_MASTER;
304   pci_write_config_byte (self->pdev, PCI_COMMAND, command);
305
306 }
307
308 /* Shutdown the chip and point the taskfile reg somewhere else */
309 static void
310 toshoboe_stopchip (struct toshoboe_cb *self)
311 {
312   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
313
314   /*Disable interrupts */
315   OUTB (0x0, OBOE_IER);
316   /*Disable DMA, Disable Rx, Disable Tx */
317   OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
318   /*Disable SIR MIR FIR, Tx and Rx */
319   OUTB (0x00, OBOE_ENABLEH);
320   /*Point the ring somewhere safe */
321   OUTB (0x3f, OBOE_RING_BASE2);
322   OUTB (0xff, OBOE_RING_BASE1);
323   OUTB (0xff, OBOE_RING_BASE0);
324
325   OUTB (RX_LEN >> 8, OBOE_MAXLENH);
326   OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
327
328   /*Acknoledge any pending interrupts */
329   OUTB (0xff, OBOE_ISR);
330
331   /*Why */
332   OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
333
334   /*switch it off */
335   OUTB (OBOE_CONFIG1_OFF, OBOE_CONFIG1);
336
337   toshoboe_disablebm (self);
338 }
339
340 /* Transmitter initialization */
341 static void
342 toshoboe_start_DMA (struct toshoboe_cb *self, int opts)
343 {
344   OUTB (0x0, OBOE_ENABLEH);
345   OUTB (CONFIG0H_DMA_ON | opts,  OBOE_CONFIG0H);
346   OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
347   PROMPT;
348 }
349
350 /*Set the baud rate */
351 static void
352 toshoboe_setbaud (struct toshoboe_cb *self)
353 {
354   __u16 pconfig = 0;
355   __u8 config0l = 0;
356
357   IRDA_DEBUG (2, "%s(%d/%d)\n", __FUNCTION__, self->speed, self->io.speed);
358
359   switch (self->speed)
360     {
361     case 2400:
362     case 4800:
363     case 9600:
364     case 19200:
365     case 38400:
366     case 57600:
367     case 115200:
368 #ifdef USE_MIR
369     case 1152000:
370 #endif
371     case 4000000:
372       break;
373     default:
374
375       printk (KERN_ERR DRIVER_NAME ": switch to unsupported baudrate %d\n",
376               self->speed);
377       return;
378     }
379
380   switch (self->speed)
381     {
382       /* For SIR the preamble is done by adding XBOFs */
383       /* to the packet */
384       /* set to filtered SIR mode, filter looks for BOF and EOF */
385     case 2400:
386       pconfig |= 47 << OBOE_PCONFIG_BAUDSHIFT;
387       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
388       break;
389     case 4800:
390       pconfig |= 23 << OBOE_PCONFIG_BAUDSHIFT;
391       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
392       break;
393     case 9600:
394       pconfig |= 11 << OBOE_PCONFIG_BAUDSHIFT;
395       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
396       break;
397     case 19200:
398       pconfig |= 5 << OBOE_PCONFIG_BAUDSHIFT;
399       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
400       break;
401     case 38400:
402       pconfig |= 2 << OBOE_PCONFIG_BAUDSHIFT;
403       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
404       break;
405     case 57600:
406       pconfig |= 1 << OBOE_PCONFIG_BAUDSHIFT;
407       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
408       break;
409     case 115200:
410       pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
411       pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
412       break;
413     default:
414       /*Set to packet based reception */
415       OUTB (RX_LEN >> 8, OBOE_MAXLENH);
416       OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
417       break;
418     }
419
420   switch (self->speed)
421     {
422     case 2400:
423     case 4800:
424     case 9600:
425     case 19200:
426     case 38400:
427     case 57600:
428     case 115200:
429       config0l = OBOE_CONFIG0L_ENSIR;
430       if (self->async)
431         {
432           /*Set to character based reception */
433           /*System will lock if MAXLEN=0 */
434           /*so have to be careful */
435           OUTB (0x01, OBOE_MAXLENH);
436           OUTB (0x01, OBOE_MAXLENL);
437           OUTB (0x00, OBOE_MAXLENH);
438         }
439       else
440         {
441           /*Set to packet based reception */
442           config0l |= OBOE_CONFIG0L_ENSIRF;
443           OUTB (RX_LEN >> 8, OBOE_MAXLENH);
444           OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
445         }
446       break;
447
448 #ifdef USE_MIR
449       /* MIR mode */
450       /* Set for 16 bit CRC and enable MIR */
451       /* Preamble now handled by the chip */
452     case 1152000:
453       pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
454       pconfig |= 8 << OBOE_PCONFIG_WIDTHSHIFT;
455       pconfig |= 1 << OBOE_PCONFIG_PREAMBLESHIFT;
456       config0l = OBOE_CONFIG0L_CRC16 | OBOE_CONFIG0L_ENMIR;
457       break;
458 #endif
459       /* FIR mode */
460       /* Set for 32 bit CRC and enable FIR */
461       /* Preamble handled by the chip */
462     case 4000000:
463       pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
464       /* Documentation says 14, but toshiba use 15 in their drivers */
465       pconfig |= 15 << OBOE_PCONFIG_PREAMBLESHIFT;
466       config0l = OBOE_CONFIG0L_ENFIR;
467       break;
468     }
469
470   /* Copy into new PHY config buffer */
471   OUTBP (pconfig >> 8, OBOE_NEW_PCONFIGH);
472   OUTB (pconfig & 0xff, OBOE_NEW_PCONFIGL);
473   OUTB (config0l, OBOE_CONFIG0L);
474
475   /* Now make OBOE copy from new PHY to current PHY */
476   OUTB (0x0, OBOE_ENABLEH);
477   OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
478   PROMPT;
479
480   /* speed change executed */
481   self->new_speed = 0;
482   self->io.speed = self->speed;
483 }
484
485 /*Let the chip look at memory */
486 static void
487 toshoboe_enablebm (struct toshoboe_cb *self)
488 {
489   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
490   pci_set_master (self->pdev);
491 }
492
493 /*setup the ring */
494 static void
495 toshoboe_initring (struct toshoboe_cb *self)
496 {
497   int i;
498
499   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
500
501   for (i = 0; i < TX_SLOTS; ++i)
502     {
503       self->ring->tx[i].len = 0;
504       self->ring->tx[i].control = 0x00;
505       self->ring->tx[i].address = virt_to_bus (self->tx_bufs[i]);
506     }
507
508   for (i = 0; i < RX_SLOTS; ++i)
509     {
510       self->ring->rx[i].len = RX_LEN;
511       self->ring->rx[i].len = 0;
512       self->ring->rx[i].address = virt_to_bus (self->rx_bufs[i]);
513       self->ring->rx[i].control = OBOE_CTL_RX_HW_OWNS;
514     }
515 }
516
517 static void
518 toshoboe_resetptrs (struct toshoboe_cb *self)
519 {
520   /* Can reset pointers by twidling DMA */
521   OUTB (0x0, OBOE_ENABLEH);
522   OUTBP (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
523   OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
524
525   self->rxs = inb_p (OBOE_RXSLOT) & OBOE_SLOT_MASK;
526   self->txs = inb_p (OBOE_TXSLOT) & OBOE_SLOT_MASK;
527 }
528
529 /* Called in locked state */
530 static void
531 toshoboe_initptrs (struct toshoboe_cb *self)
532 {
533
534   /* spin_lock_irqsave(self->spinlock, flags); */
535   /* save_flags (flags); */
536
537   /* Can reset pointers by twidling DMA */
538   toshoboe_resetptrs (self);
539
540   OUTB (0x0, OBOE_ENABLEH);
541   OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
542   OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
543
544   self->txpending = 0;
545
546   /* spin_unlock_irqrestore(self->spinlock, flags); */
547   /* restore_flags (flags); */
548 }
549
550 /* Wake the chip up and get it looking at the rings */
551 /* Called in locked state */
552 static void
553 toshoboe_startchip (struct toshoboe_cb *self)
554 {
555   __u32 physaddr;
556
557   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
558
559   toshoboe_initring (self);
560   toshoboe_enablebm (self);
561   OUTBP (OBOE_CONFIG1_RESET, OBOE_CONFIG1);
562   OUTBP (OBOE_CONFIG1_ON, OBOE_CONFIG1);
563
564   /* Stop the clocks */
565   OUTB (0, OBOE_ENABLEH);
566
567   /*Set size of rings */
568   OUTB (RING_SIZE, OBOE_RING_SIZE);
569
570   /*Acknoledge any pending interrupts */
571   OUTB (0xff, OBOE_ISR);
572
573   /*Enable ints */
574   OUTB (OBOE_INT_TXDONE  | OBOE_INT_RXDONE |
575         OBOE_INT_TXUNDER | OBOE_INT_RXOVER | OBOE_INT_SIP , OBOE_IER);
576
577   /*Acknoledge any pending interrupts */
578   OUTB (0xff, OBOE_ISR);
579
580   /*Set the maximum packet length to 0xfff (4095) */
581   OUTB (RX_LEN >> 8, OBOE_MAXLENH);
582   OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
583
584   /*Shutdown DMA */
585   OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
586
587   /*Find out where the rings live */
588   physaddr = virt_to_bus (self->ring);
589
590   IRDA_ASSERT ((physaddr & 0x3ff) == 0,
591                printk (KERN_ERR DRIVER_NAME "ring not correctly aligned\n");
592                return;);
593
594   OUTB ((physaddr >> 10) & 0xff, OBOE_RING_BASE0);
595   OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);
596   OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);
597
598   /*Enable DMA controler in byte mode and RX */
599   OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
600
601   /* Start up the clocks */
602   OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
603
604   /*set to sensible speed */
605   self->speed = 9600;
606   toshoboe_setbaud (self);
607   toshoboe_initptrs (self);
608 }
609
610 static void
611 toshoboe_isntstuck (struct toshoboe_cb *self)
612 {
613 }
614
615 static void
616 toshoboe_checkstuck (struct toshoboe_cb *self)
617 {
618   unsigned long flags;
619
620   if (0)
621     {
622       spin_lock_irqsave(&self->spinlock, flags);
623
624       /* This will reset the chip completely */
625       printk (KERN_ERR DRIVER_NAME ": Resetting chip\n");
626
627       toshoboe_stopchip (self);
628       toshoboe_startchip (self);
629       spin_unlock_irqrestore(&self->spinlock, flags);
630     }
631 }
632
633 /*Generate packet of about mtt us long */
634 static int
635 toshoboe_makemttpacket (struct toshoboe_cb *self, void *buf, int mtt)
636 {
637   int xbofs;
638
639   xbofs = ((int) (mtt/100)) * (int) (self->speed);
640   xbofs=xbofs/80000; /*Eight bits per byte, and mtt is in us*/
641   xbofs++;
642
643   IRDA_DEBUG (2, DRIVER_NAME
644       ": generated mtt of %d bytes for %d us at %d baud\n"
645           , xbofs,mtt,self->speed);
646
647   if (xbofs > TX_LEN)
648     {
649       printk (KERN_ERR DRIVER_NAME ": wanted %d bytes MTT but TX_LEN is %d\n",
650               xbofs, TX_LEN);
651       xbofs = TX_LEN;
652     }
653
654   /*xbofs will do for SIR, MIR and FIR,SIR mode doesn't generate a checksum anyway */
655   memset (buf, XBOF, xbofs);
656
657   return xbofs;
658 }
659
660 static int toshoboe_invalid_dev(int irq)
661 {
662   printk (KERN_WARNING DRIVER_NAME ": irq %d for unknown device.\n", irq);
663   return 1;
664 }
665
666 #ifdef USE_PROBE
667 /***********************************************************************/
668 /* Probe code */
669
670 static void
671 toshoboe_dumptx (struct toshoboe_cb *self)
672 {
673   int i;
674   PROBE_DEBUG(KERN_WARNING "TX:");
675   for (i = 0; i < RX_SLOTS; ++i)
676     PROBE_DEBUG(" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
677   PROBE_DEBUG(" [%d]\n",self->speed);
678 }
679
680 static void
681 toshoboe_dumprx (struct toshoboe_cb *self, int score)
682 {
683   int i;
684   PROBE_DEBUG(" %d\nRX:",score);
685   for (i = 0; i < RX_SLOTS; ++i)
686     PROBE_DEBUG(" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
687   PROBE_DEBUG("\n");
688 }
689
690 static inline int
691 stuff_byte (__u8 byte, __u8 * buf)
692 {
693   switch (byte)
694     {
695     case BOF:                  /* FALLTHROUGH */
696     case EOF:                  /* FALLTHROUGH */
697     case CE:
698       /* Insert transparently coded */
699       buf[0] = CE;              /* Send link escape */
700       buf[1] = byte ^ IRDA_TRANS; /* Complement bit 5 */
701       return 2;
702       /* break; */
703     default:
704       /* Non-special value, no transparency required */
705       buf[0] = byte;
706       return 1;
707       /* break; */
708     }
709 }
710
711 static irqreturn_t
712 toshoboe_probeinterrupt (int irq, void *dev_id)
713 {
714   struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
715   __u8 irqstat;
716
717   if (self == NULL && toshoboe_invalid_dev(irq))
718     return IRQ_NONE;
719
720   irqstat = INB (OBOE_ISR);
721
722 /* was it us */
723   if (!(irqstat & OBOE_INT_MASK))
724     return IRQ_NONE;
725
726 /* Ack all the interrupts */
727   OUTB (irqstat, OBOE_ISR);
728
729   if (irqstat & OBOE_INT_TXDONE)
730     {
731       int txp;
732
733       self->int_tx++;
734       PROBE_DEBUG("T");
735
736       txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
737       if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
738         {
739           self->int_tx+=100;
740           PROBE_DEBUG("S");
741           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
742         }
743     }
744
745   if (irqstat & OBOE_INT_RXDONE) {
746     self->int_rx++;
747     PROBE_DEBUG("R"); }
748   if (irqstat & OBOE_INT_TXUNDER) {
749     self->int_txunder++;
750     PROBE_DEBUG("U"); }
751   if (irqstat & OBOE_INT_RXOVER) {
752     self->int_rxover++;
753     PROBE_DEBUG("O"); }
754   if (irqstat & OBOE_INT_SIP) {
755     self->int_sip++;
756     PROBE_DEBUG("I"); }
757   return IRQ_HANDLED;
758 }
759
760 static int
761 toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir)
762 {
763   int i;
764   int len = 0;
765   union
766   {
767     __u16 value;
768     __u8 bytes[2];
769   }
770   fcs;
771
772   if (fir)
773     {
774       memset (buf, 0, TT_LEN);
775       return (TT_LEN);
776     }
777
778   fcs.value = INIT_FCS;
779
780   memset (buf, XBOF, 10);
781   len += 10;
782   buf[len++] = BOF;
783
784   for (i = 0; i < TT_LEN; ++i)
785     {
786       len += stuff_byte (i, buf + len);
787       fcs.value = irda_fcs (fcs.value, i);
788     }
789
790   len += stuff_byte (fcs.bytes[0] ^ badcrc, buf + len);
791   len += stuff_byte (fcs.bytes[1] ^ badcrc, buf + len);
792   buf[len++] = EOF;
793   len++;
794   return len;
795 }
796
797 static int
798 toshoboe_probefail (struct toshoboe_cb *self, char *msg)
799 {
800   printk (KERN_ERR DRIVER_NAME "probe(%d) failed %s\n",self-> speed, msg);
801   toshoboe_dumpregs (self);
802   toshoboe_stopchip (self);
803   free_irq (self->io.irq, (void *) self);
804   return 0;
805 }
806
807 static int
808 toshoboe_numvalidrcvs (struct toshoboe_cb *self)
809 {
810   int i, ret = 0;
811   for (i = 0; i < RX_SLOTS; ++i)
812     if ((self->ring->rx[i].control & 0xe0) == 0)
813       ret++;
814
815   return ret;
816 }
817
818 static int
819 toshoboe_numrcvs (struct toshoboe_cb *self)
820 {
821   int i, ret = 0;
822   for (i = 0; i < RX_SLOTS; ++i)
823     if (!(self->ring->rx[i].control & OBOE_CTL_RX_HW_OWNS))
824       ret++;
825
826   return ret;
827 }
828
829 static int
830 toshoboe_probe (struct toshoboe_cb *self)
831 {
832   int i, j, n;
833 #ifdef USE_MIR
834   int bauds[] = { 9600, 115200, 4000000, 1152000 };
835 #else
836   int bauds[] = { 9600, 115200, 4000000 };
837 #endif
838   unsigned long flags;
839
840   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
841
842   if (request_irq (self->io.irq, toshoboe_probeinterrupt,
843                    self->io.irqflags, "toshoboe", (void *) self))
844     {
845       printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n",
846               self->io.irq);
847       return 0;
848     }
849
850   /* test 1: SIR filter and back to back */
851
852   for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j)
853     {
854       int fir = (j > 1);
855       toshoboe_stopchip (self);
856
857
858       spin_lock_irqsave(&self->spinlock, flags);
859       /*Address is already setup */
860       toshoboe_startchip (self);
861       self->int_rx = self->int_tx = 0;
862       self->speed = bauds[j];
863       toshoboe_setbaud (self);
864       toshoboe_initptrs (self);
865       spin_unlock_irqrestore(&self->spinlock, flags);
866
867       self->ring->tx[self->txs].control =
868 /*   (FIR only) OBOE_CTL_TX_SIP needed for switching to next slot */
869 /*    MIR: all received data is stored in one slot */
870         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
871               : OBOE_CTL_TX_HW_OWNS ;
872       self->ring->tx[self->txs].len =
873         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
874       self->txs++;
875       self->txs %= TX_SLOTS;
876
877       self->ring->tx[self->txs].control =
878         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_SIP
879               : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
880       self->ring->tx[self->txs].len =
881         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
882       self->txs++;
883       self->txs %= TX_SLOTS;
884
885       self->ring->tx[self->txs].control =
886         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
887               : OBOE_CTL_TX_HW_OWNS ;
888       self->ring->tx[self->txs].len =
889         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
890       self->txs++;
891       self->txs %= TX_SLOTS;
892
893       self->ring->tx[self->txs].control =
894         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
895               | OBOE_CTL_TX_SIP     | OBOE_CTL_TX_BAD_CRC
896               : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
897       self->ring->tx[self->txs].len =
898         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
899       self->txs++;
900       self->txs %= TX_SLOTS;
901
902       toshoboe_dumptx (self);
903       /* Turn on TX and RX and loopback */
904       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
905
906       i = 0;
907       n = fir ? 1 : 4;
908       while (toshoboe_numvalidrcvs (self) != n)
909         {
910           if (i > 4800)
911               return toshoboe_probefail (self, "filter test");
912           udelay ((9600*(TT_LEN+16))/self->speed);
913           i++;
914         }
915
916       n = fir ? 203 : 102;
917       while ((toshoboe_numrcvs(self) != self->int_rx) || (self->int_tx != n))
918         {
919           if (i > 4800)
920               return toshoboe_probefail (self, "interrupt test");
921           udelay ((9600*(TT_LEN+16))/self->speed);
922           i++;
923         }
924      toshoboe_dumprx (self,i);
925
926      }
927
928   /* test 2: SIR in char at a time */
929
930   toshoboe_stopchip (self);
931   self->int_rx = self->int_tx = 0;
932
933   spin_lock_irqsave(&self->spinlock, flags);
934   toshoboe_startchip (self);
935   spin_unlock_irqrestore(&self->spinlock, flags);
936
937   self->async = 1;
938   self->speed = 115200;
939   toshoboe_setbaud (self);
940   self->ring->tx[self->txs].control =
941     OBOE_CTL_TX_RTCENTX | OBOE_CTL_TX_HW_OWNS;
942   self->ring->tx[self->txs].len = 4;
943
944   ((unsigned char *) self->tx_bufs[self->txs])[0] = 'f';
945   ((unsigned char *) self->tx_bufs[self->txs])[1] = 'i';
946   ((unsigned char *) self->tx_bufs[self->txs])[2] = 's';
947   ((unsigned char *) self->tx_bufs[self->txs])[3] = 'h';
948   toshoboe_dumptx (self);
949   toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
950
951   i = 0;
952   while (toshoboe_numvalidrcvs (self) != 4)
953     {
954       if (i > 100)
955           return toshoboe_probefail (self, "Async test");
956       udelay (100);
957       i++;
958     }
959
960   while ((toshoboe_numrcvs (self) != self->int_rx) || (self->int_tx != 1))
961     {
962       if (i > 100)
963           return toshoboe_probefail (self, "Async interrupt test");
964       udelay (100);
965       i++;
966     }
967   toshoboe_dumprx (self,i);
968
969   self->async = 0;
970   self->speed = 9600;
971   toshoboe_setbaud (self);
972   toshoboe_stopchip (self);
973
974   free_irq (self->io.irq, (void *) self);
975
976   printk (KERN_WARNING DRIVER_NAME ": Self test passed ok\n");
977
978   return 1;
979 }
980 #endif
981
982 /******************************************************************/
983 /* Netdev style code */
984
985 /* Transmit something */
986 static int
987 toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
988 {
989   struct toshoboe_cb *self;
990   __s32 speed;
991   int mtt, len, ctl;
992   unsigned long flags;
993   struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
994
995   self = (struct toshoboe_cb *) dev->priv;
996
997   IRDA_ASSERT (self != NULL, return 0; );
998
999   IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __FUNCTION__
1000       ,skb->len,self->txpending,INB (OBOE_ENABLEH));
1001   if (!cb->magic) {
1002       IRDA_DEBUG (2, "%s.Not IrLAP:%x\n", __FUNCTION__, cb->magic);
1003 #ifdef DUMP_PACKETS
1004       _dumpbufs(skb->data,skb->len,'>');
1005 #endif
1006     }
1007
1008   /* change speed pending, wait for its execution */
1009   if (self->new_speed)
1010       return -EBUSY;
1011
1012   /* device stopped (apm) wait for restart */
1013   if (self->stopped)
1014       return -EBUSY;
1015
1016   toshoboe_checkstuck (self);
1017
1018   dev->trans_start = jiffies;
1019
1020  /* Check if we need to change the speed */
1021   /* But not now. Wait after transmission if mtt not required */
1022   speed=irda_get_next_speed(skb);
1023   if ((speed != self->io.speed) && (speed != -1))
1024     {
1025       spin_lock_irqsave(&self->spinlock, flags);
1026
1027       if (self->txpending || skb->len)
1028         {
1029           self->new_speed = speed;
1030           IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" ,
1031                       __FUNCTION__, speed);
1032           /* if no data, that's all! */
1033           if (!skb->len)
1034             {
1035               spin_unlock_irqrestore(&self->spinlock, flags);
1036               dev_kfree_skb (skb);
1037               return 0;
1038             }
1039           /* True packet, go on, but */
1040           /* do not accept anything before change speed execution */
1041           netif_stop_queue(dev);
1042           /* ready to process TxDone interrupt */
1043           spin_unlock_irqrestore(&self->spinlock, flags);
1044         }
1045       else
1046         {
1047           /* idle and no data, change speed now */
1048           self->speed = speed;
1049           toshoboe_setbaud (self);
1050           spin_unlock_irqrestore(&self->spinlock, flags);
1051           dev_kfree_skb (skb);
1052           return 0;
1053         }
1054
1055     }
1056
1057   if ((mtt = irda_get_mtt(skb)))
1058     {
1059       /* This is fair since the queue should be empty anyway */
1060       spin_lock_irqsave(&self->spinlock, flags);
1061
1062       if (self->txpending)
1063         {
1064           spin_unlock_irqrestore(&self->spinlock, flags);
1065           return -EBUSY;
1066         }
1067
1068       /* If in SIR mode we need to generate a string of XBOFs */
1069       /* In MIR and FIR we need to generate a string of data */
1070       /* which we will add a wrong checksum to */
1071
1072       mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt);
1073       IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __FUNCTION__
1074           ,skb->len,mtt,self->txpending);
1075       if (mtt)
1076         {
1077           self->ring->tx[self->txs].len = mtt & 0xfff;
1078
1079           ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1080           if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1081             {
1082               ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ;
1083             }
1084 #ifdef USE_MIR
1085           else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON)
1086             {
1087               ctl |= OBOE_CTL_TX_BAD_CRC;
1088             }
1089 #endif
1090           self->ring->tx[self->txs].control = ctl;
1091
1092           OUTB (0x0, OBOE_ENABLEH);
1093           /* It is only a timer. Do not send mtt packet outside! */
1094           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
1095
1096           self->txpending++;
1097
1098           self->txs++;
1099           self->txs %= TX_SLOTS;
1100
1101         }
1102       else
1103         {
1104           printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n");
1105         }
1106       spin_unlock_irqrestore(&self->spinlock, flags);
1107     }
1108
1109 #ifdef DUMP_PACKETS
1110 dumpbufs(skb->data,skb->len,'>');
1111 #endif
1112
1113   spin_lock_irqsave(&self->spinlock, flags);
1114
1115   if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS)
1116     {
1117       IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __FUNCTION__
1118           ,skb->len, self->ring->tx[self->txs].control, self->txpending);
1119       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1120       spin_unlock_irqrestore(&self->spinlock, flags);
1121       return -EBUSY;
1122     }
1123
1124   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
1125     {
1126       len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ);
1127     }
1128   else
1129     {
1130       len = skb->len;
1131       memcpy (self->tx_bufs[self->txs], skb->data, len);
1132     }
1133   self->ring->tx[self->txs].len = len & 0x0fff;
1134
1135   /*Sometimes the HW doesn't see us assert RTCENTX in the interrupt code */
1136   /*later this plays safe, we garuntee the last packet to be transmitted */
1137   /*has RTCENTX set */
1138
1139   ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1140   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1141     {
1142       ctl |= OBOE_CTL_TX_SIP ;
1143     }
1144   self->ring->tx[self->txs].control = ctl;
1145
1146   /* If transmitter is idle start in one-shot mode */
1147
1148   if (!self->txpending)
1149       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1150
1151   self->txpending++;
1152
1153   self->txs++;
1154   self->txs %= TX_SLOTS;
1155
1156   spin_unlock_irqrestore(&self->spinlock, flags);
1157   dev_kfree_skb (skb);
1158
1159   return 0;
1160 }
1161
1162 /*interrupt handler */
1163 static irqreturn_t
1164 toshoboe_interrupt (int irq, void *dev_id)
1165 {
1166   struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
1167   __u8 irqstat;
1168   struct sk_buff *skb = NULL;
1169
1170   if (self == NULL && toshoboe_invalid_dev(irq))
1171     return IRQ_NONE;
1172
1173   irqstat = INB (OBOE_ISR);
1174
1175 /* was it us */
1176   if (!(irqstat & OBOE_INT_MASK))
1177       return IRQ_NONE;
1178
1179 /* Ack all the interrupts */
1180   OUTB (irqstat, OBOE_ISR);
1181
1182   toshoboe_isntstuck (self);
1183
1184 /* Txdone */
1185   if (irqstat & OBOE_INT_TXDONE)
1186     {
1187       int txp, txpc;
1188       int i;
1189
1190       txp = self->txpending;
1191       self->txpending = 0;
1192
1193       for (i = 0; i < TX_SLOTS; ++i)
1194         {
1195           if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS)
1196               self->txpending++;
1197         }
1198       IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __FUNCTION__
1199           ,irqstat,txp,self->txpending);
1200
1201       txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
1202
1203       /* Got anything queued ? start it together */
1204       if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
1205         {
1206           txpc = txp;
1207 #ifdef OPTIMIZE_TX
1208           while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1209             {
1210               txp = txpc;
1211               txpc++;
1212               txpc %= TX_SLOTS;
1213               self->stats.tx_packets++;
1214               if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1215                   self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
1216             }
1217           self->stats.tx_packets--;
1218 #else
1219           self->stats.tx_packets++;
1220 #endif
1221           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1222         }
1223
1224       if ((!self->txpending) && (self->new_speed))
1225         {
1226           self->speed = self->new_speed;
1227           IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n",
1228                       __FUNCTION__, self->speed);
1229           toshoboe_setbaud (self);
1230         }
1231
1232       /* Tell network layer that we want more frames */
1233       if (!self->new_speed)
1234           netif_wake_queue(self->netdev);
1235     }
1236
1237   if (irqstat & OBOE_INT_RXDONE)
1238     {
1239       while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS))
1240         {
1241           int len = self->ring->rx[self->rxs].len;
1242           skb = NULL;
1243           IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __FUNCTION__
1244                       ,len,self->ring->rx[self->rxs].control);
1245
1246 #ifdef DUMP_PACKETS
1247 dumpbufs(self->rx_bufs[self->rxs],len,'<');
1248 #endif
1249
1250           if (self->ring->rx[self->rxs].control == 0)
1251             {
1252               __u8 enable = INB (OBOE_ENABLEH);
1253
1254               /* In SIR mode we need to check the CRC as this */
1255               /* hasn't been done by the hardware */
1256               if (enable & OBOE_ENABLEH_SIRON)
1257                 {
1258                   if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len))
1259                       len = 0;
1260                   /*Trim off the CRC */
1261                   if (len > 1)
1262                       len -= 2;
1263                   else
1264                       len = 0;
1265                   IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __FUNCTION__, len,enable);
1266                 }
1267
1268 #ifdef USE_MIR
1269               else if (enable & OBOE_ENABLEH_MIRON)
1270                 {
1271                   if (len > 1)
1272                       len -= 2;
1273                   else
1274                       len = 0;
1275                   IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __FUNCTION__, len,enable);
1276                 }
1277 #endif
1278               else if (enable & OBOE_ENABLEH_FIRON)
1279                 {
1280                   if (len > 3)
1281                       len -= 4;   /*FIXME: check this */
1282                   else
1283                       len = 0;
1284                   IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __FUNCTION__, len,enable);
1285                 }
1286               else
1287                   IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __FUNCTION__, len,enable);
1288
1289               if (len)
1290                 {
1291                   skb = dev_alloc_skb (len + 1);
1292                   if (skb)
1293                     {
1294                       skb_reserve (skb, 1);
1295
1296                       skb_put (skb, len);
1297                       memcpy (skb->data, self->rx_bufs[self->rxs], len);
1298
1299                       self->stats.rx_packets++;
1300                       skb->dev = self->netdev;
1301                       skb->mac.raw = skb->data;
1302                       skb->protocol = htons (ETH_P_IRDA);
1303                     }
1304                   else
1305                     {
1306                       printk (KERN_INFO
1307                               "%s(), memory squeeze, dropping frame.\n",
1308                               __FUNCTION__);
1309                     }
1310                 }
1311             }
1312           else
1313             {
1314             /* TODO: =========================================== */
1315             /*  if OBOE_CTL_RX_LENGTH, our buffers are too small */
1316             /* (MIR or FIR) data is lost. */
1317             /* (SIR) data is splitted in several slots. */
1318             /* we have to join all the received buffers received */
1319             /*in a large buffer before checking CRC. */
1320             IRDA_DEBUG (0, "%s.err:%x(%x)\n", __FUNCTION__
1321                 ,len,self->ring->rx[self->rxs].control);
1322             }
1323
1324           self->ring->rx[self->rxs].len = 0x0;
1325           self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS;
1326
1327           self->rxs++;
1328           self->rxs %= RX_SLOTS;
1329
1330           if (skb)
1331               netif_rx (skb);
1332
1333         }
1334     }
1335
1336   if (irqstat & OBOE_INT_TXUNDER)
1337     {
1338       printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n");
1339     }
1340   if (irqstat & OBOE_INT_RXOVER)
1341     {
1342       printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n");
1343     }
1344 /* This must be useful for something... */
1345   if (irqstat & OBOE_INT_SIP)
1346     {
1347       self->int_sip++;
1348       IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __FUNCTION__
1349               ,self->int_sip,irqstat,self->txpending);
1350     }
1351   return IRQ_HANDLED;
1352 }
1353
1354
1355 static int
1356 toshoboe_net_open (struct net_device *dev)
1357 {
1358   struct toshoboe_cb *self;
1359   unsigned long flags;
1360
1361   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1362
1363   IRDA_ASSERT (dev != NULL, return -1; );
1364   self = (struct toshoboe_cb *) dev->priv;
1365
1366   IRDA_ASSERT (self != NULL, return 0; );
1367
1368   if (self->async)
1369     return -EBUSY;
1370
1371   if (self->stopped)
1372     return 0;
1373
1374   if (request_irq (self->io.irq, toshoboe_interrupt,
1375                    IRQF_SHARED | IRQF_DISABLED, dev->name, (void *) self))
1376     {
1377       return -EAGAIN;
1378     }
1379
1380   spin_lock_irqsave(&self->spinlock, flags);
1381   toshoboe_startchip (self);
1382   spin_unlock_irqrestore(&self->spinlock, flags);
1383
1384   /* Ready to play! */
1385   netif_start_queue(dev);
1386
1387   /*
1388    * Open new IrLAP layer instance, now that everything should be
1389    * initialized properly
1390    */
1391   self->irlap = irlap_open (dev, &self->qos, driver_name);
1392
1393   self->irdad = 1;
1394
1395   return 0;
1396 }
1397
1398 static int
1399 toshoboe_net_close (struct net_device *dev)
1400 {
1401   struct toshoboe_cb *self;
1402
1403   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1404
1405   IRDA_ASSERT (dev != NULL, return -1; );
1406   self = (struct toshoboe_cb *) dev->priv;
1407
1408   /* Stop device */
1409   netif_stop_queue(dev);
1410
1411   /* Stop and remove instance of IrLAP */
1412   if (self->irlap)
1413     irlap_close (self->irlap);
1414   self->irlap = NULL;
1415
1416   self->irdad = 0;
1417
1418   free_irq (self->io.irq, (void *) self);
1419
1420   if (!self->stopped)
1421     {
1422       toshoboe_stopchip (self);
1423     }
1424
1425   return 0;
1426 }
1427
1428 /*
1429  * Function toshoboe_net_ioctl (dev, rq, cmd)
1430  *
1431  *    Process IOCTL commands for this device
1432  *
1433  */
1434 static int
1435 toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1436 {
1437   struct if_irda_req *irq = (struct if_irda_req *) rq;
1438   struct toshoboe_cb *self;
1439   unsigned long flags;
1440   int ret = 0;
1441
1442   IRDA_ASSERT (dev != NULL, return -1; );
1443
1444   self = dev->priv;
1445
1446   IRDA_ASSERT (self != NULL, return -1; );
1447
1448   IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1449
1450   /* Disable interrupts & save flags */
1451   spin_lock_irqsave(&self->spinlock, flags);
1452
1453   switch (cmd)
1454     {
1455     case SIOCSBANDWIDTH:       /* Set bandwidth */
1456       /* This function will also be used by IrLAP to change the
1457        * speed, so we still must allow for speed change within
1458        * interrupt context.
1459        */
1460       IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
1461           ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1462       if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1463         ret = -EPERM;
1464         goto out;
1465       }
1466
1467       /* self->speed=irq->ifr_baudrate; */
1468       /* toshoboe_setbaud(self); */
1469       /* Just change speed once - inserted by Paul Bristow */
1470       self->new_speed = irq->ifr_baudrate;
1471       break;
1472     case SIOCSMEDIABUSY:       /* Set media busy */
1473       IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
1474           ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1475       if (!capable (CAP_NET_ADMIN)) {
1476         ret = -EPERM;
1477         goto out;
1478       }
1479       irda_device_set_media_busy (self->netdev, TRUE);
1480       break;
1481     case SIOCGRECEIVING:       /* Check if we are receiving right now */
1482       irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0;
1483       IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __FUNCTION__
1484           ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving );
1485       break;
1486     default:
1487       IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1488       ret = -EOPNOTSUPP;
1489     }
1490 out:
1491   spin_unlock_irqrestore(&self->spinlock, flags);
1492   return ret;
1493
1494 }
1495
1496 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
1497 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
1498 MODULE_LICENSE("GPL");
1499
1500 module_param (max_baud, int, 0);
1501 MODULE_PARM_DESC(max_baud, "Maximum baud rate");
1502
1503 #ifdef USE_PROBE
1504 module_param (do_probe, bool, 0);
1505 MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
1506 #endif
1507
1508 static void
1509 toshoboe_close (struct pci_dev *pci_dev)
1510 {
1511   int i;
1512   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1513
1514   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1515
1516   IRDA_ASSERT (self != NULL, return; );
1517
1518   if (!self->stopped)
1519     {
1520       toshoboe_stopchip (self);
1521     }
1522
1523   release_region (self->io.fir_base, self->io.fir_ext);
1524
1525   for (i = 0; i < TX_SLOTS; ++i)
1526     {
1527       kfree (self->tx_bufs[i]);
1528       self->tx_bufs[i] = NULL;
1529     }
1530
1531   for (i = 0; i < RX_SLOTS; ++i)
1532     {
1533       kfree (self->rx_bufs[i]);
1534       self->rx_bufs[i] = NULL;
1535     }
1536
1537   unregister_netdev(self->netdev);
1538
1539   kfree (self->ringbuf);
1540   self->ringbuf = NULL;
1541   self->ring = NULL;
1542
1543   free_netdev(self->netdev);
1544 }
1545
1546 static int
1547 toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
1548 {
1549   struct toshoboe_cb *self;
1550   struct net_device *dev;
1551   int i = 0;
1552   int ok = 0;
1553   int err;
1554
1555   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1556
1557   if ((err=pci_enable_device(pci_dev)))
1558     return err;
1559
1560   dev = alloc_irdadev(sizeof (struct toshoboe_cb));
1561   if (dev == NULL)
1562     {
1563       printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
1564               "IrDA control block\n");
1565       return -ENOMEM;
1566     }
1567
1568   self = dev->priv;
1569   self->netdev = dev;
1570   self->pdev = pci_dev;
1571   self->base = pci_resource_start(pci_dev,0);
1572
1573   self->io.fir_base = self->base;
1574   self->io.fir_ext = OBOE_IO_EXTENT;
1575   self->io.irq = pci_dev->irq;
1576   self->io.irqflags = IRQF_SHARED | IRQF_DISABLED;
1577
1578   self->speed = self->io.speed = 9600;
1579   self->async = 0;
1580
1581   /* Lock the port that we need */
1582   if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name))
1583     {
1584       printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n"
1585               ,self->io.fir_base);
1586       err = -EBUSY;
1587       goto freeself;
1588     }
1589
1590   spin_lock_init(&self->spinlock);
1591
1592   irda_init_max_qos_capabilies (&self->qos);
1593   self->qos.baud_rate.bits = 0;
1594
1595   if (max_baud >= 2400)
1596     self->qos.baud_rate.bits |= IR_2400;
1597   /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
1598   if (max_baud >= 9600)
1599     self->qos.baud_rate.bits |= IR_9600;
1600   if (max_baud >= 19200)
1601     self->qos.baud_rate.bits |= IR_19200;
1602   if (max_baud >= 115200)
1603     self->qos.baud_rate.bits |= IR_115200;
1604 #ifdef USE_MIR
1605   if (max_baud >= 1152000)
1606     {
1607       self->qos.baud_rate.bits |= IR_1152000;
1608     }
1609 #endif
1610   if (max_baud >= 4000000)
1611     {
1612       self->qos.baud_rate.bits |= (IR_4000000 << 8);
1613     }
1614
1615   /*FIXME: work this out... */
1616   self->qos.min_turn_time.bits = 0xff;
1617
1618   irda_qos_bits_to_value (&self->qos);
1619
1620   /* Allocate twice the size to guarantee alignment */
1621   self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL);
1622   if (!self->ringbuf)
1623     {
1624       printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
1625       err = -ENOMEM;
1626       goto freeregion;
1627     }
1628
1629 #if (BITS_PER_LONG == 64)
1630 #error broken on 64-bit:  casts pointer to 32-bit, and then back to pointer.
1631 #endif
1632
1633   /*We need to align the taskfile on a taskfile size boundary */
1634   {
1635     unsigned long addr;
1636
1637     addr = (__u32) self->ringbuf;
1638     addr &= ~(OBOE_RING_LEN - 1);
1639     addr += OBOE_RING_LEN;
1640     self->ring = (struct OboeRing *) addr;
1641   }
1642
1643   memset (self->ring, 0, OBOE_RING_LEN);
1644   self->io.mem_base = (__u32) self->ring;
1645
1646   ok = 1;
1647   for (i = 0; i < TX_SLOTS; ++i)
1648     {
1649       self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL);
1650       if (!self->tx_bufs[i])
1651         ok = 0;
1652     }
1653
1654   for (i = 0; i < RX_SLOTS; ++i)
1655     {
1656       self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL);
1657       if (!self->rx_bufs[i])
1658         ok = 0;
1659     }
1660
1661   if (!ok)
1662     {
1663       printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n");
1664       err = -ENOMEM;
1665       goto freebufs;
1666     }
1667
1668
1669 #ifdef USE_PROBE
1670   if (do_probe)
1671     if (!toshoboe_probe (self))
1672       {
1673         err = -ENODEV;
1674         goto freebufs;
1675       }
1676 #endif
1677
1678   SET_MODULE_OWNER(dev);
1679   SET_NETDEV_DEV(dev, &pci_dev->dev);
1680   dev->hard_start_xmit = toshoboe_hard_xmit;
1681   dev->open = toshoboe_net_open;
1682   dev->stop = toshoboe_net_close;
1683   dev->do_ioctl = toshoboe_net_ioctl;
1684
1685   err = register_netdev(dev);
1686   if (err)
1687     {
1688       printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
1689       err = -ENOMEM;
1690       goto freebufs;
1691     }
1692   printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
1693
1694   pci_set_drvdata(pci_dev,self);
1695
1696   printk (KERN_INFO DRIVER_NAME ": Using multiple tasks, version %s\n", rcsid);
1697
1698   return 0;
1699
1700 freebufs:
1701   for (i = 0; i < TX_SLOTS; ++i)
1702     kfree (self->tx_bufs[i]);
1703   for (i = 0; i < RX_SLOTS; ++i)
1704     kfree (self->rx_bufs[i]);
1705   kfree(self->ringbuf);
1706
1707 freeregion:
1708   release_region (self->io.fir_base, self->io.fir_ext);
1709
1710 freeself:
1711   free_netdev(dev);
1712
1713   return err;
1714 }
1715
1716 static int
1717 toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
1718 {
1719   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1720   unsigned long flags;
1721   int i = 10;
1722
1723   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1724
1725   if (!self || self->stopped)
1726     return 0;
1727
1728   if ((!self->irdad) && (!self->async))
1729     return 0;
1730
1731 /* Flush all packets */
1732   while ((i--) && (self->txpending))
1733     udelay (10000);
1734
1735   spin_lock_irqsave(&self->spinlock, flags);
1736
1737   toshoboe_stopchip (self);
1738   self->stopped = 1;
1739   self->txpending = 0;
1740
1741   spin_unlock_irqrestore(&self->spinlock, flags);
1742   return 0;
1743 }
1744
1745 static int
1746 toshoboe_wakeup (struct pci_dev *pci_dev)
1747 {
1748   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1749   unsigned long flags;
1750
1751   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1752
1753   if (!self || !self->stopped)
1754     return 0;
1755
1756   if ((!self->irdad) && (!self->async))
1757     return 0;
1758
1759   spin_lock_irqsave(&self->spinlock, flags);
1760
1761   toshoboe_startchip (self);
1762   self->stopped = 0;
1763
1764   netif_wake_queue(self->netdev);
1765   spin_unlock_irqrestore(&self->spinlock, flags);
1766   return 0;
1767 }
1768
1769 static struct pci_driver donauboe_pci_driver = {
1770         .name           = "donauboe",
1771         .id_table       = toshoboe_pci_tbl,
1772         .probe          = toshoboe_open,
1773         .remove         = toshoboe_close,
1774         .suspend        = toshoboe_gotosleep,
1775         .resume         = toshoboe_wakeup 
1776 };
1777
1778 static int __init
1779 donauboe_init (void)
1780 {
1781   return pci_register_driver(&donauboe_pci_driver);
1782 }
1783
1784 static void __exit
1785 donauboe_cleanup (void)
1786 {
1787   pci_unregister_driver(&donauboe_pci_driver);
1788 }
1789
1790 module_init(donauboe_init);
1791 module_exit(donauboe_cleanup);