[PATCH] irda: donauboe fixes, cleanups
[linux-2.6] / 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 = dev_id;
1158   __u8 irqstat;
1159   struct sk_buff *skb = NULL;
1160
1161   irqstat = INB (OBOE_ISR);
1162
1163 /* was it us */
1164   if (!(irqstat & OBOE_INT_MASK))
1165       return IRQ_NONE;
1166
1167 /* Ack all the interrupts */
1168   OUTB (irqstat, OBOE_ISR);
1169
1170   toshoboe_isntstuck (self);
1171
1172 /* Txdone */
1173   if (irqstat & OBOE_INT_TXDONE)
1174     {
1175       int txp, txpc;
1176       int i;
1177
1178       txp = self->txpending;
1179       self->txpending = 0;
1180
1181       for (i = 0; i < TX_SLOTS; ++i)
1182         {
1183           if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS)
1184               self->txpending++;
1185         }
1186       IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __FUNCTION__
1187           ,irqstat,txp,self->txpending);
1188
1189       txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
1190
1191       /* Got anything queued ? start it together */
1192       if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
1193         {
1194           txpc = txp;
1195 #ifdef OPTIMIZE_TX
1196           while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1197             {
1198               txp = txpc;
1199               txpc++;
1200               txpc %= TX_SLOTS;
1201               self->stats.tx_packets++;
1202               if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1203                   self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
1204             }
1205           self->stats.tx_packets--;
1206 #else
1207           self->stats.tx_packets++;
1208 #endif
1209           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1210         }
1211
1212       if ((!self->txpending) && (self->new_speed))
1213         {
1214           self->speed = self->new_speed;
1215           IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n",
1216                       __FUNCTION__, self->speed);
1217           toshoboe_setbaud (self);
1218         }
1219
1220       /* Tell network layer that we want more frames */
1221       if (!self->new_speed)
1222           netif_wake_queue(self->netdev);
1223     }
1224
1225   if (irqstat & OBOE_INT_RXDONE)
1226     {
1227       while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS))
1228         {
1229           int len = self->ring->rx[self->rxs].len;
1230           skb = NULL;
1231           IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __FUNCTION__
1232                       ,len,self->ring->rx[self->rxs].control);
1233
1234 #ifdef DUMP_PACKETS
1235 dumpbufs(self->rx_bufs[self->rxs],len,'<');
1236 #endif
1237
1238           if (self->ring->rx[self->rxs].control == 0)
1239             {
1240               __u8 enable = INB (OBOE_ENABLEH);
1241
1242               /* In SIR mode we need to check the CRC as this */
1243               /* hasn't been done by the hardware */
1244               if (enable & OBOE_ENABLEH_SIRON)
1245                 {
1246                   if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len))
1247                       len = 0;
1248                   /*Trim off the CRC */
1249                   if (len > 1)
1250                       len -= 2;
1251                   else
1252                       len = 0;
1253                   IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __FUNCTION__, len,enable);
1254                 }
1255
1256 #ifdef USE_MIR
1257               else if (enable & OBOE_ENABLEH_MIRON)
1258                 {
1259                   if (len > 1)
1260                       len -= 2;
1261                   else
1262                       len = 0;
1263                   IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __FUNCTION__, len,enable);
1264                 }
1265 #endif
1266               else if (enable & OBOE_ENABLEH_FIRON)
1267                 {
1268                   if (len > 3)
1269                       len -= 4;   /*FIXME: check this */
1270                   else
1271                       len = 0;
1272                   IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __FUNCTION__, len,enable);
1273                 }
1274               else
1275                   IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __FUNCTION__, len,enable);
1276
1277               if (len)
1278                 {
1279                   skb = dev_alloc_skb (len + 1);
1280                   if (skb)
1281                     {
1282                       skb_reserve (skb, 1);
1283
1284                       skb_put (skb, len);
1285                       memcpy (skb->data, self->rx_bufs[self->rxs], len);
1286
1287                       self->stats.rx_packets++;
1288                       skb->dev = self->netdev;
1289                       skb->mac.raw = skb->data;
1290                       skb->protocol = htons (ETH_P_IRDA);
1291                     }
1292                   else
1293                     {
1294                       printk (KERN_INFO
1295                               "%s(), memory squeeze, dropping frame.\n",
1296                               __FUNCTION__);
1297                     }
1298                 }
1299             }
1300           else
1301             {
1302             /* TODO: =========================================== */
1303             /*  if OBOE_CTL_RX_LENGTH, our buffers are too small */
1304             /* (MIR or FIR) data is lost. */
1305             /* (SIR) data is splitted in several slots. */
1306             /* we have to join all the received buffers received */
1307             /*in a large buffer before checking CRC. */
1308             IRDA_DEBUG (0, "%s.err:%x(%x)\n", __FUNCTION__
1309                 ,len,self->ring->rx[self->rxs].control);
1310             }
1311
1312           self->ring->rx[self->rxs].len = 0x0;
1313           self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS;
1314
1315           self->rxs++;
1316           self->rxs %= RX_SLOTS;
1317
1318           if (skb)
1319               netif_rx (skb);
1320
1321         }
1322     }
1323
1324   if (irqstat & OBOE_INT_TXUNDER)
1325     {
1326       printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n");
1327     }
1328   if (irqstat & OBOE_INT_RXOVER)
1329     {
1330       printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n");
1331     }
1332 /* This must be useful for something... */
1333   if (irqstat & OBOE_INT_SIP)
1334     {
1335       self->int_sip++;
1336       IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __FUNCTION__
1337               ,self->int_sip,irqstat,self->txpending);
1338     }
1339   return IRQ_HANDLED;
1340 }
1341
1342
1343 static int
1344 toshoboe_net_open (struct net_device *dev)
1345 {
1346   struct toshoboe_cb *self;
1347   unsigned long flags;
1348   int rc;
1349
1350   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1351
1352   self = netdev_priv(dev);
1353
1354   if (self->async)
1355     return -EBUSY;
1356
1357   if (self->stopped)
1358     return 0;
1359
1360   rc = request_irq (self->io.irq, toshoboe_interrupt,
1361                     IRQF_SHARED | IRQF_DISABLED, dev->name, self);
1362   if (rc)
1363         return rc;
1364
1365   spin_lock_irqsave(&self->spinlock, flags);
1366   toshoboe_startchip (self);
1367   spin_unlock_irqrestore(&self->spinlock, flags);
1368
1369   /* Ready to play! */
1370   netif_start_queue(dev);
1371
1372   /*
1373    * Open new IrLAP layer instance, now that everything should be
1374    * initialized properly
1375    */
1376   self->irlap = irlap_open (dev, &self->qos, driver_name);
1377
1378   self->irdad = 1;
1379
1380   return 0;
1381 }
1382
1383 static int
1384 toshoboe_net_close (struct net_device *dev)
1385 {
1386   struct toshoboe_cb *self;
1387
1388   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1389
1390   IRDA_ASSERT (dev != NULL, return -1; );
1391   self = (struct toshoboe_cb *) dev->priv;
1392
1393   /* Stop device */
1394   netif_stop_queue(dev);
1395
1396   /* Stop and remove instance of IrLAP */
1397   if (self->irlap)
1398     irlap_close (self->irlap);
1399   self->irlap = NULL;
1400
1401   self->irdad = 0;
1402
1403   free_irq (self->io.irq, (void *) self);
1404
1405   if (!self->stopped)
1406     {
1407       toshoboe_stopchip (self);
1408     }
1409
1410   return 0;
1411 }
1412
1413 /*
1414  * Function toshoboe_net_ioctl (dev, rq, cmd)
1415  *
1416  *    Process IOCTL commands for this device
1417  *
1418  */
1419 static int
1420 toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1421 {
1422   struct if_irda_req *irq = (struct if_irda_req *) rq;
1423   struct toshoboe_cb *self;
1424   unsigned long flags;
1425   int ret = 0;
1426
1427   IRDA_ASSERT (dev != NULL, return -1; );
1428
1429   self = dev->priv;
1430
1431   IRDA_ASSERT (self != NULL, return -1; );
1432
1433   IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1434
1435   /* Disable interrupts & save flags */
1436   spin_lock_irqsave(&self->spinlock, flags);
1437
1438   switch (cmd)
1439     {
1440     case SIOCSBANDWIDTH:       /* Set bandwidth */
1441       /* This function will also be used by IrLAP to change the
1442        * speed, so we still must allow for speed change within
1443        * interrupt context.
1444        */
1445       IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
1446           ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1447       if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1448         ret = -EPERM;
1449         goto out;
1450       }
1451
1452       /* self->speed=irq->ifr_baudrate; */
1453       /* toshoboe_setbaud(self); */
1454       /* Just change speed once - inserted by Paul Bristow */
1455       self->new_speed = irq->ifr_baudrate;
1456       break;
1457     case SIOCSMEDIABUSY:       /* Set media busy */
1458       IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
1459           ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1460       if (!capable (CAP_NET_ADMIN)) {
1461         ret = -EPERM;
1462         goto out;
1463       }
1464       irda_device_set_media_busy (self->netdev, TRUE);
1465       break;
1466     case SIOCGRECEIVING:       /* Check if we are receiving right now */
1467       irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0;
1468       IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __FUNCTION__
1469           ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving );
1470       break;
1471     default:
1472       IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1473       ret = -EOPNOTSUPP;
1474     }
1475 out:
1476   spin_unlock_irqrestore(&self->spinlock, flags);
1477   return ret;
1478
1479 }
1480
1481 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
1482 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
1483 MODULE_LICENSE("GPL");
1484
1485 module_param (max_baud, int, 0);
1486 MODULE_PARM_DESC(max_baud, "Maximum baud rate");
1487
1488 #ifdef USE_PROBE
1489 module_param (do_probe, bool, 0);
1490 MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
1491 #endif
1492
1493 static void
1494 toshoboe_close (struct pci_dev *pci_dev)
1495 {
1496   int i;
1497   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1498
1499   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1500
1501   IRDA_ASSERT (self != NULL, return; );
1502
1503   if (!self->stopped)
1504     {
1505       toshoboe_stopchip (self);
1506     }
1507
1508   release_region (self->io.fir_base, self->io.fir_ext);
1509
1510   for (i = 0; i < TX_SLOTS; ++i)
1511     {
1512       kfree (self->tx_bufs[i]);
1513       self->tx_bufs[i] = NULL;
1514     }
1515
1516   for (i = 0; i < RX_SLOTS; ++i)
1517     {
1518       kfree (self->rx_bufs[i]);
1519       self->rx_bufs[i] = NULL;
1520     }
1521
1522   unregister_netdev(self->netdev);
1523
1524   kfree (self->ringbuf);
1525   self->ringbuf = NULL;
1526   self->ring = NULL;
1527
1528   free_netdev(self->netdev);
1529 }
1530
1531 static int
1532 toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
1533 {
1534   struct toshoboe_cb *self;
1535   struct net_device *dev;
1536   int i = 0;
1537   int ok = 0;
1538   int err;
1539
1540   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1541
1542   if ((err=pci_enable_device(pci_dev)))
1543     return err;
1544
1545   dev = alloc_irdadev(sizeof (struct toshoboe_cb));
1546   if (dev == NULL)
1547     {
1548       printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
1549               "IrDA control block\n");
1550       return -ENOMEM;
1551     }
1552
1553   self = dev->priv;
1554   self->netdev = dev;
1555   self->pdev = pci_dev;
1556   self->base = pci_resource_start(pci_dev,0);
1557
1558   self->io.fir_base = self->base;
1559   self->io.fir_ext = OBOE_IO_EXTENT;
1560   self->io.irq = pci_dev->irq;
1561   self->io.irqflags = IRQF_SHARED | IRQF_DISABLED;
1562
1563   self->speed = self->io.speed = 9600;
1564   self->async = 0;
1565
1566   /* Lock the port that we need */
1567   if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name))
1568     {
1569       printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n"
1570               ,self->io.fir_base);
1571       err = -EBUSY;
1572       goto freeself;
1573     }
1574
1575   spin_lock_init(&self->spinlock);
1576
1577   irda_init_max_qos_capabilies (&self->qos);
1578   self->qos.baud_rate.bits = 0;
1579
1580   if (max_baud >= 2400)
1581     self->qos.baud_rate.bits |= IR_2400;
1582   /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
1583   if (max_baud >= 9600)
1584     self->qos.baud_rate.bits |= IR_9600;
1585   if (max_baud >= 19200)
1586     self->qos.baud_rate.bits |= IR_19200;
1587   if (max_baud >= 115200)
1588     self->qos.baud_rate.bits |= IR_115200;
1589 #ifdef USE_MIR
1590   if (max_baud >= 1152000)
1591     {
1592       self->qos.baud_rate.bits |= IR_1152000;
1593     }
1594 #endif
1595   if (max_baud >= 4000000)
1596     {
1597       self->qos.baud_rate.bits |= (IR_4000000 << 8);
1598     }
1599
1600   /*FIXME: work this out... */
1601   self->qos.min_turn_time.bits = 0xff;
1602
1603   irda_qos_bits_to_value (&self->qos);
1604
1605   /* Allocate twice the size to guarantee alignment */
1606   self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL);
1607   if (!self->ringbuf)
1608     {
1609       printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
1610       err = -ENOMEM;
1611       goto freeregion;
1612     }
1613
1614 #if (BITS_PER_LONG == 64)
1615 #error broken on 64-bit:  casts pointer to 32-bit, and then back to pointer.
1616 #endif
1617
1618   /*We need to align the taskfile on a taskfile size boundary */
1619   {
1620     unsigned long addr;
1621
1622     addr = (__u32) self->ringbuf;
1623     addr &= ~(OBOE_RING_LEN - 1);
1624     addr += OBOE_RING_LEN;
1625     self->ring = (struct OboeRing *) addr;
1626   }
1627
1628   memset (self->ring, 0, OBOE_RING_LEN);
1629   self->io.mem_base = (__u32) self->ring;
1630
1631   ok = 1;
1632   for (i = 0; i < TX_SLOTS; ++i)
1633     {
1634       self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL);
1635       if (!self->tx_bufs[i])
1636         ok = 0;
1637     }
1638
1639   for (i = 0; i < RX_SLOTS; ++i)
1640     {
1641       self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL);
1642       if (!self->rx_bufs[i])
1643         ok = 0;
1644     }
1645
1646   if (!ok)
1647     {
1648       printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n");
1649       err = -ENOMEM;
1650       goto freebufs;
1651     }
1652
1653
1654 #ifdef USE_PROBE
1655   if (do_probe)
1656     if (!toshoboe_probe (self))
1657       {
1658         err = -ENODEV;
1659         goto freebufs;
1660       }
1661 #endif
1662
1663   SET_MODULE_OWNER(dev);
1664   SET_NETDEV_DEV(dev, &pci_dev->dev);
1665   dev->hard_start_xmit = toshoboe_hard_xmit;
1666   dev->open = toshoboe_net_open;
1667   dev->stop = toshoboe_net_close;
1668   dev->do_ioctl = toshoboe_net_ioctl;
1669
1670   err = register_netdev(dev);
1671   if (err)
1672     {
1673       printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
1674       err = -ENOMEM;
1675       goto freebufs;
1676     }
1677   printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
1678
1679   pci_set_drvdata(pci_dev,self);
1680
1681   printk (KERN_INFO DRIVER_NAME ": Using multiple tasks, version %s\n", rcsid);
1682
1683   return 0;
1684
1685 freebufs:
1686   for (i = 0; i < TX_SLOTS; ++i)
1687     kfree (self->tx_bufs[i]);
1688   for (i = 0; i < RX_SLOTS; ++i)
1689     kfree (self->rx_bufs[i]);
1690   kfree(self->ringbuf);
1691
1692 freeregion:
1693   release_region (self->io.fir_base, self->io.fir_ext);
1694
1695 freeself:
1696   free_netdev(dev);
1697
1698   return err;
1699 }
1700
1701 static int
1702 toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
1703 {
1704   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1705   unsigned long flags;
1706   int i = 10;
1707
1708   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1709
1710   if (!self || self->stopped)
1711     return 0;
1712
1713   if ((!self->irdad) && (!self->async))
1714     return 0;
1715
1716 /* Flush all packets */
1717   while ((i--) && (self->txpending))
1718     udelay (10000);
1719
1720   spin_lock_irqsave(&self->spinlock, flags);
1721
1722   toshoboe_stopchip (self);
1723   self->stopped = 1;
1724   self->txpending = 0;
1725
1726   spin_unlock_irqrestore(&self->spinlock, flags);
1727   return 0;
1728 }
1729
1730 static int
1731 toshoboe_wakeup (struct pci_dev *pci_dev)
1732 {
1733   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
1734   unsigned long flags;
1735
1736   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
1737
1738   if (!self || !self->stopped)
1739     return 0;
1740
1741   if ((!self->irdad) && (!self->async))
1742     return 0;
1743
1744   spin_lock_irqsave(&self->spinlock, flags);
1745
1746   toshoboe_startchip (self);
1747   self->stopped = 0;
1748
1749   netif_wake_queue(self->netdev);
1750   spin_unlock_irqrestore(&self->spinlock, flags);
1751   return 0;
1752 }
1753
1754 static struct pci_driver donauboe_pci_driver = {
1755         .name           = "donauboe",
1756         .id_table       = toshoboe_pci_tbl,
1757         .probe          = toshoboe_open,
1758         .remove         = toshoboe_close,
1759         .suspend        = toshoboe_gotosleep,
1760         .resume         = toshoboe_wakeup 
1761 };
1762
1763 static int __init
1764 donauboe_init (void)
1765 {
1766   return pci_register_driver(&donauboe_pci_driver);
1767 }
1768
1769 static void __exit
1770 donauboe_cleanup (void)
1771 {
1772   pci_unregister_driver(&donauboe_pci_driver);
1773 }
1774
1775 module_init(donauboe_init);
1776 module_exit(donauboe_cleanup);