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