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