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