Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/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 recommended, 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/interrupt.h>
156 #include <linux/pci.h>
157 #include <linux/rtnetlink.h>
158 
159 #include <asm/io.h>
160 
161 #include <net/irda/wrapper.h>
162 #include <net/irda/irda.h>
163 //#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 const struct pci_device_id 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 bool do_probe = false;
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   static const int bauds[] = { 9600, 115200, 4000000, 1152000 };
822 #else
823   static const int bauds[] = { 9600, 115200, 4000000 };
824 #endif
825   unsigned long flags;
826 
827   IRDA_DEBUG (4, "%s()\n", __func__);
828 
829   if (request_irq (self->io.irq, toshoboe_probeinterrupt,
830                    self->io.irqflags, "toshoboe", (void *) self))
831     {
832       printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n",
833               self->io.irq);
834       return 0;
835     }
836 
837   /* 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  /* Check if we need to change the speed */
1006   /* But not now. Wait after transmission if mtt not required */
1007   speed=irda_get_next_speed(skb);
1008   if ((speed != self->io.speed) && (speed != -1))
1009     {
1010       spin_lock_irqsave(&self->spinlock, flags);
1011 
1012       if (self->txpending || skb->len)
1013         {
1014           self->new_speed = speed;
1015           IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" ,
1016                       __func__, speed);
1017           /* if no data, that's all! */
1018           if (!skb->len)
1019             {
1020               spin_unlock_irqrestore(&self->spinlock, flags);
1021               dev_kfree_skb (skb);
1022               return NETDEV_TX_OK;
1023             }
1024           /* True packet, go on, but */
1025           /* do not accept anything before change speed execution */
1026           netif_stop_queue(dev);
1027           /* ready to process TxDone interrupt */
1028           spin_unlock_irqrestore(&self->spinlock, flags);
1029         }
1030       else
1031         {
1032           /* idle and no data, change speed now */
1033           self->speed = speed;
1034           toshoboe_setbaud (self);
1035           spin_unlock_irqrestore(&self->spinlock, flags);
1036           dev_kfree_skb (skb);
1037           return NETDEV_TX_OK;
1038         }
1039 
1040     }
1041 
1042   if ((mtt = irda_get_mtt(skb)))
1043     {
1044       /* This is fair since the queue should be empty anyway */
1045       spin_lock_irqsave(&self->spinlock, flags);
1046 
1047       if (self->txpending)
1048         {
1049           spin_unlock_irqrestore(&self->spinlock, flags);
1050           return NETDEV_TX_BUSY;
1051         }
1052 
1053       /* If in SIR mode we need to generate a string of XBOFs */
1054       /* In MIR and FIR we need to generate a string of data */
1055       /* which we will add a wrong checksum to */
1056 
1057       mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt);
1058       IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __func__
1059           ,skb->len,mtt,self->txpending);
1060       if (mtt)
1061         {
1062           self->ring->tx[self->txs].len = mtt & 0xfff;
1063 
1064           ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1065           if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1066             {
1067               ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ;
1068             }
1069 #ifdef USE_MIR
1070           else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON)
1071             {
1072               ctl |= OBOE_CTL_TX_BAD_CRC;
1073             }
1074 #endif
1075           self->ring->tx[self->txs].control = ctl;
1076 
1077           OUTB (0x0, OBOE_ENABLEH);
1078           /* It is only a timer. Do not send mtt packet outside! */
1079           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
1080 
1081           self->txpending++;
1082 
1083           self->txs++;
1084           self->txs %= TX_SLOTS;
1085 
1086         }
1087       else
1088         {
1089           printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n");
1090         }
1091       spin_unlock_irqrestore(&self->spinlock, flags);
1092     }
1093 
1094 #ifdef DUMP_PACKETS
1095 dumpbufs(skb->data,skb->len,'>');
1096 #endif
1097 
1098   spin_lock_irqsave(&self->spinlock, flags);
1099 
1100   if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS)
1101     {
1102       IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __func__
1103           ,skb->len, self->ring->tx[self->txs].control, self->txpending);
1104       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1105       spin_unlock_irqrestore(&self->spinlock, flags);
1106       return NETDEV_TX_BUSY;
1107     }
1108 
1109   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
1110     {
1111       len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ);
1112     }
1113   else
1114     {
1115       len = skb->len;
1116       skb_copy_from_linear_data(skb, self->tx_bufs[self->txs], len);
1117     }
1118   self->ring->tx[self->txs].len = len & 0x0fff;
1119 
1120   /*Sometimes the HW doesn't see us assert RTCENTX in the interrupt code */
1121   /*later this plays safe, we garuntee the last packet to be transmitted */
1122   /*has RTCENTX set */
1123 
1124   ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1125   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1126     {
1127       ctl |= OBOE_CTL_TX_SIP ;
1128     }
1129   self->ring->tx[self->txs].control = ctl;
1130 
1131   /* If transmitter is idle start in one-shot mode */
1132 
1133   if (!self->txpending)
1134       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1135 
1136   self->txpending++;
1137 
1138   self->txs++;
1139   self->txs %= TX_SLOTS;
1140 
1141   spin_unlock_irqrestore(&self->spinlock, flags);
1142   dev_kfree_skb (skb);
1143 
1144   return NETDEV_TX_OK;
1145 }
1146 
1147 /*interrupt handler */
1148 static irqreturn_t
1149 toshoboe_interrupt (int irq, void *dev_id)
1150 {
1151   struct toshoboe_cb *self = dev_id;
1152   __u8 irqstat;
1153   struct sk_buff *skb = NULL;
1154 
1155   irqstat = INB (OBOE_ISR);
1156 
1157 /* was it us */
1158   if (!(irqstat & OBOE_INT_MASK))
1159       return IRQ_NONE;
1160 
1161 /* Ack all the interrupts */
1162   OUTB (irqstat, OBOE_ISR);
1163 
1164   toshoboe_isntstuck (self);
1165 
1166 /* Txdone */
1167   if (irqstat & OBOE_INT_TXDONE)
1168     {
1169       int txp, txpc;
1170       int i;
1171 
1172       txp = self->txpending;
1173       self->txpending = 0;
1174 
1175       for (i = 0; i < TX_SLOTS; ++i)
1176         {
1177           if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS)
1178               self->txpending++;
1179         }
1180       IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __func__
1181           ,irqstat,txp,self->txpending);
1182 
1183       txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
1184 
1185       /* Got anything queued ? start it together */
1186       if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
1187         {
1188           txpc = txp;
1189 #ifdef OPTIMIZE_TX
1190           while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1191             {
1192               txp = txpc;
1193               txpc++;
1194               txpc %= TX_SLOTS;
1195               self->netdev->stats.tx_packets++;
1196               if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1197                   self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
1198             }
1199           self->netdev->stats.tx_packets--;
1200 #else
1201           self->netdev->stats.tx_packets++;
1202 #endif
1203           toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1204         }
1205 
1206       if ((!self->txpending) && (self->new_speed))
1207         {
1208           self->speed = self->new_speed;
1209           IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n",
1210                       __func__, self->speed);
1211           toshoboe_setbaud (self);
1212         }
1213 
1214       /* Tell network layer that we want more frames */
1215       if (!self->new_speed)
1216           netif_wake_queue(self->netdev);
1217     }
1218 
1219   if (irqstat & OBOE_INT_RXDONE)
1220     {
1221       while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS))
1222         {
1223           int len = self->ring->rx[self->rxs].len;
1224           skb = NULL;
1225           IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __func__
1226                       ,len,self->ring->rx[self->rxs].control);
1227 
1228 #ifdef DUMP_PACKETS
1229 dumpbufs(self->rx_bufs[self->rxs],len,'<');
1230 #endif
1231 
1232           if (self->ring->rx[self->rxs].control == 0)
1233             {
1234               __u8 enable = INB (OBOE_ENABLEH);
1235 
1236               /* In SIR mode we need to check the CRC as this */
1237               /* hasn't been done by the hardware */
1238               if (enable & OBOE_ENABLEH_SIRON)
1239                 {
1240                   if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len))
1241                       len = 0;
1242                   /*Trim off the CRC */
1243                   if (len > 1)
1244                       len -= 2;
1245                   else
1246                       len = 0;
1247                   IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __func__, len,enable);
1248                 }
1249 
1250 #ifdef USE_MIR
1251               else if (enable & OBOE_ENABLEH_MIRON)
1252                 {
1253                   if (len > 1)
1254                       len -= 2;
1255                   else
1256                       len = 0;
1257                   IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __func__, len,enable);
1258                 }
1259 #endif
1260               else if (enable & OBOE_ENABLEH_FIRON)
1261                 {
1262                   if (len > 3)
1263                       len -= 4;   /*FIXME: check this */
1264                   else
1265                       len = 0;
1266                   IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __func__, len,enable);
1267                 }
1268               else
1269                   IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __func__, len,enable);
1270 
1271               if (len)
1272                 {
1273                   skb = dev_alloc_skb (len + 1);
1274                   if (skb)
1275                     {
1276                       skb_reserve (skb, 1);
1277 
1278                       skb_put (skb, len);
1279                       skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs],
1280                                               len);
1281                       self->netdev->stats.rx_packets++;
1282                       skb->dev = self->netdev;
1283                       skb_reset_mac_header(skb);
1284                       skb->protocol = htons (ETH_P_IRDA);
1285                     }
1286                   else
1287                     {
1288                       printk (KERN_INFO
1289                               "%s(), memory squeeze, dropping frame.\n",
1290                               __func__);
1291                     }
1292                 }
1293             }
1294           else
1295             {
1296             /* TODO: =========================================== */
1297             /*  if OBOE_CTL_RX_LENGTH, our buffers are too small */
1298             /* (MIR or FIR) data is lost. */
1299             /* (SIR) data is splitted in several slots. */
1300             /* we have to join all the received buffers received */
1301             /*in a large buffer before checking CRC. */
1302             IRDA_DEBUG (0, "%s.err:%x(%x)\n", __func__
1303                 ,len,self->ring->rx[self->rxs].control);
1304             }
1305 
1306           self->ring->rx[self->rxs].len = 0x0;
1307           self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS;
1308 
1309           self->rxs++;
1310           self->rxs %= RX_SLOTS;
1311 
1312           if (skb)
1313               netif_rx (skb);
1314 
1315         }
1316     }
1317 
1318   if (irqstat & OBOE_INT_TXUNDER)
1319     {
1320       printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n");
1321     }
1322   if (irqstat & OBOE_INT_RXOVER)
1323     {
1324       printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n");
1325     }
1326 /* This must be useful for something... */
1327   if (irqstat & OBOE_INT_SIP)
1328     {
1329       self->int_sip++;
1330       IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __func__
1331               ,self->int_sip,irqstat,self->txpending);
1332     }
1333   return IRQ_HANDLED;
1334 }
1335 
1336 
1337 static int
1338 toshoboe_net_open (struct net_device *dev)
1339 {
1340   struct toshoboe_cb *self;
1341   unsigned long flags;
1342   int rc;
1343 
1344   IRDA_DEBUG (4, "%s()\n", __func__);
1345 
1346   self = netdev_priv(dev);
1347 
1348   if (self->async)
1349     return -EBUSY;
1350 
1351   if (self->stopped)
1352     return 0;
1353 
1354   rc = request_irq (self->io.irq, toshoboe_interrupt,
1355                     IRQF_SHARED, dev->name, self);
1356   if (rc)
1357         return rc;
1358 
1359   spin_lock_irqsave(&self->spinlock, flags);
1360   toshoboe_startchip (self);
1361   spin_unlock_irqrestore(&self->spinlock, flags);
1362 
1363   /* Ready to play! */
1364   netif_start_queue(dev);
1365 
1366   /*
1367    * Open new IrLAP layer instance, now that everything should be
1368    * initialized properly
1369    */
1370   self->irlap = irlap_open (dev, &self->qos, driver_name);
1371 
1372   self->irdad = 1;
1373 
1374   return 0;
1375 }
1376 
1377 static int
1378 toshoboe_net_close (struct net_device *dev)
1379 {
1380   struct toshoboe_cb *self;
1381 
1382   IRDA_DEBUG (4, "%s()\n", __func__);
1383 
1384   IRDA_ASSERT (dev != NULL, return -1; );
1385   self = netdev_priv(dev);
1386 
1387   /* Stop device */
1388   netif_stop_queue(dev);
1389 
1390   /* Stop and remove instance of IrLAP */
1391   if (self->irlap)
1392     irlap_close (self->irlap);
1393   self->irlap = NULL;
1394 
1395   self->irdad = 0;
1396 
1397   free_irq (self->io.irq, (void *) self);
1398 
1399   if (!self->stopped)
1400     {
1401       toshoboe_stopchip (self);
1402     }
1403 
1404   return 0;
1405 }
1406 
1407 /*
1408  * Function toshoboe_net_ioctl (dev, rq, cmd)
1409  *
1410  *    Process IOCTL commands for this device
1411  *
1412  */
1413 static int
1414 toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1415 {
1416   struct if_irda_req *irq = (struct if_irda_req *) rq;
1417   struct toshoboe_cb *self;
1418   unsigned long flags;
1419   int ret = 0;
1420 
1421   IRDA_ASSERT (dev != NULL, return -1; );
1422 
1423   self = netdev_priv(dev);
1424 
1425   IRDA_ASSERT (self != NULL, return -1; );
1426 
1427   IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
1428 
1429   /* Disable interrupts & save flags */
1430   spin_lock_irqsave(&self->spinlock, flags);
1431 
1432   switch (cmd)
1433     {
1434     case SIOCSBANDWIDTH:       /* Set bandwidth */
1435       /* This function will also be used by IrLAP to change the
1436        * speed, so we still must allow for speed change within
1437        * interrupt context.
1438        */
1439       IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __func__
1440           ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1441       if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1442         ret = -EPERM;
1443         goto out;
1444       }
1445 
1446       /* self->speed=irq->ifr_baudrate; */
1447       /* toshoboe_setbaud(self); */
1448       /* Just change speed once - inserted by Paul Bristow */
1449       self->new_speed = irq->ifr_baudrate;
1450       break;
1451     case SIOCSMEDIABUSY:       /* Set media busy */
1452       IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __func__
1453           ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1454       if (!capable (CAP_NET_ADMIN)) {
1455         ret = -EPERM;
1456         goto out;
1457       }
1458       irda_device_set_media_busy (self->netdev, TRUE);
1459       break;
1460     case SIOCGRECEIVING:       /* Check if we are receiving right now */
1461       irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0;
1462       IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __func__
1463           ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving );
1464       break;
1465     default:
1466       IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
1467       ret = -EOPNOTSUPP;
1468     }
1469 out:
1470   spin_unlock_irqrestore(&self->spinlock, flags);
1471   return ret;
1472 
1473 }
1474 
1475 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
1476 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
1477 MODULE_LICENSE("GPL");
1478 
1479 module_param (max_baud, int, 0);
1480 MODULE_PARM_DESC(max_baud, "Maximum baud rate");
1481 
1482 #ifdef USE_PROBE
1483 module_param (do_probe, bool, 0);
1484 MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
1485 #endif
1486 
1487 static void
1488 toshoboe_close (struct pci_dev *pci_dev)
1489 {
1490   int i;
1491   struct toshoboe_cb *self = pci_get_drvdata(pci_dev);
1492 
1493   IRDA_DEBUG (4, "%s()\n", __func__);
1494 
1495   IRDA_ASSERT (self != NULL, return; );
1496 
1497   if (!self->stopped)
1498     {
1499       toshoboe_stopchip (self);
1500     }
1501 
1502   release_region (self->io.fir_base, self->io.fir_ext);
1503 
1504   for (i = 0; i < TX_SLOTS; ++i)
1505     {
1506       kfree (self->tx_bufs[i]);
1507       self->tx_bufs[i] = NULL;
1508     }
1509 
1510   for (i = 0; i < RX_SLOTS; ++i)
1511     {
1512       kfree (self->rx_bufs[i]);
1513       self->rx_bufs[i] = NULL;
1514     }
1515 
1516   unregister_netdev(self->netdev);
1517 
1518   kfree (self->ringbuf);
1519   self->ringbuf = NULL;
1520   self->ring = NULL;
1521 
1522   free_netdev(self->netdev);
1523 }
1524 
1525 static const struct net_device_ops toshoboe_netdev_ops = {
1526         .ndo_open       = toshoboe_net_open,
1527         .ndo_stop       = toshoboe_net_close,
1528         .ndo_start_xmit = toshoboe_hard_xmit,
1529         .ndo_do_ioctl   = toshoboe_net_ioctl,
1530 };
1531 
1532 static int
1533 toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
1534 {
1535   struct toshoboe_cb *self;
1536   struct net_device *dev;
1537   int i = 0;
1538   int ok = 0;
1539   int err;
1540 
1541   IRDA_DEBUG (4, "%s()\n", __func__);
1542 
1543   if ((err=pci_enable_device(pci_dev)))
1544     return err;
1545 
1546   dev = alloc_irdadev(sizeof (struct toshoboe_cb));
1547   if (dev == NULL)
1548     {
1549       printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
1550               "IrDA control block\n");
1551       return -ENOMEM;
1552     }
1553 
1554   self = netdev_priv(dev);
1555   self->netdev = dev;
1556   self->pdev = pci_dev;
1557   self->base = pci_resource_start(pci_dev,0);
1558 
1559   self->io.fir_base = self->base;
1560   self->io.fir_ext = OBOE_IO_EXTENT;
1561   self->io.irq = pci_dev->irq;
1562   self->io.irqflags = IRQF_SHARED;
1563 
1564   self->speed = self->io.speed = 9600;
1565   self->async = 0;
1566 
1567   /* Lock the port that we need */
1568   if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name))
1569     {
1570       printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n"
1571               ,self->io.fir_base);
1572       err = -EBUSY;
1573       goto freeself;
1574     }
1575 
1576   spin_lock_init(&self->spinlock);
1577 
1578   irda_init_max_qos_capabilies (&self->qos);
1579   self->qos.baud_rate.bits = 0;
1580 
1581   if (max_baud >= 2400)
1582     self->qos.baud_rate.bits |= IR_2400;
1583   /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
1584   if (max_baud >= 9600)
1585     self->qos.baud_rate.bits |= IR_9600;
1586   if (max_baud >= 19200)
1587     self->qos.baud_rate.bits |= IR_19200;
1588   if (max_baud >= 115200)
1589     self->qos.baud_rate.bits |= IR_115200;
1590 #ifdef USE_MIR
1591   if (max_baud >= 1152000)
1592     {
1593       self->qos.baud_rate.bits |= IR_1152000;
1594     }
1595 #endif
1596   if (max_baud >= 4000000)
1597     {
1598       self->qos.baud_rate.bits |= (IR_4000000 << 8);
1599     }
1600 
1601   /*FIXME: work this out... */
1602   self->qos.min_turn_time.bits = 0xff;
1603 
1604   irda_qos_bits_to_value (&self->qos);
1605 
1606   /* Allocate twice the size to guarantee alignment */
1607   self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL);
1608   if (!self->ringbuf)
1609     {
1610       err = -ENOMEM;
1611       goto freeregion;
1612     }
1613 
1614 #if (BITS_PER_LONG == 64)
1615 #error broken on 64-bit:  casts pointer to 32-bit, and then back to pointer.
1616 #endif
1617 
1618   /*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       err = -ENOMEM;
1649       goto freebufs;
1650     }
1651 
1652 
1653 #ifdef USE_PROBE
1654   if (do_probe)
1655     if (!toshoboe_probe (self))
1656       {
1657         err = -ENODEV;
1658         goto freebufs;
1659       }
1660 #endif
1661 
1662   SET_NETDEV_DEV(dev, &pci_dev->dev);
1663   dev->netdev_ops = &toshoboe_netdev_ops;
1664 
1665   err = register_netdev(dev);
1666   if (err)
1667     {
1668       printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
1669       err = -ENOMEM;
1670       goto freebufs;
1671     }
1672   printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
1673 
1674   pci_set_drvdata(pci_dev,self);
1675 
1676   printk (KERN_INFO DRIVER_NAME ": Using multiple tasks\n");
1677 
1678   return 0;
1679 
1680 freebufs:
1681   for (i = 0; i < TX_SLOTS; ++i)
1682     kfree (self->tx_bufs[i]);
1683   for (i = 0; i < RX_SLOTS; ++i)
1684     kfree (self->rx_bufs[i]);
1685   kfree(self->ringbuf);
1686 
1687 freeregion:
1688   release_region (self->io.fir_base, self->io.fir_ext);
1689 
1690 freeself:
1691   free_netdev(dev);
1692 
1693   return err;
1694 }
1695 
1696 static int
1697 toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
1698 {
1699   struct toshoboe_cb *self = pci_get_drvdata(pci_dev);
1700   unsigned long flags;
1701   int i = 10;
1702 
1703   IRDA_DEBUG (4, "%s()\n", __func__);
1704 
1705   if (!self || self->stopped)
1706     return 0;
1707 
1708   if ((!self->irdad) && (!self->async))
1709     return 0;
1710 
1711 /* Flush all packets */
1712   while ((i--) && (self->txpending))
1713     msleep(10);
1714 
1715   spin_lock_irqsave(&self->spinlock, flags);
1716 
1717   toshoboe_stopchip (self);
1718   self->stopped = 1;
1719   self->txpending = 0;
1720 
1721   spin_unlock_irqrestore(&self->spinlock, flags);
1722   return 0;
1723 }
1724 
1725 static int
1726 toshoboe_wakeup (struct pci_dev *pci_dev)
1727 {
1728   struct toshoboe_cb *self = pci_get_drvdata(pci_dev);
1729   unsigned long flags;
1730 
1731   IRDA_DEBUG (4, "%s()\n", __func__);
1732 
1733   if (!self || !self->stopped)
1734     return 0;
1735 
1736   if ((!self->irdad) && (!self->async))
1737     return 0;
1738 
1739   spin_lock_irqsave(&self->spinlock, flags);
1740 
1741   toshoboe_startchip (self);
1742   self->stopped = 0;
1743 
1744   netif_wake_queue(self->netdev);
1745   spin_unlock_irqrestore(&self->spinlock, flags);
1746   return 0;
1747 }
1748 
1749 static struct pci_driver donauboe_pci_driver = {
1750         .name           = "donauboe",
1751         .id_table       = toshoboe_pci_tbl,
1752         .probe          = toshoboe_open,
1753         .remove         = toshoboe_close,
1754         .suspend        = toshoboe_gotosleep,
1755         .resume         = toshoboe_wakeup 
1756 };
1757 
1758 module_pci_driver(donauboe_pci_driver);
1759 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us