1static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj0rn@blox.se)\n"; 2/* 3 * de600.c 4 * 5 * Linux driver for the D-Link DE-600 Ethernet pocket adapter. 6 * 7 * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall 8 * The Author may be reached as bj0rn@blox.se 9 * 10 * Based on adapter information gathered from DE600.ASM by D-Link Inc., 11 * as included on disk C in the v.2.11 of PC/TCP from FTP Software. 12 * For DE600.asm: 13 * Portions (C) Copyright 1990 D-Link, Inc. 14 * Copyright, 1988-1992, Russell Nelson, Crynwr Software 15 * 16 * Adapted to the sample network driver core for linux, 17 * written by: Donald Becker <becker@super.org> 18 * (Now at <becker@scyld.com>) 19 * 20 **************************************************************/ 21/* 22 * This program is free software; you can redistribute it and/or modify 23 * it under the terms of the GNU General Public License as published by 24 * the Free Software Foundation; either version 2, or (at your option) 25 * any later version. 26 * 27 * This program is distributed in the hope that it will be useful, 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 * GNU General Public License for more details. 31 * 32 * You should have received a copy of the GNU General Public License 33 * along with this program; if not, write to the Free Software 34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 35 * 36 **************************************************************/ 37 38/* Add more time here if your adapter won't work OK: */ 39#define DE600_SLOW_DOWN udelay(delay_time) 40 41#include <linux/module.h> 42#include <linux/kernel.h> 43#include <linux/types.h> 44#include <linux/fcntl.h> 45#include <linux/string.h> 46#include <linux/interrupt.h> 47#include <linux/ioport.h> 48#include <linux/in.h> 49#include <asm/system.h> 50#include <linux/errno.h> 51#include <linux/init.h> 52#include <linux/delay.h> 53#include <linux/inet.h> 54#include <linux/netdevice.h> 55#include <linux/etherdevice.h> 56#include <linux/skbuff.h> 57 58#include <asm/io.h> 59 60#include "de600.h" 61 62static unsigned int check_lost = 1; 63module_param(check_lost, bool, 0); 64MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600"); 65 66static unsigned int delay_time = 10; 67module_param(delay_time, int, 0); 68MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds"); 69 70 71/* 72 * D-Link driver variables: 73 */ 74 75static volatile int rx_page; 76 77#define TX_PAGES 2 78static volatile int tx_fifo[TX_PAGES]; 79static volatile int tx_fifo_in; 80static volatile int tx_fifo_out; 81static volatile int free_tx_pages = TX_PAGES; 82static int was_down; 83static DEFINE_SPINLOCK(de600_lock); 84 85static inline u8 de600_read_status(struct net_device *dev) 86{ 87 u8 status; 88 89 outb_p(STATUS, DATA_PORT); 90 status = inb(STATUS_PORT); 91 outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT); 92 93 return status; 94} 95 96static inline u8 de600_read_byte(unsigned char type, struct net_device *dev) 97{ 98 /* dev used by macros */ 99 u8 lo; 100 outb_p((type), DATA_PORT); 101 lo = ((unsigned char)inb(STATUS_PORT)) >> 4; 102 outb_p((type) | HI_NIBBLE, DATA_PORT); 103 return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo; 104} 105 106/* 107 * Open/initialize the board. This is called (in the current kernel) 108 * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1). 109 * 110 * This routine should set everything up anew at each open, even 111 * registers that "should" only need to be set once at boot, so that 112 * there is a non-reboot way to recover if something goes wrong. 113 */ 114 115static int de600_open(struct net_device *dev) 116{ 117 unsigned long flags; 118 int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev); 119 if (ret) { 120 printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, DE600_IRQ); 121 return ret; 122 } 123 spin_lock_irqsave(&de600_lock, flags); 124 ret = adapter_init(dev); 125 spin_unlock_irqrestore(&de600_lock, flags); 126 return ret; 127} 128 129/* 130 * The inverse routine to de600_open(). 131 */ 132 133static int de600_close(struct net_device *dev) 134{ 135 select_nic(); 136 rx_page = 0; 137 de600_put_command(RESET); 138 de600_put_command(STOP_RESET); 139 de600_put_command(0); 140 select_prn(); 141 free_irq(DE600_IRQ, dev); 142 return 0; 143} 144 145static inline void trigger_interrupt(struct net_device *dev) 146{ 147 de600_put_command(FLIP_IRQ); 148 select_prn(); 149 DE600_SLOW_DOWN; 150 select_nic(); 151 de600_put_command(0); 152} 153 154/* 155 * Copy a buffer to the adapter transmit page memory. 156 * Start sending. 157 */ 158 159static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev) 160{ 161 unsigned long flags; 162 int transmit_from; 163 int len; 164 int tickssofar; 165 u8 *buffer = skb->data; 166 int i; 167 168 if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */ 169 tickssofar = jiffies - dev_trans_start(dev); 170 if (tickssofar < HZ/20) 171 return NETDEV_TX_BUSY; 172 /* else */ 173 printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem"); 174 /* Restart the adapter. */ 175 spin_lock_irqsave(&de600_lock, flags); 176 if (adapter_init(dev)) { 177 spin_unlock_irqrestore(&de600_lock, flags); 178 return NETDEV_TX_BUSY; 179 } 180 spin_unlock_irqrestore(&de600_lock, flags); 181 } 182 183 /* Start real output */ 184 pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages); 185 186 if ((len = skb->len) < RUNT) 187 len = RUNT; 188 189 spin_lock_irqsave(&de600_lock, flags); 190 select_nic(); 191 tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len; 192 tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */ 193 194 if(check_lost) 195 { 196 /* This costs about 40 instructions per packet... */ 197 de600_setup_address(NODE_ADDRESS, RW_ADDR); 198 de600_read_byte(READ_DATA, dev); 199 if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) { 200 if (adapter_init(dev)) { 201 spin_unlock_irqrestore(&de600_lock, flags); 202 return NETDEV_TX_BUSY; 203 } 204 } 205 } 206 207 de600_setup_address(transmit_from, RW_ADDR); 208 for (i = 0; i < skb->len ; ++i, ++buffer) 209 de600_put_byte(*buffer); 210 for (; i < len; ++i) 211 de600_put_byte(0); 212 213 if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */ 214 dev->trans_start = jiffies; 215 netif_start_queue(dev); /* allow more packets into adapter */ 216 /* Send page and generate a faked interrupt */ 217 de600_setup_address(transmit_from, TX_ADDR); 218 de600_put_command(TX_ENABLE); 219 } 220 else { 221 if (free_tx_pages) 222 netif_start_queue(dev); 223 else 224 netif_stop_queue(dev); 225 select_prn(); 226 } 227 spin_unlock_irqrestore(&de600_lock, flags); 228 dev_kfree_skb(skb); 229 return NETDEV_TX_OK; 230} 231 232/* 233 * The typical workload of the driver: 234 * Handle the network interface interrupts. 235 */ 236 237static irqreturn_t de600_interrupt(int irq, void *dev_id) 238{ 239 struct net_device *dev = dev_id; 240 u8 irq_status; 241 int retrig = 0; 242 int boguscount = 0; 243 244 spin_lock(&de600_lock); 245 246 select_nic(); 247 irq_status = de600_read_status(dev); 248 249 do { 250 pr_debug("de600_interrupt (%02X)\n", irq_status); 251 252 if (irq_status & RX_GOOD) 253 de600_rx_intr(dev); 254 else if (!(irq_status & RX_BUSY)) 255 de600_put_command(RX_ENABLE); 256 257 /* Any transmission in progress? */ 258 if (free_tx_pages < TX_PAGES) 259 retrig = de600_tx_intr(dev, irq_status); 260 else 261 retrig = 0; 262 263 irq_status = de600_read_status(dev); 264 } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) ); 265 /* 266 * Yeah, it _looks_ like busy waiting, smells like busy waiting 267 * and I know it's not PC, but please, it will only occur once 268 * in a while and then only for a loop or so (< 1ms for sure!) 269 */ 270 271 /* Enable adapter interrupts */ 272 select_prn(); 273 if (retrig) 274 trigger_interrupt(dev); 275 spin_unlock(&de600_lock); 276 return IRQ_HANDLED; 277} 278 279static int de600_tx_intr(struct net_device *dev, int irq_status) 280{ 281 /* 282 * Returns 1 if tx still not done 283 */ 284 285 /* Check if current transmission is done yet */ 286 if (irq_status & TX_BUSY) 287 return 1; /* tx not done, try again */ 288 289 /* else */ 290 /* If last transmission OK then bump fifo index */ 291 if (!(irq_status & TX_FAILED16)) { 292 tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES; 293 ++free_tx_pages; 294 dev->stats.tx_packets++; 295 netif_wake_queue(dev); 296 } 297 298 /* More to send, or resend last packet? */ 299 if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) { 300 dev->trans_start = jiffies; 301 de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR); 302 de600_put_command(TX_ENABLE); 303 return 1; 304 } 305 /* else */ 306 307 return 0; 308} 309 310/* 311 * We have a good packet, get it out of the adapter. 312 */ 313static void de600_rx_intr(struct net_device *dev) 314{ 315 struct sk_buff *skb; 316 int i; 317 int read_from; 318 int size; 319 unsigned char *buffer; 320 321 /* Get size of received packet */ 322 size = de600_read_byte(RX_LEN, dev); /* low byte */ 323 size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */ 324 size -= 4; /* Ignore trailing 4 CRC-bytes */ 325 326 /* Tell adapter where to store next incoming packet, enable receiver */ 327 read_from = rx_page_adr(); 328 next_rx_page(); 329 de600_put_command(RX_ENABLE); 330 331 if ((size < 32) || (size > 1535)) { 332 printk(KERN_WARNING "%s: Bogus packet size %d.\n", dev->name, size); 333 if (size > 10000) 334 adapter_init(dev); 335 return; 336 } 337 338 skb = dev_alloc_skb(size+2); 339 if (skb == NULL) { 340 printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); 341 return; 342 } 343 /* else */ 344 345 skb_reserve(skb,2); /* Align */ 346 347 /* 'skb->data' points to the start of sk_buff data area. */ 348 buffer = skb_put(skb,size); 349 350 /* copy the packet into the buffer */ 351 de600_setup_address(read_from, RW_ADDR); 352 for (i = size; i > 0; --i, ++buffer) 353 *buffer = de600_read_byte(READ_DATA, dev); 354 355 skb->protocol=eth_type_trans(skb,dev); 356 357 netif_rx(skb); 358 359 /* update stats */ 360 dev->stats.rx_packets++; /* count all receives */ 361 dev->stats.rx_bytes += size; /* count all received bytes */ 362 363 /* 364 * If any worth-while packets have been received, netif_rx() 365 * will work on them when we get to the tasklets. 366 */ 367} 368 369static const struct net_device_ops de600_netdev_ops = { 370 .ndo_open = de600_open, 371 .ndo_stop = de600_close, 372 .ndo_start_xmit = de600_start_xmit, 373 .ndo_change_mtu = eth_change_mtu, 374 .ndo_set_mac_address = eth_mac_addr, 375 .ndo_validate_addr = eth_validate_addr, 376}; 377 378 379static struct net_device * __init de600_probe(void) 380{ 381 int i; 382 struct net_device *dev; 383 int err; 384 385 dev = alloc_etherdev(0); 386 if (!dev) 387 return ERR_PTR(-ENOMEM); 388 389 390 if (!request_region(DE600_IO, 3, "de600")) { 391 printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO); 392 err = -EBUSY; 393 goto out; 394 } 395 396 printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name); 397 /* Alpha testers must have the version number to report bugs. */ 398 pr_debug("%s", version); 399 400 /* probe for adapter */ 401 err = -ENODEV; 402 rx_page = 0; 403 select_nic(); 404 (void)de600_read_status(dev); 405 de600_put_command(RESET); 406 de600_put_command(STOP_RESET); 407 if (de600_read_status(dev) & 0xf0) { 408 printk(": not at I/O %#3x.\n", DATA_PORT); 409 goto out1; 410 } 411 412 /* 413 * Maybe we found one, 414 * have to check if it is a D-Link DE-600 adapter... 415 */ 416 417 /* Get the adapter ethernet address from the ROM */ 418 de600_setup_address(NODE_ADDRESS, RW_ADDR); 419 for (i = 0; i < ETH_ALEN; i++) { 420 dev->dev_addr[i] = de600_read_byte(READ_DATA, dev); 421 dev->broadcast[i] = 0xff; 422 } 423 424 /* Check magic code */ 425 if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) { 426 /* OK, install real address */ 427 dev->dev_addr[0] = 0x00; 428 dev->dev_addr[1] = 0x80; 429 dev->dev_addr[2] = 0xc8; 430 dev->dev_addr[3] &= 0x0f; 431 dev->dev_addr[3] |= 0x70; 432 } else { 433 printk(" not identified in the printer port\n"); 434 goto out1; 435 } 436 437 printk(", Ethernet Address: %pM\n", dev->dev_addr); 438 439 dev->netdev_ops = &de600_netdev_ops; 440 441 dev->flags&=~IFF_MULTICAST; 442 443 select_prn(); 444 445 err = register_netdev(dev); 446 if (err) 447 goto out1; 448 449 return dev; 450 451out1: 452 release_region(DE600_IO, 3); 453out: 454 free_netdev(dev); 455 return ERR_PTR(err); 456} 457 458static int adapter_init(struct net_device *dev) 459{ 460 int i; 461 462 select_nic(); 463 rx_page = 0; /* used by RESET */ 464 de600_put_command(RESET); 465 de600_put_command(STOP_RESET); 466 467 /* Check if it is still there... */ 468 /* Get the some bytes of the adapter ethernet address from the ROM */ 469 de600_setup_address(NODE_ADDRESS, RW_ADDR); 470 de600_read_byte(READ_DATA, dev); 471 if ((de600_read_byte(READ_DATA, dev) != 0xde) || 472 (de600_read_byte(READ_DATA, dev) != 0x15)) { 473 /* was: if (de600_read_status(dev) & 0xf0) { */ 474 printk("Something has happened to the DE-600! Please check it and do a new ifconfig!\n"); 475 /* Goodbye, cruel world... */ 476 dev->flags &= ~IFF_UP; 477 de600_close(dev); 478 was_down = 1; 479 netif_stop_queue(dev); /* Transmit busy... */ 480 return 1; /* failed */ 481 } 482 483 if (was_down) { 484 printk(KERN_INFO "%s: Thanks, I feel much better now!\n", dev->name); 485 was_down = 0; 486 } 487 488 tx_fifo_in = 0; 489 tx_fifo_out = 0; 490 free_tx_pages = TX_PAGES; 491 492 493 /* set the ether address. */ 494 de600_setup_address(NODE_ADDRESS, RW_ADDR); 495 for (i = 0; i < ETH_ALEN; i++) 496 de600_put_byte(dev->dev_addr[i]); 497 498 /* where to start saving incoming packets */ 499 rx_page = RX_BP | RX_BASE_PAGE; 500 de600_setup_address(MEM_4K, RW_ADDR); 501 /* Enable receiver */ 502 de600_put_command(RX_ENABLE); 503 select_prn(); 504 505 netif_start_queue(dev); 506 507 return 0; /* OK */ 508} 509 510static struct net_device *de600_dev; 511 512static int __init de600_init(void) 513{ 514 de600_dev = de600_probe(); 515 if (IS_ERR(de600_dev)) 516 return PTR_ERR(de600_dev); 517 return 0; 518} 519 520static void __exit de600_exit(void) 521{ 522 unregister_netdev(de600_dev); 523 release_region(DE600_IO, 3); 524 free_netdev(de600_dev); 525} 526 527module_init(de600_init); 528module_exit(de600_exit); 529 530MODULE_LICENSE("GPL"); 531