drivers/net: eliminate irq handler impossible checks, needless casts
[linux-3.10.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 #ifdef USE_PROBE
661 /***********************************************************************/
662 /* Probe code */
663
664 static void
665 toshoboe_dumptx (struct toshoboe_cb *self)
666 {
667   int i;
668   PROBE_DEBUG(KERN_WARNING "TX:");
669   for (i = 0; i < RX_SLOTS; ++i)
670     PROBE_DEBUG(" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
671   PROBE_DEBUG(" [%d]\n",self->speed);
672 }
673
674 static void
675 toshoboe_dumprx (struct toshoboe_cb *self, int score)
676 {
677   int i;
678   PROBE_DEBUG(" %d\nRX:",score);
679   for (i = 0; i < RX_SLOTS; ++i)
680     PROBE_DEBUG(" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
681   PROBE_DEBUG("\n");
682 }
683
684 static inline int
685 stuff_byte (__u8 byte, __u8 * buf)
686 {
687   switch (byte)
688     {
689     case BOF:                  /* FALLTHROUGH */
690     case EOF:                  /* FALLTHROUGH */
691     case CE:
692       /* Insert transparently coded */
693       buf[0] = CE;              /* Send link escape */
694       buf[1] = byte ^ IRDA_TRANS; /* Complement bit 5 */
695       return 2;
696       /* break; */
697     default:
698       /* Non-special value, no transparency required */
699       buf[0] = byte;
700       return 1;
701       /* break; */
702     }
703 }
704
705 static irqreturn_t
706 toshoboe_probeinterrupt (int irq, void *dev_id)
707 {
708   struct toshoboe_cb *self = dev_id;
709   __u8 irqstat;
710
711   irqstat = INB (OBOE_ISR);
712
713 /* was it us */
714   if (!(irqstat & OBOE_INT_MASK))
715     return IRQ_NONE;
716
717 /* Ack all the interrupts */
718   OUTB (irqstat, OBOE_ISR);
719
720   if (irqstat & OBOE_INT_TXDONE)
721     {
722       int txp;
723
724       self->int_tx++;
725       PROBE_DEBUG("T");
726
727       txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
728       if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
729         {
730           self->int_tx+=100;
731           PROBE_DEBUG("S");
732           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
733         }
734     }
735
736   if (irqstat & OBOE_INT_RXDONE) {
737     self->int_rx++;
738     PROBE_DEBUG("R"); }
739   if (irqstat & OBOE_INT_TXUNDER) {
740     self->int_txunder++;
741     PROBE_DEBUG("U"); }
742   if (irqstat & OBOE_INT_RXOVER) {
743     self->int_rxover++;
744     PROBE_DEBUG("O"); }
745   if (irqstat & OBOE_INT_SIP) {
746     self->int_sip++;
747     PROBE_DEBUG("I"); }
748   return IRQ_HANDLED;
749 }
750
751 static int
752 toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir)
753 {
754   int i;
755   int len = 0;
756   union
757   {
758     __u16 value;
759     __u8 bytes[2];
760   }
761   fcs;
762
763   if (fir)
764     {
765       memset (buf, 0, TT_LEN);
766       return (TT_LEN);
767     }
768
769   fcs.value = INIT_FCS;
770
771   memset (buf, XBOF, 10);
772   len += 10;
773   buf[len++] = BOF;
774
775   for (i = 0; i < TT_LEN; ++i)
776     {
777       len += stuff_byte (i, buf + len);
778       fcs.value = irda_fcs (fcs.value, i);
779     }
780
781   len += stuff_byte (fcs.bytes[0] ^ badcrc, buf + len);
782   len += stuff_byte (fcs.bytes[1] ^ badcrc, buf + len);
783   buf[len++] = EOF;
784   len++;
785   return len;
786 }
787
788 static int
789 toshoboe_probefail (struct toshoboe_cb *self, char *msg)
790 {
791   printk (KERN_ERR DRIVER_NAME "probe(%d) failed %s\n",self-> speed, msg);
792   toshoboe_dumpregs (self);
793   toshoboe_stopchip (self);
794   free_irq (self->io.irq, (void *) self);
795   return 0;
796 }
797
798 static int
799 toshoboe_numvalidrcvs (struct toshoboe_cb *self)
800 {
801   int i, ret = 0;
802   for (i = 0; i < RX_SLOTS; ++i)
803     if ((self->ring->rx[i].control & 0xe0) == 0)
804       ret++;
805
806   return ret;
807 }
808
809 static int
810 toshoboe_numrcvs (struct toshoboe_cb *self)
811 {
812   int i, ret = 0;
813   for (i = 0; i < RX_SLOTS; ++i)
814     if (!(self->ring->rx[i].control & OBOE_CTL_RX_HW_OWNS))
815       ret++;
816
817   return ret;
818 }
819
820 static int
821 toshoboe_probe (struct toshoboe_cb *self)
822 {
823   int i, j, n;
824 #ifdef USE_MIR
825   int bauds[] = { 9600, 115200, 4000000, 1152000 };
826 #else
827   int bauds[] = { 9600, 115200, 4000000 };
828 #endif
829   unsigned long flags;
830
831   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
832
833   if (request_irq (self->io.irq, toshoboe_probeinterrupt,
834                    self->io.irqflags, "toshoboe", (void *) self))
835     {
836       printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n",
837               self->io.irq);
838       return 0;
839     }
840
841   /* test 1: SIR filter and back to back */
842
843   for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j)
844     {
845       int fir = (j > 1);
846       toshoboe_stopchip (self);
847
848
849       spin_lock_irqsave(&self->spinlock, flags);
850       /*Address is already setup */
851       toshoboe_startchip (self);
852       self->int_rx = self->int_tx = 0;
853       self->speed = bauds[j];
854       toshoboe_setbaud (self);
855       toshoboe_initptrs (self);
856       spin_unlock_irqrestore(&self->spinlock, flags);
857
858       self->ring->tx[self->txs].control =
859 /*   (FIR only) OBOE_CTL_TX_SIP needed for switching to next slot */
860 /*    MIR: all received data is stored in one slot */
861         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
862               : OBOE_CTL_TX_HW_OWNS ;
863       self->ring->tx[self->txs].len =
864         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
865       self->txs++;
866       self->txs %= TX_SLOTS;
867
868       self->ring->tx[self->txs].control =
869         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_SIP
870               : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
871       self->ring->tx[self->txs].len =
872         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
873       self->txs++;
874       self->txs %= TX_SLOTS;
875
876       self->ring->tx[self->txs].control =
877         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
878               : OBOE_CTL_TX_HW_OWNS ;
879       self->ring->tx[self->txs].len =
880         toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
881       self->txs++;
882       self->txs %= TX_SLOTS;
883
884       self->ring->tx[self->txs].control =
885         (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
886               | OBOE_CTL_TX_SIP     | OBOE_CTL_TX_BAD_CRC
887               : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
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       toshoboe_dumptx (self);
894       /* Turn on TX and RX and loopback */
895       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
896
897       i = 0;
898       n = fir ? 1 : 4;
899       while (toshoboe_numvalidrcvs (self) != n)
900         {
901           if (i > 4800)
902               return toshoboe_probefail (self, "filter test");
903           udelay ((9600*(TT_LEN+16))/self->speed);
904           i++;
905         }
906
907       n = fir ? 203 : 102;
908       while ((toshoboe_numrcvs(self) != self->int_rx) || (self->int_tx != n))
909         {
910           if (i > 4800)
911               return toshoboe_probefail (self, "interrupt test");
912           udelay ((9600*(TT_LEN+16))/self->speed);
913           i++;
914         }
915      toshoboe_dumprx (self,i);
916
917      }
918
919   /* test 2: SIR in char at a time */
920
921   toshoboe_stopchip (self);
922   self->int_rx = self->int_tx = 0;
923
924   spin_lock_irqsave(&self->spinlock, flags);
925   toshoboe_startchip (self);
926   spin_unlock_irqrestore(&self->spinlock, flags);
927
928   self->async = 1;
929   self->speed = 115200;
930   toshoboe_setbaud (self);
931   self->ring->tx[self->txs].control =
932     OBOE_CTL_TX_RTCENTX | OBOE_CTL_TX_HW_OWNS;
933   self->ring->tx[self->txs].len = 4;
934
935   ((unsigned char *) self->tx_bufs[self->txs])[0] = 'f';
936   ((unsigned char *) self->tx_bufs[self->txs])[1] = 'i';
937   ((unsigned char *) self->tx_bufs[self->txs])[2] = 's';
938   ((unsigned char *) self->tx_bufs[self->txs])[3] = 'h';
939   toshoboe_dumptx (self);
940   toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
941
942   i = 0;
943   while (toshoboe_numvalidrcvs (self) != 4)
944     {
945       if (i > 100)
946           return toshoboe_probefail (self, "Async test");
947       udelay (100);
948       i++;
949     }
950
951   while ((toshoboe_numrcvs (self) != self->int_rx) || (self->int_tx != 1))
952     {
953       if (i > 100)
954           return toshoboe_probefail (self, "Async interrupt test");
955       udelay (100);
956       i++;
957     }
958   toshoboe_dumprx (self,i);
959
960   self->async = 0;
961   self->speed = 9600;
962   toshoboe_setbaud (self);
963   toshoboe_stopchip (self);
964
965   free_irq (self->io.irq, (void *) self);
966
967   printk (KERN_WARNING DRIVER_NAME ": Self test passed ok\n");
968
969   return 1;
970 }
971 #endif
972
973 /******************************************************************/
974 /* Netdev style code */
975
976 /* Transmit something */
977 static int
978 toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
979 {
980   struct toshoboe_cb *self;
981   __s32 speed;
982   int mtt, len, ctl;
983   unsigned long flags;
984   struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
985
986   self = (struct toshoboe_cb *) dev->priv;
987
988   IRDA_ASSERT (self != NULL, return 0; );
989
990   IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __FUNCTION__
991       ,skb->len,self->txpending,INB (OBOE_ENABLEH));
992   if (!cb->magic) {
993       IRDA_DEBUG (2, "%s.Not IrLAP:%x\n", __FUNCTION__, cb->magic);
994 #ifdef DUMP_PACKETS
995       _dumpbufs(skb->data,skb->len,'>');
996 #endif
997     }
998
999   /* change speed pending, wait for its execution */
1000   if (self->new_speed)
1001       return -EBUSY;
1002
1003   /* device stopped (apm) wait for restart */
1004   if (self->stopped)
1005       return -EBUSY;
1006
1007   toshoboe_checkstuck (self);
1008
1009   dev->trans_start = jiffies;
1010
1011  /* Check if we need to change the speed */
1012   /* But not now. Wait after transmission if mtt not required */
1013   speed=irda_get_next_speed(skb);
1014   if ((speed != self->io.speed) && (speed != -1))
1015     {
1016       spin_lock_irqsave(&self->spinlock, flags);
1017
1018       if (self->txpending || skb->len)
1019         {
1020           self->new_speed = speed;
1021           IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" ,
1022                       __FUNCTION__, speed);
1023           /* if no data, that's all! */
1024           if (!skb->len)
1025             {
1026               spin_unlock_irqrestore(&self->spinlock, flags);
1027               dev_kfree_skb (skb);
1028               return 0;
1029             }
1030           /* True packet, go on, but */
1031           /* do not accept anything before change speed execution */
1032           netif_stop_queue(dev);
1033           /* ready to process TxDone interrupt */
1034           spin_unlock_irqrestore(&self->spinlock, flags);
1035         }
1036       else
1037         {
1038           /* idle and no data, change speed now */
1039           self->speed = speed;
1040           toshoboe_setbaud (self);
1041           spin_unlock_irqrestore(&self->spinlock, flags);
1042           dev_kfree_skb (skb);
1043           return 0;
1044         }
1045
1046     }
1047
1048   if ((mtt = irda_get_mtt(skb)))
1049     {
1050       /* This is fair since the queue should be empty anyway */
1051       spin_lock_irqsave(&self->spinlock, flags);
1052
1053       if (self->txpending)
1054         {
1055           spin_unlock_irqrestore(&self->spinlock, flags);
1056           return -EBUSY;
1057         }
1058
1059       /* If in SIR mode we need to generate a string of XBOFs */
1060       /* In MIR and FIR we need to generate a string of data */
1061       /* which we will add a wrong checksum to */
1062
1063       mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt);
1064       IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __FUNCTION__
1065           ,skb->len,mtt,self->txpending);
1066       if (mtt)
1067         {
1068           self->ring->tx[self->txs].len = mtt & 0xfff;
1069
1070           ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1071           if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1072             {
1073               ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ;
1074             }
1075 #ifdef USE_MIR
1076           else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON)
1077             {
1078               ctl |= OBOE_CTL_TX_BAD_CRC;
1079             }
1080 #endif
1081           self->ring->tx[self->txs].control = ctl;
1082
1083           OUTB (0x0, OBOE_ENABLEH);
1084           /* It is only a timer. Do not send mtt packet outside! */
1085           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
1086
1087           self->txpending++;
1088
1089           self->txs++;
1090           self->txs %= TX_SLOTS;
1091
1092         }
1093       else
1094         {
1095           printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n");
1096         }
1097       spin_unlock_irqrestore(&self->spinlock, flags);
1098     }
1099
1100 #ifdef DUMP_PACKETS
1101 dumpbufs(skb->data,skb->len,'>');
1102 #endif
1103
1104   spin_lock_irqsave(&self->spinlock, flags);
1105
1106   if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS)
1107     {
1108       IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __FUNCTION__
1109           ,skb->len, self->ring->tx[self->txs].control, self->txpending);
1110       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1111       spin_unlock_irqrestore(&self->spinlock, flags);
1112       return -EBUSY;
1113     }
1114
1115   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
1116     {
1117       len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ);
1118     }
1119   else
1120     {
1121       len = skb->len;
1122       memcpy (self->tx_bufs[self->txs], skb->data, len);
1123     }
1124   self->ring->tx[self->txs].len = len & 0x0fff;
1125
1126   /*Sometimes the HW doesn't see us assert RTCENTX in the interrupt code */
1127   /*later this plays safe, we garuntee the last packet to be transmitted */
1128   /*has RTCENTX set */
1129
1130   ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1131   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1132     {
1133       ctl |= OBOE_CTL_TX_SIP ;
1134     }
1135   self->ring->tx[self->txs].control = ctl;
1136
1137   /* If transmitter is idle start in one-shot mode */
1138
1139   if (!self->txpending)
1140       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1141
1142   self->txpending++;
1143
1144   self->txs++;
1145   self->txs %= TX_SLOTS;
1146
1147   spin_unlock_irqrestore(&self->spinlock, flags);
1148   dev_kfree_skb (skb);
1149
1150   return 0;
1151 }
1152
1153 /*interrupt handler */
1154 static irqreturn_t
1155 toshoboe_interrupt (int irq, void *dev_id)
1156 {
1157   struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
1158   __u8 irqstat;
1159   struct sk_buff *skb = NULL;
1160
1161   if (self == NULL && toshoboe_invalid_dev(irq))
1162     return IRQ_NONE;
1163
1164   irqstat = INB (OBOE_ISR);
1165
1166 /* was it us */
1167   if (!(irqstat & OBOE_INT_MASK))
1168       return IRQ_NONE;
1169
1170 /* Ack all the interrupts */
1171   OUTB (irqstat, OBOE_ISR);
1172
1173   toshoboe_isntstuck (self);
1174
1175 /* Txdone */
1176   if (irqstat & OBOE_INT_TXDONE)
1177     {
1178       int txp, txpc;
1179       int i;
1180
1181       txp = self->txpending;
1182       self->txpending = 0;
1183
1184       for (i = 0; i < TX_SLOTS; ++i)
1185         {
1186           if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS)
1187               self->txpending++;
1188         }
1189       IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __FUNCTION__
1190           ,irqstat,txp,self->txpending);
1191
1192       txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
1193
1194       /* Got anything queued ? start it together */
1195       if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
1196         {
1197           txpc = txp;
1198 #ifdef OPTIMIZE_TX
1199           while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1200             {
1201               txp = txpc;
1202               txpc++;
1203               txpc %= TX_SLOTS;
1204               self->stats.tx_packets++;
1205               if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1206                   self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
1207             }
1208           self->stats.tx_packets--;
1209 #else
1210           self->stats.tx_packets++;
1211 #endif
1212           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1213         }
1214
1215       if ((!self->txpending) && (self->new_speed))
1216         {
1217           self->speed = self->new_speed;
1218           IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n",
1219                       __FUNCTION__, self->speed);
1220           toshoboe_setbaud (self);
1221         }
1222
1223       /* Tell network layer that we want more frames */
1224       if (!self->new_speed)
1225           netif_wake_queue(self->netdev);
1226     }
1227
1228   if (irqstat & OBOE_INT_RXDONE)
1229     {
1230       while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS))
1231         {
1232           int len = self->ring->rx[self->rxs].len;
1233           skb = NULL;
1234           IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __FUNCTION__
1235                       ,len,self->ring->rx[self->rxs].control);
1236
1237 #ifdef DUMP_PACKETS
1238 dumpbufs(self->rx_bufs[self->rxs],len,'<');
1239 #endif
1240
1241           if (self->ring->rx[self->rxs].control == 0)
1242             {
1243               __u8 enable = INB (OBOE_ENABLEH);
1244
1245               /* In SIR mode we need to check the CRC as this */
1246               /* hasn't been done by the hardware */
1247               if (enable & OBOE_ENABLEH_SIRON)
1248                 {
1249                   if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len))
1250                       len = 0;
1251                   /*Trim off the CRC */
1252                   if (len > 1)
1253                       len -= 2;
1254                   else
1255                       len = 0;
1256                   IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __FUNCTION__, len,enable);
1257                 }
1258
1259 #ifdef USE_MIR
1260               else if (enable & OBOE_ENABLEH_MIRON)
1261                 {
1262                   if (len > 1)
1263                       len -= 2;
1264                   else
1265                       len = 0;
1266                   IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __FUNCTION__, len,enable);
1267                 }
1268 #endif
1269               else if (enable & OBOE_ENABLEH_FIRON)
1270                 {
1271                   if (len > 3)
1272                       len -= 4;   /*FIXME: check this */
1273                   else
1274                       len = 0;
1275                   IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __FUNCTION__, len,enable);
1276                 }
1277               else
1278                   IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __FUNCTION__, len,enable);
1279
1280               if (len)
1281                 {
1282                   skb = dev_alloc_skb (len + 1);
1283                   if (skb)
1284                     {
1285                       skb_reserve (skb, 1);
1286
1287                       skb_put (skb, len);
1288                       memcpy (skb->data, self->rx_bufs[self->rxs], len);
1289
1290                       self->stats.rx_packets++;
1291                       skb->dev = self->netdev;
1292                       skb->mac.raw = skb->data;
1293                       skb->protocol = htons (ETH_P_IRDA);
1294                     }
1295                   else
1296                     {
1297                       printk (KERN_INFO
1298                               "%s(), memory squeeze, dropping frame.\n",
1299                               __FUNCTION__);
1300                     }
1301                 }
1302             }
1303           else
1304             {
1305             /* TODO: =========================================== */
1306             /*  if OBOE_CTL_RX_LENGTH, our buffers are too small */
1307             /* (MIR or FIR) data is lost. */
1308             /* (SIR) data is splitted in several slots. */
1309             /* we have to join all the received buffers received */
1310             /*in a large buffer before checking CRC. */
1311             IRDA_DEBUG (0, "%s.err:%x(%x)\n", __FUNCTION__
1312                 ,len,self->ring->rx[self->rxs].control);
1313             }
1314
1315           self->ring->rx[self->rxs].len = 0x0;
1316           self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS;
1317
1318           self->rxs++;
1319           self->rxs %= RX_SLOTS;
1320
1321           if (skb)
1322               netif_rx (skb);
1323
1324         }
1325     }
1326
1327   if (irqstat & OBOE_INT_TXUNDER)
1328     {
1329       printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n");
1330     }
1331   if (irqstat & OBOE_INT_RXOVER)
1332     {
1333       printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n");
1334     }
1335 /* This must be useful for something... */
1336   if (irqstat & OBOE_INT_SIP)
1337     {
1338       self->int_sip++;
1339       IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __FUNCTION__
1340               ,self->int_sip,irqstat,self->txpending);
1341     }
1342   return IRQ_HANDLED;
1343 }
1344
1345
1346 static int
1347 toshoboe_net_open (struct net_device *dev)
1348 {
1349   struct toshoboe_cb *self;
1350   unsigned long flags;
1351
1352   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1353
1354   IRDA_ASSERT (dev != NULL, return -1; );
1355   self = (struct toshoboe_cb *) dev->priv;
1356
1357   IRDA_ASSERT (self != NULL, return 0; );
1358
1359   if (self->async)
1360     return -EBUSY;
1361
1362   if (self->stopped)
1363     return 0;
1364
1365   if (request_irq (self->io.irq, toshoboe_interrupt,
1366                    IRQF_SHARED | IRQF_DISABLED, dev->name, (void *) self))
1367     {
1368       return -EAGAIN;
1369     }
1370
1371   spin_lock_irqsave(&self->spinlock, flags);
1372   toshoboe_startchip (self);
1373   spin_unlock_irqrestore(&self->spinlock, flags);
1374
1375   /* Ready to play! */
1376   netif_start_queue(dev);
1377
1378   /*
1379    * Open new IrLAP layer instance, now that everything should be
1380    * initialized properly
1381    */
1382   self->irlap = irlap_open (dev, &self->qos, driver_name);
1383
1384   self->irdad = 1;
1385
1386   return 0;
1387 }
1388
1389 static int
1390 toshoboe_net_close (struct net_device *dev)
1391 {
1392   struct toshoboe_cb *self;
1393
1394   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1395
1396   IRDA_ASSERT (dev != NULL, return -1; );
1397   self = (struct toshoboe_cb *) dev->priv;
1398
1399   /* Stop device */
1400   netif_stop_queue(dev);
1401
1402   /* Stop and remove instance of IrLAP */
1403   if (self->irlap)
1404     irlap_close (self->irlap);
1405   self->irlap = NULL;
1406
1407   self->irdad = 0;
1408
1409   free_irq (self->io.irq, (void *) self);
1410
1411   if (!self->stopped)
1412     {
1413       toshoboe_stopchip (self);
1414     }
1415
1416   return 0;
1417 }
1418
1419 /*
1420  * Function toshoboe_net_ioctl (dev, rq, cmd)
1421  *
1422  *    Process IOCTL commands for this device
1423  *
1424  */
1425 static int
1426 toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1427 {
1428   struct if_irda_req *irq = (struct if_irda_req *) rq;
1429   struct toshoboe_cb *self;
1430   unsigned long flags;
1431   int ret = 0;
1432
1433   IRDA_ASSERT (dev != NULL, return -1; );
1434
1435   self = dev->priv;
1436
1437   IRDA_ASSERT (self != NULL, return -1; );
1438
1439   IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1440
1441   /* Disable interrupts & save flags */
1442   spin_lock_irqsave(&self->spinlock, flags);
1443
1444   switch (cmd)
1445     {
1446     case SIOCSBANDWIDTH:       /* Set bandwidth */
1447       /* This function will also be used by IrLAP to change the
1448        * speed, so we still must allow for speed change within
1449        * interrupt context.
1450        */
1451       IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
1452           ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1453       if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1454         ret = -EPERM;
1455         goto out;
1456       }
1457
1458       /* self->speed=irq->ifr_baudrate; */
1459       /* toshoboe_setbaud(self); */
1460       /* Just change speed once - inserted by Paul Bristow */
1461       self->new_speed = irq->ifr_baudrate;
1462       break;
1463     case SIOCSMEDIABUSY:       /* Set media busy */
1464       IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
1465           ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1466       if (!capable (CAP_NET_ADMIN)) {
1467         ret = -EPERM;
1468         goto out;
1469       }
1470       irda_device_set_media_busy (self->netdev, TRUE);
1471       break;
1472     case SIOCGRECEIVING:       /* Check if we are receiving right now */
1473       irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0;
1474       IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __FUNCTION__
1475           ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving );
1476       break;
1477     default:
1478       IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1479       ret = -EOPNOTSUPP;
1480     }
1481 out:
1482   spin_unlock_irqrestore(&self->spinlock, flags);
1483   return ret;
1484
1485 }
1486
1487 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
1488 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
1489 MODULE_LICENSE("GPL");
1490
1491 module_param (max_baud, int, 0);
1492 MODULE_PARM_DESC(max_baud, "Maximum baud rate");
1493
1494 #ifdef USE_PROBE
1495 module_param (do_probe, bool, 0);
1496 MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
1497 #endif
1498
1499 static void
1500 toshoboe_close (struct pci_dev *pci_dev)
1501 {
1502   int i;
1503   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1504
1505   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1506
1507   IRDA_ASSERT (self != NULL, return; );
1508
1509   if (!self->stopped)
1510     {
1511       toshoboe_stopchip (self);
1512     }
1513
1514   release_region (self->io.fir_base, self->io.fir_ext);
1515
1516   for (i = 0; i < TX_SLOTS; ++i)
1517     {
1518       kfree (self->tx_bufs[i]);
1519       self->tx_bufs[i] = NULL;
1520     }
1521
1522   for (i = 0; i < RX_SLOTS; ++i)
1523     {
1524       kfree (self->rx_bufs[i]);
1525       self->rx_bufs[i] = NULL;
1526     }
1527
1528   unregister_netdev(self->netdev);
1529
1530   kfree (self->ringbuf);
1531   self->ringbuf = NULL;
1532   self->ring = NULL;
1533
1534   free_netdev(self->netdev);
1535 }
1536
1537 static int
1538 toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
1539 {
1540   struct toshoboe_cb *self;
1541   struct net_device *dev;
1542   int i = 0;
1543   int ok = 0;
1544   int err;
1545
1546   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1547
1548   if ((err=pci_enable_device(pci_dev)))
1549     return err;
1550
1551   dev = alloc_irdadev(sizeof (struct toshoboe_cb));
1552   if (dev == NULL)
1553     {
1554       printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
1555               "IrDA control block\n");
1556       return -ENOMEM;
1557     }
1558
1559   self = dev->priv;
1560   self->netdev = dev;
1561   self->pdev = pci_dev;
1562   self->base = pci_resource_start(pci_dev,0);
1563
1564   self->io.fir_base = self->base;
1565   self->io.fir_ext = OBOE_IO_EXTENT;
1566   self->io.irq = pci_dev->irq;
1567   self->io.irqflags = IRQF_SHARED | IRQF_DISABLED;
1568
1569   self->speed = self->io.speed = 9600;
1570   self->async = 0;
1571
1572   /* Lock the port that we need */
1573   if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name))
1574     {
1575       printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n"
1576               ,self->io.fir_base);
1577       err = -EBUSY;
1578       goto freeself;
1579     }
1580
1581   spin_lock_init(&self->spinlock);
1582
1583   irda_init_max_qos_capabilies (&self->qos);
1584   self->qos.baud_rate.bits = 0;
1585
1586   if (max_baud >= 2400)
1587     self->qos.baud_rate.bits |= IR_2400;
1588   /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
1589   if (max_baud >= 9600)
1590     self->qos.baud_rate.bits |= IR_9600;
1591   if (max_baud >= 19200)
1592     self->qos.baud_rate.bits |= IR_19200;
1593   if (max_baud >= 115200)
1594     self->qos.baud_rate.bits |= IR_115200;
1595 #ifdef USE_MIR
1596   if (max_baud >= 1152000)
1597     {
1598       self->qos.baud_rate.bits |= IR_1152000;
1599     }
1600 #endif
1601   if (max_baud >= 4000000)
1602     {
1603       self->qos.baud_rate.bits |= (IR_4000000 << 8);
1604     }
1605
1606   /*FIXME: work this out... */
1607   self->qos.min_turn_time.bits = 0xff;
1608
1609   irda_qos_bits_to_value (&self->qos);
1610
1611   /* Allocate twice the size to guarantee alignment */
1612   self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL);
1613   if (!self->ringbuf)
1614     {
1615       printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
1616       err = -ENOMEM;
1617       goto freeregion;
1618     }
1619
1620 #if (BITS_PER_LONG == 64)
1621 #error broken on 64-bit:  casts pointer to 32-bit, and then back to pointer.
1622 #endif
1623
1624   /*We need to align the taskfile on a taskfile size boundary */
1625   {
1626     unsigned long addr;
1627
1628     addr = (__u32) self->ringbuf;
1629     addr &= ~(OBOE_RING_LEN - 1);
1630     addr += OBOE_RING_LEN;
1631     self->ring = (struct OboeRing *) addr;
1632   }
1633
1634   memset (self->ring, 0, OBOE_RING_LEN);
1635   self->io.mem_base = (__u32) self->ring;
1636
1637   ok = 1;
1638   for (i = 0; i < TX_SLOTS; ++i)
1639     {
1640       self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL);
1641       if (!self->tx_bufs[i])
1642         ok = 0;
1643     }
1644
1645   for (i = 0; i < RX_SLOTS; ++i)
1646     {
1647       self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL);
1648       if (!self->rx_bufs[i])
1649         ok = 0;
1650     }
1651
1652   if (!ok)
1653     {
1654       printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n");
1655       err = -ENOMEM;
1656       goto freebufs;
1657     }
1658
1659
1660 #ifdef USE_PROBE
1661   if (do_probe)
1662     if (!toshoboe_probe (self))
1663       {
1664         err = -ENODEV;
1665         goto freebufs;
1666       }
1667 #endif
1668
1669   SET_MODULE_OWNER(dev);
1670   SET_NETDEV_DEV(dev, &pci_dev->dev);
1671   dev->hard_start_xmit = toshoboe_hard_xmit;
1672   dev->open = toshoboe_net_open;
1673   dev->stop = toshoboe_net_close;
1674   dev->do_ioctl = toshoboe_net_ioctl;
1675
1676   err = register_netdev(dev);
1677   if (err)
1678     {
1679       printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
1680       err = -ENOMEM;
1681       goto freebufs;
1682     }
1683   printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
1684
1685   pci_set_drvdata(pci_dev,self);
1686
1687   printk (KERN_INFO DRIVER_NAME ": Using multiple tasks, version %s\n", rcsid);
1688
1689   return 0;
1690
1691 freebufs:
1692   for (i = 0; i < TX_SLOTS; ++i)
1693     kfree (self->tx_bufs[i]);
1694   for (i = 0; i < RX_SLOTS; ++i)
1695     kfree (self->rx_bufs[i]);
1696   kfree(self->ringbuf);
1697
1698 freeregion:
1699   release_region (self->io.fir_base, self->io.fir_ext);
1700
1701 freeself:
1702   free_netdev(dev);
1703
1704   return err;
1705 }
1706
1707 static int
1708 toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
1709 {
1710   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1711   unsigned long flags;
1712   int i = 10;
1713
1714   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1715
1716   if (!self || self->stopped)
1717     return 0;
1718
1719   if ((!self->irdad) && (!self->async))
1720     return 0;
1721
1722 /* Flush all packets */
1723   while ((i--) && (self->txpending))
1724     udelay (10000);
1725
1726   spin_lock_irqsave(&self->spinlock, flags);
1727
1728   toshoboe_stopchip (self);
1729   self->stopped = 1;
1730   self->txpending = 0;
1731
1732   spin_unlock_irqrestore(&self->spinlock, flags);
1733   return 0;
1734 }
1735
1736 static int
1737 toshoboe_wakeup (struct pci_dev *pci_dev)
1738 {
1739   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1740   unsigned long flags;
1741
1742   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1743
1744   if (!self || !self->stopped)
1745     return 0;
1746
1747   if ((!self->irdad) && (!self->async))
1748     return 0;
1749
1750   spin_lock_irqsave(&self->spinlock, flags);
1751
1752   toshoboe_startchip (self);
1753   self->stopped = 0;
1754
1755   netif_wake_queue(self->netdev);
1756   spin_unlock_irqrestore(&self->spinlock, flags);
1757   return 0;
1758 }
1759
1760 static struct pci_driver donauboe_pci_driver = {
1761         .name           = "donauboe",
1762         .id_table       = toshoboe_pci_tbl,
1763         .probe          = toshoboe_open,
1764         .remove         = toshoboe_close,
1765         .suspend        = toshoboe_gotosleep,
1766         .resume         = toshoboe_wakeup 
1767 };
1768
1769 static int __init
1770 donauboe_init (void)
1771 {
1772   return pci_register_driver(&donauboe_pci_driver);
1773 }
1774
1775 static void __exit
1776 donauboe_cleanup (void)
1777 {
1778   pci_unregister_driver(&donauboe_pci_driver);
1779 }
1780
1781 module_init(donauboe_init);
1782 module_exit(donauboe_cleanup);