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