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