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

Configure Feed

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

at v2.6.32 1775 lines 48 kB view raw
1/***************************************************************** 2 * 3 * Filename: donauboe.c 4 * Version: 2.17 5 * Description: Driver for the Toshiba OBOE (or type-O or 701) 6 * FIR Chipset, also supports the DONAUOBOE (type-DO 7 * or d01) FIR chipset which as far as I know is 8 * register compatible. 9 * Documentation: http://libxg.free.fr/irda/lib-irda.html 10 * Status: Experimental. 11 * Author: James McKenzie <james@fishsoup.dhs.org> 12 * Created at: Sat May 8 12:35:27 1999 13 * Modified: Paul Bristow <paul.bristow@technologist.com> 14 * Modified: Mon Nov 11 19:10:05 1999 15 * Modified: James McKenzie <james@fishsoup.dhs.org> 16 * Modified: Thu Mar 16 12:49:00 2000 (Substantial rewrite) 17 * Modified: Sat Apr 29 00:23:03 2000 (Added DONAUOBOE support) 18 * Modified: Wed May 24 23:45:02 2000 (Fixed chipio_t structure) 19 * Modified: 2.13 Christian Gennerat <christian.gennerat@polytechnique.org> 20 * Modified: 2.13 dim jan 07 21:57:39 2001 (tested with kernel 2.4 & irnet/ppp) 21 * Modified: 2.14 Christian Gennerat <christian.gennerat@polytechnique.org> 22 * Modified: 2.14 lun fev 05 17:55:59 2001 (adapted to patch-2.4.1-pre8-irda1) 23 * Modified: 2.15 Martin Lucina <mato@kotelna.sk> 24 * Modified: 2.15 Fri Jun 21 20:40:59 2002 (sync with 2.4.18, substantial fixes) 25 * Modified: 2.16 Martin Lucina <mato@kotelna.sk> 26 * Modified: 2.16 Sat Jun 22 18:54:29 2002 (fix freeregion, default to verbose) 27 * Modified: 2.17 Christian Gennerat <christian.gennerat@polytechnique.org> 28 * Modified: 2.17 jeu sep 12 08:50:20 2002 (save_flags();cli(); replaced by spinlocks) 29 * Modified: 2.18 Christian Gennerat <christian.gennerat@polytechnique.org> 30 * Modified: 2.18 ven jan 10 03:14:16 2003 Change probe default options 31 * 32 * Copyright (c) 1999 James McKenzie, All Rights Reserved. 33 * 34 * This program is free software; you can redistribute it and/or 35 * modify it under the terms of the GNU General Public License as 36 * published by the Free Software Foundation; either version 2 of 37 * the License, or (at your option) any later version. 38 * 39 * Neither James McKenzie nor Cambridge University admit liability nor 40 * provide warranty for any of this software. This material is 41 * provided "AS-IS" and at no charge. 42 * 43 * Applicable Models : Libretto 100/110CT and many more. 44 * Toshiba refers to this chip as the type-O IR port, 45 * or the type-DO IR port. 46 * 47 ********************************************************************/ 48 49/* Look at toshoboe.h (currently in include/net/irda) for details of */ 50/* Where to get documentation on the chip */ 51 52/* See below for a description of the logic in this driver */ 53 54/* User servicable parts */ 55/* USE_PROBE Create the code which probes the chip and does a few tests */ 56/* do_probe module parameter Enable this code */ 57/* Probe code is very useful for understanding how the hardware works */ 58/* Use it with various combinations of TT_LEN, RX_LEN */ 59/* Strongly recomended, 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/pci.h> 156#include <linux/rtnetlink.h> 157 158#include <asm/system.h> 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 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 int do_probe = 0; 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 int bauds[] = { 9600, 115200, 4000000, 1152000 }; 822#else 823 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 dev->trans_start = jiffies; 1006 1007 /* Check if we need to change the speed */ 1008 /* But not now. Wait after transmission if mtt not required */ 1009 speed=irda_get_next_speed(skb); 1010 if ((speed != self->io.speed) && (speed != -1)) 1011 { 1012 spin_lock_irqsave(&self->spinlock, flags); 1013 1014 if (self->txpending || skb->len) 1015 { 1016 self->new_speed = speed; 1017 IRDA_DEBUG (1, "%s: Queued TxDone scheduled speed change %d\n" , 1018 __func__, speed); 1019 /* if no data, that's all! */ 1020 if (!skb->len) 1021 { 1022 spin_unlock_irqrestore(&self->spinlock, flags); 1023 dev_kfree_skb (skb); 1024 return NETDEV_TX_OK; 1025 } 1026 /* True packet, go on, but */ 1027 /* do not accept anything before change speed execution */ 1028 netif_stop_queue(dev); 1029 /* ready to process TxDone interrupt */ 1030 spin_unlock_irqrestore(&self->spinlock, flags); 1031 } 1032 else 1033 { 1034 /* idle and no data, change speed now */ 1035 self->speed = speed; 1036 toshoboe_setbaud (self); 1037 spin_unlock_irqrestore(&self->spinlock, flags); 1038 dev_kfree_skb (skb); 1039 return NETDEV_TX_OK; 1040 } 1041 1042 } 1043 1044 if ((mtt = irda_get_mtt(skb))) 1045 { 1046 /* This is fair since the queue should be empty anyway */ 1047 spin_lock_irqsave(&self->spinlock, flags); 1048 1049 if (self->txpending) 1050 { 1051 spin_unlock_irqrestore(&self->spinlock, flags); 1052 return NETDEV_TX_BUSY; 1053 } 1054 1055 /* If in SIR mode we need to generate a string of XBOFs */ 1056 /* In MIR and FIR we need to generate a string of data */ 1057 /* which we will add a wrong checksum to */ 1058 1059 mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt); 1060 IRDA_DEBUG (1, "%s.mtt:%x(%x)%d\n", __func__ 1061 ,skb->len,mtt,self->txpending); 1062 if (mtt) 1063 { 1064 self->ring->tx[self->txs].len = mtt & 0xfff; 1065 1066 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX; 1067 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON) 1068 { 1069 ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ; 1070 } 1071#ifdef USE_MIR 1072 else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON) 1073 { 1074 ctl |= OBOE_CTL_TX_BAD_CRC; 1075 } 1076#endif 1077 self->ring->tx[self->txs].control = ctl; 1078 1079 OUTB (0x0, OBOE_ENABLEH); 1080 /* It is only a timer. Do not send mtt packet outside! */ 1081 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP); 1082 1083 self->txpending++; 1084 1085 self->txs++; 1086 self->txs %= TX_SLOTS; 1087 1088 } 1089 else 1090 { 1091 printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n"); 1092 } 1093 spin_unlock_irqrestore(&self->spinlock, flags); 1094 } 1095 1096#ifdef DUMP_PACKETS 1097dumpbufs(skb->data,skb->len,'>'); 1098#endif 1099 1100 spin_lock_irqsave(&self->spinlock, flags); 1101 1102 if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS) 1103 { 1104 IRDA_DEBUG (0, "%s.ful:%x(%x)%x\n", __func__ 1105 ,skb->len, self->ring->tx[self->txs].control, self->txpending); 1106 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); 1107 spin_unlock_irqrestore(&self->spinlock, flags); 1108 return NETDEV_TX_BUSY; 1109 } 1110 1111 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON) 1112 { 1113 len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ); 1114 } 1115 else 1116 { 1117 len = skb->len; 1118 skb_copy_from_linear_data(skb, self->tx_bufs[self->txs], len); 1119 } 1120 self->ring->tx[self->txs].len = len & 0x0fff; 1121 1122 /*Sometimes the HW doesn't see us assert RTCENTX in the interrupt code */ 1123 /*later this plays safe, we garuntee the last packet to be transmitted */ 1124 /*has RTCENTX set */ 1125 1126 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX; 1127 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON) 1128 { 1129 ctl |= OBOE_CTL_TX_SIP ; 1130 } 1131 self->ring->tx[self->txs].control = ctl; 1132 1133 /* If transmitter is idle start in one-shot mode */ 1134 1135 if (!self->txpending) 1136 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); 1137 1138 self->txpending++; 1139 1140 self->txs++; 1141 self->txs %= TX_SLOTS; 1142 1143 spin_unlock_irqrestore(&self->spinlock, flags); 1144 dev_kfree_skb (skb); 1145 1146 return NETDEV_TX_OK; 1147} 1148 1149/*interrupt handler */ 1150static irqreturn_t 1151toshoboe_interrupt (int irq, void *dev_id) 1152{ 1153 struct toshoboe_cb *self = dev_id; 1154 __u8 irqstat; 1155 struct sk_buff *skb = NULL; 1156 1157 irqstat = INB (OBOE_ISR); 1158 1159/* was it us */ 1160 if (!(irqstat & OBOE_INT_MASK)) 1161 return IRQ_NONE; 1162 1163/* Ack all the interrupts */ 1164 OUTB (irqstat, OBOE_ISR); 1165 1166 toshoboe_isntstuck (self); 1167 1168/* Txdone */ 1169 if (irqstat & OBOE_INT_TXDONE) 1170 { 1171 int txp, txpc; 1172 int i; 1173 1174 txp = self->txpending; 1175 self->txpending = 0; 1176 1177 for (i = 0; i < TX_SLOTS; ++i) 1178 { 1179 if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS) 1180 self->txpending++; 1181 } 1182 IRDA_DEBUG (1, "%s.txd(%x)%x/%x\n", __func__ 1183 ,irqstat,txp,self->txpending); 1184 1185 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK; 1186 1187 /* Got anything queued ? start it together */ 1188 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS) 1189 { 1190 txpc = txp; 1191#ifdef OPTIMIZE_TX 1192 while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS) 1193 { 1194 txp = txpc; 1195 txpc++; 1196 txpc %= TX_SLOTS; 1197 self->netdev->stats.tx_packets++; 1198 if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS) 1199 self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX; 1200 } 1201 self->netdev->stats.tx_packets--; 1202#else 1203 self->netdev->stats.tx_packets++; 1204#endif 1205 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); 1206 } 1207 1208 if ((!self->txpending) && (self->new_speed)) 1209 { 1210 self->speed = self->new_speed; 1211 IRDA_DEBUG (1, "%s: Executed TxDone scheduled speed change %d\n", 1212 __func__, self->speed); 1213 toshoboe_setbaud (self); 1214 } 1215 1216 /* Tell network layer that we want more frames */ 1217 if (!self->new_speed) 1218 netif_wake_queue(self->netdev); 1219 } 1220 1221 if (irqstat & OBOE_INT_RXDONE) 1222 { 1223 while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS)) 1224 { 1225 int len = self->ring->rx[self->rxs].len; 1226 skb = NULL; 1227 IRDA_DEBUG (3, "%s.rcv:%x(%x)\n", __func__ 1228 ,len,self->ring->rx[self->rxs].control); 1229 1230#ifdef DUMP_PACKETS 1231dumpbufs(self->rx_bufs[self->rxs],len,'<'); 1232#endif 1233 1234 if (self->ring->rx[self->rxs].control == 0) 1235 { 1236 __u8 enable = INB (OBOE_ENABLEH); 1237 1238 /* In SIR mode we need to check the CRC as this */ 1239 /* hasn't been done by the hardware */ 1240 if (enable & OBOE_ENABLEH_SIRON) 1241 { 1242 if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len)) 1243 len = 0; 1244 /*Trim off the CRC */ 1245 if (len > 1) 1246 len -= 2; 1247 else 1248 len = 0; 1249 IRDA_DEBUG (1, "%s.SIR:%x(%x)\n", __func__, len,enable); 1250 } 1251 1252#ifdef USE_MIR 1253 else if (enable & OBOE_ENABLEH_MIRON) 1254 { 1255 if (len > 1) 1256 len -= 2; 1257 else 1258 len = 0; 1259 IRDA_DEBUG (2, "%s.MIR:%x(%x)\n", __func__, len,enable); 1260 } 1261#endif 1262 else if (enable & OBOE_ENABLEH_FIRON) 1263 { 1264 if (len > 3) 1265 len -= 4; /*FIXME: check this */ 1266 else 1267 len = 0; 1268 IRDA_DEBUG (1, "%s.FIR:%x(%x)\n", __func__, len,enable); 1269 } 1270 else 1271 IRDA_DEBUG (0, "%s.?IR:%x(%x)\n", __func__, len,enable); 1272 1273 if (len) 1274 { 1275 skb = dev_alloc_skb (len + 1); 1276 if (skb) 1277 { 1278 skb_reserve (skb, 1); 1279 1280 skb_put (skb, len); 1281 skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs], 1282 len); 1283 self->netdev->stats.rx_packets++; 1284 skb->dev = self->netdev; 1285 skb_reset_mac_header(skb); 1286 skb->protocol = htons (ETH_P_IRDA); 1287 } 1288 else 1289 { 1290 printk (KERN_INFO 1291 "%s(), memory squeeze, dropping frame.\n", 1292 __func__); 1293 } 1294 } 1295 } 1296 else 1297 { 1298 /* TODO: =========================================== */ 1299 /* if OBOE_CTL_RX_LENGTH, our buffers are too small */ 1300 /* (MIR or FIR) data is lost. */ 1301 /* (SIR) data is splitted in several slots. */ 1302 /* we have to join all the received buffers received */ 1303 /*in a large buffer before checking CRC. */ 1304 IRDA_DEBUG (0, "%s.err:%x(%x)\n", __func__ 1305 ,len,self->ring->rx[self->rxs].control); 1306 } 1307 1308 self->ring->rx[self->rxs].len = 0x0; 1309 self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS; 1310 1311 self->rxs++; 1312 self->rxs %= RX_SLOTS; 1313 1314 if (skb) 1315 netif_rx (skb); 1316 1317 } 1318 } 1319 1320 if (irqstat & OBOE_INT_TXUNDER) 1321 { 1322 printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n"); 1323 } 1324 if (irqstat & OBOE_INT_RXOVER) 1325 { 1326 printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n"); 1327 } 1328/* This must be useful for something... */ 1329 if (irqstat & OBOE_INT_SIP) 1330 { 1331 self->int_sip++; 1332 IRDA_DEBUG (1, "%s.sip:%x(%x)%x\n", __func__ 1333 ,self->int_sip,irqstat,self->txpending); 1334 } 1335 return IRQ_HANDLED; 1336} 1337 1338 1339static int 1340toshoboe_net_open (struct net_device *dev) 1341{ 1342 struct toshoboe_cb *self; 1343 unsigned long flags; 1344 int rc; 1345 1346 IRDA_DEBUG (4, "%s()\n", __func__); 1347 1348 self = netdev_priv(dev); 1349 1350 if (self->async) 1351 return -EBUSY; 1352 1353 if (self->stopped) 1354 return 0; 1355 1356 rc = request_irq (self->io.irq, toshoboe_interrupt, 1357 IRQF_SHARED | IRQF_DISABLED, dev->name, self); 1358 if (rc) 1359 return rc; 1360 1361 spin_lock_irqsave(&self->spinlock, flags); 1362 toshoboe_startchip (self); 1363 spin_unlock_irqrestore(&self->spinlock, flags); 1364 1365 /* Ready to play! */ 1366 netif_start_queue(dev); 1367 1368 /* 1369 * Open new IrLAP layer instance, now that everything should be 1370 * initialized properly 1371 */ 1372 self->irlap = irlap_open (dev, &self->qos, driver_name); 1373 1374 self->irdad = 1; 1375 1376 return 0; 1377} 1378 1379static int 1380toshoboe_net_close (struct net_device *dev) 1381{ 1382 struct toshoboe_cb *self; 1383 1384 IRDA_DEBUG (4, "%s()\n", __func__); 1385 1386 IRDA_ASSERT (dev != NULL, return -1; ); 1387 self = netdev_priv(dev); 1388 1389 /* Stop device */ 1390 netif_stop_queue(dev); 1391 1392 /* Stop and remove instance of IrLAP */ 1393 if (self->irlap) 1394 irlap_close (self->irlap); 1395 self->irlap = NULL; 1396 1397 self->irdad = 0; 1398 1399 free_irq (self->io.irq, (void *) self); 1400 1401 if (!self->stopped) 1402 { 1403 toshoboe_stopchip (self); 1404 } 1405 1406 return 0; 1407} 1408 1409/* 1410 * Function toshoboe_net_ioctl (dev, rq, cmd) 1411 * 1412 * Process IOCTL commands for this device 1413 * 1414 */ 1415static int 1416toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) 1417{ 1418 struct if_irda_req *irq = (struct if_irda_req *) rq; 1419 struct toshoboe_cb *self; 1420 unsigned long flags; 1421 int ret = 0; 1422 1423 IRDA_ASSERT (dev != NULL, return -1; ); 1424 1425 self = netdev_priv(dev); 1426 1427 IRDA_ASSERT (self != NULL, return -1; ); 1428 1429 IRDA_DEBUG (5, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); 1430 1431 /* Disable interrupts & save flags */ 1432 spin_lock_irqsave(&self->spinlock, flags); 1433 1434 switch (cmd) 1435 { 1436 case SIOCSBANDWIDTH: /* Set bandwidth */ 1437 /* This function will also be used by IrLAP to change the 1438 * speed, so we still must allow for speed change within 1439 * interrupt context. 1440 */ 1441 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __func__ 1442 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); 1443 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) { 1444 ret = -EPERM; 1445 goto out; 1446 } 1447 1448 /* self->speed=irq->ifr_baudrate; */ 1449 /* toshoboe_setbaud(self); */ 1450 /* Just change speed once - inserted by Paul Bristow */ 1451 self->new_speed = irq->ifr_baudrate; 1452 break; 1453 case SIOCSMEDIABUSY: /* Set media busy */ 1454 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __func__ 1455 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); 1456 if (!capable (CAP_NET_ADMIN)) { 1457 ret = -EPERM; 1458 goto out; 1459 } 1460 irda_device_set_media_busy (self->netdev, TRUE); 1461 break; 1462 case SIOCGRECEIVING: /* Check if we are receiving right now */ 1463 irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0; 1464 IRDA_DEBUG (3, "%s(RECEIVING), %s, (%X/%x)\n", __func__ 1465 ,dev->name, INB (OBOE_STATUS), irq->ifr_receiving ); 1466 break; 1467 default: 1468 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); 1469 ret = -EOPNOTSUPP; 1470 } 1471out: 1472 spin_unlock_irqrestore(&self->spinlock, flags); 1473 return ret; 1474 1475} 1476 1477MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver"); 1478MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>"); 1479MODULE_LICENSE("GPL"); 1480 1481module_param (max_baud, int, 0); 1482MODULE_PARM_DESC(max_baud, "Maximum baud rate"); 1483 1484#ifdef USE_PROBE 1485module_param (do_probe, bool, 0); 1486MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test"); 1487#endif 1488 1489static void 1490toshoboe_close (struct pci_dev *pci_dev) 1491{ 1492 int i; 1493 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); 1494 1495 IRDA_DEBUG (4, "%s()\n", __func__); 1496 1497 IRDA_ASSERT (self != NULL, return; ); 1498 1499 if (!self->stopped) 1500 { 1501 toshoboe_stopchip (self); 1502 } 1503 1504 release_region (self->io.fir_base, self->io.fir_ext); 1505 1506 for (i = 0; i < TX_SLOTS; ++i) 1507 { 1508 kfree (self->tx_bufs[i]); 1509 self->tx_bufs[i] = NULL; 1510 } 1511 1512 for (i = 0; i < RX_SLOTS; ++i) 1513 { 1514 kfree (self->rx_bufs[i]); 1515 self->rx_bufs[i] = NULL; 1516 } 1517 1518 unregister_netdev(self->netdev); 1519 1520 kfree (self->ringbuf); 1521 self->ringbuf = NULL; 1522 self->ring = NULL; 1523 1524 free_netdev(self->netdev); 1525} 1526 1527static const struct net_device_ops toshoboe_netdev_ops = { 1528 .ndo_open = toshoboe_net_open, 1529 .ndo_stop = toshoboe_net_close, 1530 .ndo_start_xmit = toshoboe_hard_xmit, 1531 .ndo_do_ioctl = toshoboe_net_ioctl, 1532}; 1533 1534static int 1535toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) 1536{ 1537 struct toshoboe_cb *self; 1538 struct net_device *dev; 1539 int i = 0; 1540 int ok = 0; 1541 int err; 1542 1543 IRDA_DEBUG (4, "%s()\n", __func__); 1544 1545 if ((err=pci_enable_device(pci_dev))) 1546 return err; 1547 1548 dev = alloc_irdadev(sizeof (struct toshoboe_cb)); 1549 if (dev == NULL) 1550 { 1551 printk (KERN_ERR DRIVER_NAME ": can't allocate memory for " 1552 "IrDA control block\n"); 1553 return -ENOMEM; 1554 } 1555 1556 self = netdev_priv(dev); 1557 self->netdev = dev; 1558 self->pdev = pci_dev; 1559 self->base = pci_resource_start(pci_dev,0); 1560 1561 self->io.fir_base = self->base; 1562 self->io.fir_ext = OBOE_IO_EXTENT; 1563 self->io.irq = pci_dev->irq; 1564 self->io.irqflags = IRQF_SHARED | IRQF_DISABLED; 1565 1566 self->speed = self->io.speed = 9600; 1567 self->async = 0; 1568 1569 /* Lock the port that we need */ 1570 if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name)) 1571 { 1572 printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n" 1573 ,self->io.fir_base); 1574 err = -EBUSY; 1575 goto freeself; 1576 } 1577 1578 spin_lock_init(&self->spinlock); 1579 1580 irda_init_max_qos_capabilies (&self->qos); 1581 self->qos.baud_rate.bits = 0; 1582 1583 if (max_baud >= 2400) 1584 self->qos.baud_rate.bits |= IR_2400; 1585 /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */ 1586 if (max_baud >= 9600) 1587 self->qos.baud_rate.bits |= IR_9600; 1588 if (max_baud >= 19200) 1589 self->qos.baud_rate.bits |= IR_19200; 1590 if (max_baud >= 115200) 1591 self->qos.baud_rate.bits |= IR_115200; 1592#ifdef USE_MIR 1593 if (max_baud >= 1152000) 1594 { 1595 self->qos.baud_rate.bits |= IR_1152000; 1596 } 1597#endif 1598 if (max_baud >= 4000000) 1599 { 1600 self->qos.baud_rate.bits |= (IR_4000000 << 8); 1601 } 1602 1603 /*FIXME: work this out... */ 1604 self->qos.min_turn_time.bits = 0xff; 1605 1606 irda_qos_bits_to_value (&self->qos); 1607 1608 /* Allocate twice the size to guarantee alignment */ 1609 self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL); 1610 if (!self->ringbuf) 1611 { 1612 printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n"); 1613 err = -ENOMEM; 1614 goto freeregion; 1615 } 1616 1617#if (BITS_PER_LONG == 64) 1618#error broken on 64-bit: casts pointer to 32-bit, and then back to pointer. 1619#endif 1620 1621 /*We need to align the taskfile on a taskfile size boundary */ 1622 { 1623 unsigned long addr; 1624 1625 addr = (__u32) self->ringbuf; 1626 addr &= ~(OBOE_RING_LEN - 1); 1627 addr += OBOE_RING_LEN; 1628 self->ring = (struct OboeRing *) addr; 1629 } 1630 1631 memset (self->ring, 0, OBOE_RING_LEN); 1632 self->io.mem_base = (__u32) self->ring; 1633 1634 ok = 1; 1635 for (i = 0; i < TX_SLOTS; ++i) 1636 { 1637 self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL); 1638 if (!self->tx_bufs[i]) 1639 ok = 0; 1640 } 1641 1642 for (i = 0; i < RX_SLOTS; ++i) 1643 { 1644 self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL); 1645 if (!self->rx_bufs[i]) 1646 ok = 0; 1647 } 1648 1649 if (!ok) 1650 { 1651 printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n"); 1652 err = -ENOMEM; 1653 goto freebufs; 1654 } 1655 1656 1657#ifdef USE_PROBE 1658 if (do_probe) 1659 if (!toshoboe_probe (self)) 1660 { 1661 err = -ENODEV; 1662 goto freebufs; 1663 } 1664#endif 1665 1666 SET_NETDEV_DEV(dev, &pci_dev->dev); 1667 dev->netdev_ops = &toshoboe_netdev_ops; 1668 1669 err = register_netdev(dev); 1670 if (err) 1671 { 1672 printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n"); 1673 err = -ENOMEM; 1674 goto freebufs; 1675 } 1676 printk (KERN_INFO "IrDA: Registered device %s\n", dev->name); 1677 1678 pci_set_drvdata(pci_dev,self); 1679 1680 printk (KERN_INFO DRIVER_NAME ": Using multiple tasks\n"); 1681 1682 return 0; 1683 1684freebufs: 1685 for (i = 0; i < TX_SLOTS; ++i) 1686 kfree (self->tx_bufs[i]); 1687 for (i = 0; i < RX_SLOTS; ++i) 1688 kfree (self->rx_bufs[i]); 1689 kfree(self->ringbuf); 1690 1691freeregion: 1692 release_region (self->io.fir_base, self->io.fir_ext); 1693 1694freeself: 1695 free_netdev(dev); 1696 1697 return err; 1698} 1699 1700static int 1701toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap) 1702{ 1703 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); 1704 unsigned long flags; 1705 int i = 10; 1706 1707 IRDA_DEBUG (4, "%s()\n", __func__); 1708 1709 if (!self || self->stopped) 1710 return 0; 1711 1712 if ((!self->irdad) && (!self->async)) 1713 return 0; 1714 1715/* Flush all packets */ 1716 while ((i--) && (self->txpending)) 1717 udelay (10000); 1718 1719 spin_lock_irqsave(&self->spinlock, flags); 1720 1721 toshoboe_stopchip (self); 1722 self->stopped = 1; 1723 self->txpending = 0; 1724 1725 spin_unlock_irqrestore(&self->spinlock, flags); 1726 return 0; 1727} 1728 1729static int 1730toshoboe_wakeup (struct pci_dev *pci_dev) 1731{ 1732 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev); 1733 unsigned long flags; 1734 1735 IRDA_DEBUG (4, "%s()\n", __func__); 1736 1737 if (!self || !self->stopped) 1738 return 0; 1739 1740 if ((!self->irdad) && (!self->async)) 1741 return 0; 1742 1743 spin_lock_irqsave(&self->spinlock, flags); 1744 1745 toshoboe_startchip (self); 1746 self->stopped = 0; 1747 1748 netif_wake_queue(self->netdev); 1749 spin_unlock_irqrestore(&self->spinlock, flags); 1750 return 0; 1751} 1752 1753static struct pci_driver donauboe_pci_driver = { 1754 .name = "donauboe", 1755 .id_table = toshoboe_pci_tbl, 1756 .probe = toshoboe_open, 1757 .remove = toshoboe_close, 1758 .suspend = toshoboe_gotosleep, 1759 .resume = toshoboe_wakeup 1760}; 1761 1762static int __init 1763donauboe_init (void) 1764{ 1765 return pci_register_driver(&donauboe_pci_driver); 1766} 1767 1768static void __exit 1769donauboe_cleanup (void) 1770{ 1771 pci_unregister_driver(&donauboe_pci_driver); 1772} 1773 1774module_init(donauboe_init); 1775module_exit(donauboe_cleanup);