Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.18-rc6 1791 lines 49 kB view raw
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 660static int toshoboe_invalid_dev(int irq) 661{ 662 printk (KERN_WARNING DRIVER_NAME ": irq %d for unknown device.\n", irq); 663 return 1; 664} 665 666#ifdef USE_PROBE 667/***********************************************************************/ 668/* Probe code */ 669 670static void 671toshoboe_dumptx (struct toshoboe_cb *self) 672{ 673 int i; 674 PROBE_DEBUG(KERN_WARNING "TX:"); 675 for (i = 0; i < RX_SLOTS; ++i) 676 PROBE_DEBUG(" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control); 677 PROBE_DEBUG(" [%d]\n",self->speed); 678} 679 680static void 681toshoboe_dumprx (struct toshoboe_cb *self, int score) 682{ 683 int i; 684 PROBE_DEBUG(" %d\nRX:",score); 685 for (i = 0; i < RX_SLOTS; ++i) 686 PROBE_DEBUG(" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control); 687 PROBE_DEBUG("\n"); 688} 689 690static inline int 691stuff_byte (__u8 byte, __u8 * buf) 692{ 693 switch (byte) 694 { 695 case BOF: /* FALLTHROUGH */ 696 case EOF: /* FALLTHROUGH */ 697 case CE: 698 /* Insert transparently coded */ 699 buf[0] = CE; /* Send link escape */ 700 buf[1] = byte ^ IRDA_TRANS; /* Complement bit 5 */ 701 return 2; 702 /* break; */ 703 default: 704 /* Non-special value, no transparency required */ 705 buf[0] = byte; 706 return 1; 707 /* break; */ 708 } 709} 710 711static irqreturn_t 712toshoboe_probeinterrupt (int irq, void *dev_id, struct pt_regs *regs) 713{ 714 struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id; 715 __u8 irqstat; 716 717 if (self == NULL && toshoboe_invalid_dev(irq)) 718 return IRQ_NONE; 719 720 irqstat = INB (OBOE_ISR); 721 722/* was it us */ 723 if (!(irqstat & OBOE_INT_MASK)) 724 return IRQ_NONE; 725 726/* Ack all the interrupts */ 727 OUTB (irqstat, OBOE_ISR); 728 729 if (irqstat & OBOE_INT_TXDONE) 730 { 731 int txp; 732 733 self->int_tx++; 734 PROBE_DEBUG("T"); 735 736 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK; 737 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS) 738 { 739 self->int_tx+=100; 740 PROBE_DEBUG("S"); 741 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP); 742 } 743 } 744 745 if (irqstat & OBOE_INT_RXDONE) { 746 self->int_rx++; 747 PROBE_DEBUG("R"); } 748 if (irqstat & OBOE_INT_TXUNDER) { 749 self->int_txunder++; 750 PROBE_DEBUG("U"); } 751 if (irqstat & OBOE_INT_RXOVER) { 752 self->int_rxover++; 753 PROBE_DEBUG("O"); } 754 if (irqstat & OBOE_INT_SIP) { 755 self->int_sip++; 756 PROBE_DEBUG("I"); } 757 return IRQ_HANDLED; 758} 759 760static int 761toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir) 762{ 763 int i; 764 int len = 0; 765 union 766 { 767 __u16 value; 768 __u8 bytes[2]; 769 } 770 fcs; 771 772 if (fir) 773 { 774 memset (buf, 0, TT_LEN); 775 return (TT_LEN); 776 } 777 778 fcs.value = INIT_FCS; 779 780 memset (buf, XBOF, 10); 781 len += 10; 782 buf[len++] = BOF; 783 784 for (i = 0; i < TT_LEN; ++i) 785 { 786 len += stuff_byte (i, buf + len); 787 fcs.value = irda_fcs (fcs.value, i); 788 } 789 790 len += stuff_byte (fcs.bytes[0] ^ badcrc, buf + len); 791 len += stuff_byte (fcs.bytes[1] ^ badcrc, buf + len); 792 buf[len++] = EOF; 793 len++; 794 return len; 795} 796 797static int 798toshoboe_probefail (struct toshoboe_cb *self, char *msg) 799{ 800 printk (KERN_ERR DRIVER_NAME "probe(%d) failed %s\n",self-> speed, msg); 801 toshoboe_dumpregs (self); 802 toshoboe_stopchip (self); 803 free_irq (self->io.irq, (void *) self); 804 return 0; 805} 806 807static int 808toshoboe_numvalidrcvs (struct toshoboe_cb *self) 809{ 810 int i, ret = 0; 811 for (i = 0; i < RX_SLOTS; ++i) 812 if ((self->ring->rx[i].control & 0xe0) == 0) 813 ret++; 814 815 return ret; 816} 817 818static int 819toshoboe_numrcvs (struct toshoboe_cb *self) 820{ 821 int i, ret = 0; 822 for (i = 0; i < RX_SLOTS; ++i) 823 if (!(self->ring->rx[i].control & OBOE_CTL_RX_HW_OWNS)) 824 ret++; 825 826 return ret; 827} 828 829static int 830toshoboe_probe (struct toshoboe_cb *self) 831{ 832 int i, j, n; 833#ifdef USE_MIR 834 int bauds[] = { 9600, 115200, 4000000, 1152000 }; 835#else 836 int bauds[] = { 9600, 115200, 4000000 }; 837#endif 838 unsigned long flags; 839 840 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 841 842 if (request_irq (self->io.irq, toshoboe_probeinterrupt, 843 self->io.irqflags, "toshoboe", (void *) self)) 844 { 845 printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n", 846 self->io.irq); 847 return 0; 848 } 849 850 /* test 1: SIR filter and back to back */ 851 852 for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j) 853 { 854 int fir = (j > 1); 855 toshoboe_stopchip (self); 856 857 858 spin_lock_irqsave(&self->spinlock, flags); 859 /*Address is already setup */ 860 toshoboe_startchip (self); 861 self->int_rx = self->int_tx = 0; 862 self->speed = bauds[j]; 863 toshoboe_setbaud (self); 864 toshoboe_initptrs (self); 865 spin_unlock_irqrestore(&self->spinlock, flags); 866 867 self->ring->tx[self->txs].control = 868/* (FIR only) OBOE_CTL_TX_SIP needed for switching to next slot */ 869/* MIR: all received data is stored in one slot */ 870 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX 871 : OBOE_CTL_TX_HW_OWNS ; 872 self->ring->tx[self->txs].len = 873 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir); 874 self->txs++; 875 self->txs %= TX_SLOTS; 876 877 self->ring->tx[self->txs].control = 878 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_SIP 879 : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ; 880 self->ring->tx[self->txs].len = 881 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir); 882 self->txs++; 883 self->txs %= TX_SLOTS; 884 885 self->ring->tx[self->txs].control = 886 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX 887 : OBOE_CTL_TX_HW_OWNS ; 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 self->ring->tx[self->txs].control = 894 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX 895 | OBOE_CTL_TX_SIP | OBOE_CTL_TX_BAD_CRC 896 : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ; 897 self->ring->tx[self->txs].len = 898 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir); 899 self->txs++; 900 self->txs %= TX_SLOTS; 901 902 toshoboe_dumptx (self); 903 /* Turn on TX and RX and loopback */ 904 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP); 905 906 i = 0; 907 n = fir ? 1 : 4; 908 while (toshoboe_numvalidrcvs (self) != n) 909 { 910 if (i > 4800) 911 return toshoboe_probefail (self, "filter test"); 912 udelay ((9600*(TT_LEN+16))/self->speed); 913 i++; 914 } 915 916 n = fir ? 203 : 102; 917 while ((toshoboe_numrcvs(self) != self->int_rx) || (self->int_tx != n)) 918 { 919 if (i > 4800) 920 return toshoboe_probefail (self, "interrupt test"); 921 udelay ((9600*(TT_LEN+16))/self->speed); 922 i++; 923 } 924 toshoboe_dumprx (self,i); 925 926 } 927 928 /* test 2: SIR in char at a time */ 929 930 toshoboe_stopchip (self); 931 self->int_rx = self->int_tx = 0; 932 933 spin_lock_irqsave(&self->spinlock, flags); 934 toshoboe_startchip (self); 935 spin_unlock_irqrestore(&self->spinlock, flags); 936 937 self->async = 1; 938 self->speed = 115200; 939 toshoboe_setbaud (self); 940 self->ring->tx[self->txs].control = 941 OBOE_CTL_TX_RTCENTX | OBOE_CTL_TX_HW_OWNS; 942 self->ring->tx[self->txs].len = 4; 943 944 ((unsigned char *) self->tx_bufs[self->txs])[0] = 'f'; 945 ((unsigned char *) self->tx_bufs[self->txs])[1] = 'i'; 946 ((unsigned char *) self->tx_bufs[self->txs])[2] = 's'; 947 ((unsigned char *) self->tx_bufs[self->txs])[3] = 'h'; 948 toshoboe_dumptx (self); 949 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP); 950 951 i = 0; 952 while (toshoboe_numvalidrcvs (self) != 4) 953 { 954 if (i > 100) 955 return toshoboe_probefail (self, "Async test"); 956 udelay (100); 957 i++; 958 } 959 960 while ((toshoboe_numrcvs (self) != self->int_rx) || (self->int_tx != 1)) 961 { 962 if (i > 100) 963 return toshoboe_probefail (self, "Async interrupt test"); 964 udelay (100); 965 i++; 966 } 967 toshoboe_dumprx (self,i); 968 969 self->async = 0; 970 self->speed = 9600; 971 toshoboe_setbaud (self); 972 toshoboe_stopchip (self); 973 974 free_irq (self->io.irq, (void *) self); 975 976 printk (KERN_WARNING DRIVER_NAME ": Self test passed ok\n"); 977 978 return 1; 979} 980#endif 981 982/******************************************************************/ 983/* Netdev style code */ 984 985/* Transmit something */ 986static int 987toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) 988{ 989 struct toshoboe_cb *self; 990 __s32 speed; 991 int mtt, len, ctl; 992 unsigned long flags; 993 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb; 994 995 self = (struct toshoboe_cb *) dev->priv; 996 997 IRDA_ASSERT (self != NULL, return 0; ); 998 999 IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __FUNCTION__ 1000 ,skb->len,self->txpending,INB (OBOE_ENABLEH)); 1001 if (!cb->magic) { 1002 IRDA_DEBUG (2, "%s.Not IrLAP:%x\n", __FUNCTION__, cb->magic); 1003#ifdef DUMP_PACKETS 1004 _dumpbufs(skb->data,skb->len,'>'); 1005#endif 1006 } 1007 1008 /* change speed pending, wait for its execution */ 1009 if (self->new_speed) 1010 return -EBUSY; 1011 1012 /* device stopped (apm) wait for restart */ 1013 if (self->stopped) 1014 return -EBUSY; 1015 1016 toshoboe_checkstuck (self); 1017 1018 dev->trans_start = jiffies; 1019 1020 /* Check if we need to change the speed */ 1021 /* But not now. Wait after transmission if mtt not required */ 1022 speed=irda_get_next_speed(skb); 1023 if ((speed != self->io.speed) && (speed != -1)) 1024 { 1025 spin_lock_irqsave(&self->spinlock, flags); 1026 1027 if (self->txpending || skb->len) 1028 { 1029 self->new_speed = speed; 1030 IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" , 1031 __FUNCTION__, speed); 1032 /* if no data, that's all! */ 1033 if (!skb->len) 1034 { 1035 spin_unlock_irqrestore(&self->spinlock, flags); 1036 dev_kfree_skb (skb); 1037 return 0; 1038 } 1039 /* True packet, go on, but */ 1040 /* do not accept anything before change speed execution */ 1041 netif_stop_queue(dev); 1042 /* ready to process TxDone interrupt */ 1043 spin_unlock_irqrestore(&self->spinlock, flags); 1044 } 1045 else 1046 { 1047 /* idle and no data, change speed now */ 1048 self->speed = speed; 1049 toshoboe_setbaud (self); 1050 spin_unlock_irqrestore(&self->spinlock, flags); 1051 dev_kfree_skb (skb); 1052 return 0; 1053 } 1054 1055 } 1056 1057 if ((mtt = irda_get_mtt(skb))) 1058 { 1059 /* This is fair since the queue should be empty anyway */ 1060 spin_lock_irqsave(&self->spinlock, flags); 1061 1062 if (self->txpending) 1063 { 1064 spin_unlock_irqrestore(&self->spinlock, flags); 1065 return -EBUSY; 1066 } 1067 1068 /* If in SIR mode we need to generate a string of XBOFs */ 1069 /* In MIR and FIR we need to generate a string of data */ 1070 /* which we will add a wrong checksum to */ 1071 1072 mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt); 1073 IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __FUNCTION__ 1074 ,skb->len,mtt,self->txpending); 1075 if (mtt) 1076 { 1077 self->ring->tx[self->txs].len = mtt & 0xfff; 1078 1079 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX; 1080 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON) 1081 { 1082 ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ; 1083 } 1084#ifdef USE_MIR 1085 else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON) 1086 { 1087 ctl |= OBOE_CTL_TX_BAD_CRC; 1088 } 1089#endif 1090 self->ring->tx[self->txs].control = ctl; 1091 1092 OUTB (0x0, OBOE_ENABLEH); 1093 /* It is only a timer. Do not send mtt packet outside! */ 1094 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP); 1095 1096 self->txpending++; 1097 1098 self->txs++; 1099 self->txs %= TX_SLOTS; 1100 1101 } 1102 else 1103 { 1104 printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n"); 1105 } 1106 spin_unlock_irqrestore(&self->spinlock, flags); 1107 } 1108 1109#ifdef DUMP_PACKETS 1110dumpbufs(skb->data,skb->len,'>'); 1111#endif 1112 1113 spin_lock_irqsave(&self->spinlock, flags); 1114 1115 if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS) 1116 { 1117 IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __FUNCTION__ 1118 ,skb->len, self->ring->tx[self->txs].control, self->txpending); 1119 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); 1120 spin_unlock_irqrestore(&self->spinlock, flags); 1121 return -EBUSY; 1122 } 1123 1124 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON) 1125 { 1126 len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ); 1127 } 1128 else 1129 { 1130 len = skb->len; 1131 memcpy (self->tx_bufs[self->txs], skb->data, len); 1132 } 1133 self->ring->tx[self->txs].len = len & 0x0fff; 1134 1135 /*Sometimes the HW doesn't see us assert RTCENTX in the interrupt code */ 1136 /*later this plays safe, we garuntee the last packet to be transmitted */ 1137 /*has RTCENTX set */ 1138 1139 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX; 1140 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON) 1141 { 1142 ctl |= OBOE_CTL_TX_SIP ; 1143 } 1144 self->ring->tx[self->txs].control = ctl; 1145 1146 /* If transmitter is idle start in one-shot mode */ 1147 1148 if (!self->txpending) 1149 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); 1150 1151 self->txpending++; 1152 1153 self->txs++; 1154 self->txs %= TX_SLOTS; 1155 1156 spin_unlock_irqrestore(&self->spinlock, flags); 1157 dev_kfree_skb (skb); 1158 1159 return 0; 1160} 1161 1162/*interrupt handler */ 1163static irqreturn_t 1164toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) 1165{ 1166 struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id; 1167 __u8 irqstat; 1168 struct sk_buff *skb = NULL; 1169 1170 if (self == NULL && toshoboe_invalid_dev(irq)) 1171 return IRQ_NONE; 1172 1173 irqstat = INB (OBOE_ISR); 1174 1175/* was it us */ 1176 if (!(irqstat & OBOE_INT_MASK)) 1177 return IRQ_NONE; 1178 1179/* Ack all the interrupts */ 1180 OUTB (irqstat, OBOE_ISR); 1181 1182 toshoboe_isntstuck (self); 1183 1184/* Txdone */ 1185 if (irqstat & OBOE_INT_TXDONE) 1186 { 1187 int txp, txpc; 1188 int i; 1189 1190 txp = self->txpending; 1191 self->txpending = 0; 1192 1193 for (i = 0; i < TX_SLOTS; ++i) 1194 { 1195 if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS) 1196 self->txpending++; 1197 } 1198 IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __FUNCTION__ 1199 ,irqstat,txp,self->txpending); 1200 1201 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK; 1202 1203 /* Got anything queued ? start it together */ 1204 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS) 1205 { 1206 txpc = txp; 1207#ifdef OPTIMIZE_TX 1208 while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS) 1209 { 1210 txp = txpc; 1211 txpc++; 1212 txpc %= TX_SLOTS; 1213 self->stats.tx_packets++; 1214 if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS) 1215 self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX; 1216 } 1217 self->stats.tx_packets--; 1218#else 1219 self->stats.tx_packets++; 1220#endif 1221 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); 1222 } 1223 1224 if ((!self->txpending) && (self->new_speed)) 1225 { 1226 self->speed = self->new_speed; 1227 IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n", 1228 __FUNCTION__, self->speed); 1229 toshoboe_setbaud (self); 1230 } 1231 1232 /* Tell network layer that we want more frames */ 1233 if (!self->new_speed) 1234 netif_wake_queue(self->netdev); 1235 } 1236 1237 if (irqstat & OBOE_INT_RXDONE) 1238 { 1239 while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS)) 1240 { 1241 int len = self->ring->rx[self->rxs].len; 1242 skb = NULL; 1243 IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __FUNCTION__ 1244 ,len,self->ring->rx[self->rxs].control); 1245 1246#ifdef DUMP_PACKETS 1247dumpbufs(self->rx_bufs[self->rxs],len,'<'); 1248#endif 1249 1250 if (self->ring->rx[self->rxs].control == 0) 1251 { 1252 __u8 enable = INB (OBOE_ENABLEH); 1253 1254 /* In SIR mode we need to check the CRC as this */ 1255 /* hasn't been done by the hardware */ 1256 if (enable & OBOE_ENABLEH_SIRON) 1257 { 1258 if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len)) 1259 len = 0; 1260 /*Trim off the CRC */ 1261 if (len > 1) 1262 len -= 2; 1263 else 1264 len = 0; 1265 IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __FUNCTION__, len,enable); 1266 } 1267 1268#ifdef USE_MIR 1269 else if (enable & OBOE_ENABLEH_MIRON) 1270 { 1271 if (len > 1) 1272 len -= 2; 1273 else 1274 len = 0; 1275 IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __FUNCTION__, len,enable); 1276 } 1277#endif 1278 else if (enable & OBOE_ENABLEH_FIRON) 1279 { 1280 if (len > 3) 1281 len -= 4; /*FIXME: check this */ 1282 else 1283 len = 0; 1284 IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __FUNCTION__, len,enable); 1285 } 1286 else 1287 IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __FUNCTION__, len,enable); 1288 1289 if (len) 1290 { 1291 skb = dev_alloc_skb (len + 1); 1292 if (skb) 1293 { 1294 skb_reserve (skb, 1); 1295 1296 skb_put (skb, len); 1297 memcpy (skb->data, self->rx_bufs[self->rxs], len); 1298 1299 self->stats.rx_packets++; 1300 skb->dev = self->netdev; 1301 skb->mac.raw = skb->data; 1302 skb->protocol = htons (ETH_P_IRDA); 1303 } 1304 else 1305 { 1306 printk (KERN_INFO 1307 "%s(), memory squeeze, dropping frame.\n", 1308 __FUNCTION__); 1309 } 1310 } 1311 } 1312 else 1313 { 1314 /* TODO: =========================================== */ 1315 /* if OBOE_CTL_RX_LENGTH, our buffers are too small */ 1316 /* (MIR or FIR) data is lost. */ 1317 /* (SIR) data is splitted in several slots. */ 1318 /* we have to join all the received buffers received */ 1319 /*in a large buffer before checking CRC. */ 1320 IRDA_DEBUG (0, "%s.err:%x(%x)\n", __FUNCTION__ 1321 ,len,self->ring->rx[self->rxs].control); 1322 } 1323 1324 self->ring->rx[self->rxs].len = 0x0; 1325 self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS; 1326 1327 self->rxs++; 1328 self->rxs %= RX_SLOTS; 1329 1330 if (skb) 1331 netif_rx (skb); 1332 1333 } 1334 } 1335 1336 if (irqstat & OBOE_INT_TXUNDER) 1337 { 1338 printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n"); 1339 } 1340 if (irqstat & OBOE_INT_RXOVER) 1341 { 1342 printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n"); 1343 } 1344/* This must be useful for something... */ 1345 if (irqstat & OBOE_INT_SIP) 1346 { 1347 self->int_sip++; 1348 IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __FUNCTION__ 1349 ,self->int_sip,irqstat,self->txpending); 1350 } 1351 return IRQ_HANDLED; 1352} 1353 1354 1355static int 1356toshoboe_net_open (struct net_device *dev) 1357{ 1358 struct toshoboe_cb *self; 1359 unsigned long flags; 1360 1361 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 1362 1363 IRDA_ASSERT (dev != NULL, return -1; ); 1364 self = (struct toshoboe_cb *) dev->priv; 1365 1366 IRDA_ASSERT (self != NULL, return 0; ); 1367 1368 if (self->async) 1369 return -EBUSY; 1370 1371 if (self->stopped) 1372 return 0; 1373 1374 if (request_irq (self->io.irq, toshoboe_interrupt, 1375 IRQF_SHARED | IRQF_DISABLED, dev->name, (void *) self)) 1376 { 1377 return -EAGAIN; 1378 } 1379 1380 spin_lock_irqsave(&self->spinlock, flags); 1381 toshoboe_startchip (self); 1382 spin_unlock_irqrestore(&self->spinlock, flags); 1383 1384 /* Ready to play! */ 1385 netif_start_queue(dev); 1386 1387 /* 1388 * Open new IrLAP layer instance, now that everything should be 1389 * initialized properly 1390 */ 1391 self->irlap = irlap_open (dev, &self->qos, driver_name); 1392 1393 self->irdad = 1; 1394 1395 return 0; 1396} 1397 1398static int 1399toshoboe_net_close (struct net_device *dev) 1400{ 1401 struct toshoboe_cb *self; 1402 1403 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 1404 1405 IRDA_ASSERT (dev != NULL, return -1; ); 1406 self = (struct toshoboe_cb *) dev->priv; 1407 1408 /* Stop device */ 1409 netif_stop_queue(dev); 1410 1411 /* Stop and remove instance of IrLAP */ 1412 if (self->irlap) 1413 irlap_close (self->irlap); 1414 self->irlap = NULL; 1415 1416 self->irdad = 0; 1417 1418 free_irq (self->io.irq, (void *) self); 1419 1420 if (!self->stopped) 1421 { 1422 toshoboe_stopchip (self); 1423 } 1424 1425 return 0; 1426} 1427 1428/* 1429 * Function toshoboe_net_ioctl (dev, rq, cmd) 1430 * 1431 * Process IOCTL commands for this device 1432 * 1433 */ 1434static int 1435toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) 1436{ 1437 struct if_irda_req *irq = (struct if_irda_req *) rq; 1438 struct toshoboe_cb *self; 1439 unsigned long flags; 1440 int ret = 0; 1441 1442 IRDA_ASSERT (dev != NULL, return -1; ); 1443 1444 self = dev->priv; 1445 1446 IRDA_ASSERT (self != NULL, return -1; ); 1447 1448 IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); 1449 1450 /* Disable interrupts & save flags */ 1451 spin_lock_irqsave(&self->spinlock, flags); 1452 1453 switch (cmd) 1454 { 1455 case SIOCSBANDWIDTH: /* Set bandwidth */ 1456 /* This function will also be used by IrLAP to change the 1457 * speed, so we still must allow for speed change within 1458 * interrupt context. 1459 */ 1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__ 1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); 1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) { 1463 ret = -EPERM; 1464 goto out; 1465 } 1466 1467 /* self->speed=irq->ifr_baudrate; */ 1468 /* toshoboe_setbaud(self); */ 1469 /* Just change speed once - inserted by Paul Bristow */ 1470 self->new_speed = irq->ifr_baudrate; 1471 break; 1472 case SIOCSMEDIABUSY: /* Set media busy */ 1473 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__ 1474 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); 1475 if (!capable (CAP_NET_ADMIN)) { 1476 ret = -EPERM; 1477 goto out; 1478 } 1479 irda_device_set_media_busy (self->netdev, TRUE); 1480 break; 1481 case SIOCGRECEIVING: /* Check if we are receiving right now */ 1482 irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0; 1483 IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __FUNCTION__ 1484 ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving ); 1485 break; 1486 default: 1487 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); 1488 ret = -EOPNOTSUPP; 1489 } 1490out: 1491 spin_unlock_irqrestore(&self->spinlock, flags); 1492 return ret; 1493 1494} 1495 1496MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver"); 1497MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>"); 1498MODULE_LICENSE("GPL"); 1499 1500module_param (max_baud, int, 0); 1501MODULE_PARM_DESC(max_baud, "Maximum baud rate"); 1502 1503#ifdef USE_PROBE 1504module_param (do_probe, bool, 0); 1505MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test"); 1506#endif 1507 1508static void 1509toshoboe_close (struct pci_dev *pci_dev) 1510{ 1511 int i; 1512 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); 1513 1514 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 1515 1516 IRDA_ASSERT (self != NULL, return; ); 1517 1518 if (!self->stopped) 1519 { 1520 toshoboe_stopchip (self); 1521 } 1522 1523 release_region (self->io.fir_base, self->io.fir_ext); 1524 1525 for (i = 0; i < TX_SLOTS; ++i) 1526 { 1527 kfree (self->tx_bufs[i]); 1528 self->tx_bufs[i] = NULL; 1529 } 1530 1531 for (i = 0; i < RX_SLOTS; ++i) 1532 { 1533 kfree (self->rx_bufs[i]); 1534 self->rx_bufs[i] = NULL; 1535 } 1536 1537 unregister_netdev(self->netdev); 1538 1539 kfree (self->ringbuf); 1540 self->ringbuf = NULL; 1541 self->ring = NULL; 1542 1543 free_netdev(self->netdev); 1544} 1545 1546static int 1547toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) 1548{ 1549 struct toshoboe_cb *self; 1550 struct net_device *dev; 1551 int i = 0; 1552 int ok = 0; 1553 int err; 1554 1555 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 1556 1557 if ((err=pci_enable_device(pci_dev))) 1558 return err; 1559 1560 dev = alloc_irdadev(sizeof (struct toshoboe_cb)); 1561 if (dev == NULL) 1562 { 1563 printk (KERN_ERR DRIVER_NAME ": can't allocate memory for " 1564 "IrDA control block\n"); 1565 return -ENOMEM; 1566 } 1567 1568 self = dev->priv; 1569 self->netdev = dev; 1570 self->pdev = pci_dev; 1571 self->base = pci_resource_start(pci_dev,0); 1572 1573 self->io.fir_base = self->base; 1574 self->io.fir_ext = OBOE_IO_EXTENT; 1575 self->io.irq = pci_dev->irq; 1576 self->io.irqflags = IRQF_SHARED | IRQF_DISABLED; 1577 1578 self->speed = self->io.speed = 9600; 1579 self->async = 0; 1580 1581 /* Lock the port that we need */ 1582 if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name)) 1583 { 1584 printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n" 1585 ,self->io.fir_base); 1586 err = -EBUSY; 1587 goto freeself; 1588 } 1589 1590 spin_lock_init(&self->spinlock); 1591 1592 irda_init_max_qos_capabilies (&self->qos); 1593 self->qos.baud_rate.bits = 0; 1594 1595 if (max_baud >= 2400) 1596 self->qos.baud_rate.bits |= IR_2400; 1597 /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */ 1598 if (max_baud >= 9600) 1599 self->qos.baud_rate.bits |= IR_9600; 1600 if (max_baud >= 19200) 1601 self->qos.baud_rate.bits |= IR_19200; 1602 if (max_baud >= 115200) 1603 self->qos.baud_rate.bits |= IR_115200; 1604#ifdef USE_MIR 1605 if (max_baud >= 1152000) 1606 { 1607 self->qos.baud_rate.bits |= IR_1152000; 1608 } 1609#endif 1610 if (max_baud >= 4000000) 1611 { 1612 self->qos.baud_rate.bits |= (IR_4000000 << 8); 1613 } 1614 1615 /*FIXME: work this out... */ 1616 self->qos.min_turn_time.bits = 0xff; 1617 1618 irda_qos_bits_to_value (&self->qos); 1619 1620 /* Allocate twice the size to guarantee alignment */ 1621 self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL); 1622 if (!self->ringbuf) 1623 { 1624 printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n"); 1625 err = -ENOMEM; 1626 goto freeregion; 1627 } 1628 1629#if (BITS_PER_LONG == 64) 1630#error broken on 64-bit: casts pointer to 32-bit, and then back to pointer. 1631#endif 1632 1633 /*We need to align the taskfile on a taskfile size boundary */ 1634 { 1635 unsigned long addr; 1636 1637 addr = (__u32) self->ringbuf; 1638 addr &= ~(OBOE_RING_LEN - 1); 1639 addr += OBOE_RING_LEN; 1640 self->ring = (struct OboeRing *) addr; 1641 } 1642 1643 memset (self->ring, 0, OBOE_RING_LEN); 1644 self->io.mem_base = (__u32) self->ring; 1645 1646 ok = 1; 1647 for (i = 0; i < TX_SLOTS; ++i) 1648 { 1649 self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL); 1650 if (!self->tx_bufs[i]) 1651 ok = 0; 1652 } 1653 1654 for (i = 0; i < RX_SLOTS; ++i) 1655 { 1656 self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL); 1657 if (!self->rx_bufs[i]) 1658 ok = 0; 1659 } 1660 1661 if (!ok) 1662 { 1663 printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n"); 1664 err = -ENOMEM; 1665 goto freebufs; 1666 } 1667 1668 1669#ifdef USE_PROBE 1670 if (do_probe) 1671 if (!toshoboe_probe (self)) 1672 { 1673 err = -ENODEV; 1674 goto freebufs; 1675 } 1676#endif 1677 1678 SET_MODULE_OWNER(dev); 1679 SET_NETDEV_DEV(dev, &pci_dev->dev); 1680 dev->hard_start_xmit = toshoboe_hard_xmit; 1681 dev->open = toshoboe_net_open; 1682 dev->stop = toshoboe_net_close; 1683 dev->do_ioctl = toshoboe_net_ioctl; 1684 1685 err = register_netdev(dev); 1686 if (err) 1687 { 1688 printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n"); 1689 err = -ENOMEM; 1690 goto freebufs; 1691 } 1692 printk (KERN_INFO "IrDA: Registered device %s\n", dev->name); 1693 1694 pci_set_drvdata(pci_dev,self); 1695 1696 printk (KERN_INFO DRIVER_NAME ": Using multiple tasks, version %s\n", rcsid); 1697 1698 return 0; 1699 1700freebufs: 1701 for (i = 0; i < TX_SLOTS; ++i) 1702 kfree (self->tx_bufs[i]); 1703 for (i = 0; i < RX_SLOTS; ++i) 1704 kfree (self->rx_bufs[i]); 1705 kfree(self->ringbuf); 1706 1707freeregion: 1708 release_region (self->io.fir_base, self->io.fir_ext); 1709 1710freeself: 1711 free_netdev(dev); 1712 1713 return err; 1714} 1715 1716static int 1717toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap) 1718{ 1719 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); 1720 unsigned long flags; 1721 int i = 10; 1722 1723 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 1724 1725 if (!self || self->stopped) 1726 return 0; 1727 1728 if ((!self->irdad) && (!self->async)) 1729 return 0; 1730 1731/* Flush all packets */ 1732 while ((i--) && (self->txpending)) 1733 udelay (10000); 1734 1735 spin_lock_irqsave(&self->spinlock, flags); 1736 1737 toshoboe_stopchip (self); 1738 self->stopped = 1; 1739 self->txpending = 0; 1740 1741 spin_unlock_irqrestore(&self->spinlock, flags); 1742 return 0; 1743} 1744 1745static int 1746toshoboe_wakeup (struct pci_dev *pci_dev) 1747{ 1748 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); 1749 unsigned long flags; 1750 1751 IRDA_DEBUG (4, "%s()\n", __FUNCTION__); 1752 1753 if (!self || !self->stopped) 1754 return 0; 1755 1756 if ((!self->irdad) && (!self->async)) 1757 return 0; 1758 1759 spin_lock_irqsave(&self->spinlock, flags); 1760 1761 toshoboe_startchip (self); 1762 self->stopped = 0; 1763 1764 netif_wake_queue(self->netdev); 1765 spin_unlock_irqrestore(&self->spinlock, flags); 1766 return 0; 1767} 1768 1769static struct pci_driver donauboe_pci_driver = { 1770 .name = "donauboe", 1771 .id_table = toshoboe_pci_tbl, 1772 .probe = toshoboe_open, 1773 .remove = toshoboe_close, 1774 .suspend = toshoboe_gotosleep, 1775 .resume = toshoboe_wakeup 1776}; 1777 1778static int __init 1779donauboe_init (void) 1780{ 1781 return pci_register_driver(&donauboe_pci_driver); 1782} 1783 1784static void __exit 1785donauboe_cleanup (void) 1786{ 1787 pci_unregister_driver(&donauboe_pci_driver); 1788} 1789 1790module_init(donauboe_init); 1791module_exit(donauboe_cleanup);