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