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

Configure Feed

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

at v3.0-rc6 858 lines 24 kB view raw
1/* 2 * Amiga Linux/m68k Ariadne Ethernet Driver 3 * 4 * © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org) 5 * Peter De Schrijver (p2@mind.be) 6 * 7 * --------------------------------------------------------------------------- 8 * 9 * This program is based on 10 * 11 * lance.c: An AMD LANCE ethernet driver for linux. 12 * Written 1993-94 by Donald Becker. 13 * 14 * Am79C960: PCnet(tm)-ISA Single-Chip Ethernet Controller 15 * Advanced Micro Devices 16 * Publication #16907, Rev. B, Amendment/0, May 1994 17 * 18 * MC68230: Parallel Interface/Timer (PI/T) 19 * Motorola Semiconductors, December, 1983 20 * 21 * --------------------------------------------------------------------------- 22 * 23 * This file is subject to the terms and conditions of the GNU General Public 24 * License. See the file COPYING in the main directory of the Linux 25 * distribution for more details. 26 * 27 * --------------------------------------------------------------------------- 28 * 29 * The Ariadne is a Zorro-II board made by Village Tronic. It contains: 30 * 31 * - an Am79C960 PCnet-ISA Single-Chip Ethernet Controller with both 32 * 10BASE-2 (thin coax) and 10BASE-T (UTP) connectors 33 * 34 * - an MC68230 Parallel Interface/Timer configured as 2 parallel ports 35 */ 36 37#include <linux/module.h> 38#include <linux/stddef.h> 39#include <linux/kernel.h> 40#include <linux/string.h> 41#include <linux/errno.h> 42#include <linux/ioport.h> 43#include <linux/netdevice.h> 44#include <linux/etherdevice.h> 45#include <linux/interrupt.h> 46#include <linux/skbuff.h> 47#include <linux/init.h> 48#include <linux/zorro.h> 49#include <linux/bitops.h> 50 51#include <asm/amigaints.h> 52#include <asm/amigahw.h> 53#include <asm/irq.h> 54 55#include "ariadne.h" 56 57 58#ifdef ARIADNE_DEBUG 59int ariadne_debug = ARIADNE_DEBUG; 60#else 61int ariadne_debug = 1; 62#endif 63 64 65 /* 66 * Macros to Fix Endianness problems 67 */ 68 69 /* Swap the Bytes in a WORD */ 70#define swapw(x) (((x>>8)&0x00ff)|((x<<8)&0xff00)) 71 /* Get the Low BYTE in a WORD */ 72#define lowb(x) (x&0xff) 73 /* Get the Swapped High WORD in a LONG */ 74#define swhighw(x) ((((x)>>8)&0xff00)|(((x)>>24)&0x00ff)) 75 /* Get the Swapped Low WORD in a LONG */ 76#define swloww(x) ((((x)<<8)&0xff00)|(((x)>>8)&0x00ff)) 77 78 79 /* 80 * Transmit/Receive Ring Definitions 81 */ 82 83#define TX_RING_SIZE 5 84#define RX_RING_SIZE 16 85 86#define PKT_BUF_SIZE 1520 87 88 89 /* 90 * Private Device Data 91 */ 92 93struct ariadne_private { 94 volatile struct TDRE *tx_ring[TX_RING_SIZE]; 95 volatile struct RDRE *rx_ring[RX_RING_SIZE]; 96 volatile u_short *tx_buff[TX_RING_SIZE]; 97 volatile u_short *rx_buff[RX_RING_SIZE]; 98 int cur_tx, cur_rx; /* The next free ring entry */ 99 int dirty_tx; /* The ring entries to be free()ed. */ 100 char tx_full; 101}; 102 103 104 /* 105 * Structure Created in the Ariadne's RAM Buffer 106 */ 107 108struct lancedata { 109 struct TDRE tx_ring[TX_RING_SIZE]; 110 struct RDRE rx_ring[RX_RING_SIZE]; 111 u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)]; 112 u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)]; 113}; 114 115static int ariadne_open(struct net_device *dev); 116static void ariadne_init_ring(struct net_device *dev); 117static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb, 118 struct net_device *dev); 119static void ariadne_tx_timeout(struct net_device *dev); 120static int ariadne_rx(struct net_device *dev); 121static void ariadne_reset(struct net_device *dev); 122static irqreturn_t ariadne_interrupt(int irq, void *data); 123static int ariadne_close(struct net_device *dev); 124static struct net_device_stats *ariadne_get_stats(struct net_device *dev); 125static void set_multicast_list(struct net_device *dev); 126 127 128static void memcpyw(volatile u_short *dest, u_short *src, int len) 129{ 130 while (len >= 2) { 131 *(dest++) = *(src++); 132 len -= 2; 133 } 134 if (len == 1) 135 *dest = (*(u_char *)src)<<8; 136} 137 138 139static int __devinit ariadne_init_one(struct zorro_dev *z, 140 const struct zorro_device_id *ent); 141static void __devexit ariadne_remove_one(struct zorro_dev *z); 142 143 144static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = { 145 { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE }, 146 { 0 } 147}; 148MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl); 149 150static struct zorro_driver ariadne_driver = { 151 .name = "ariadne", 152 .id_table = ariadne_zorro_tbl, 153 .probe = ariadne_init_one, 154 .remove = __devexit_p(ariadne_remove_one), 155}; 156 157static const struct net_device_ops ariadne_netdev_ops = { 158 .ndo_open = ariadne_open, 159 .ndo_stop = ariadne_close, 160 .ndo_start_xmit = ariadne_start_xmit, 161 .ndo_tx_timeout = ariadne_tx_timeout, 162 .ndo_get_stats = ariadne_get_stats, 163 .ndo_set_multicast_list = set_multicast_list, 164 .ndo_validate_addr = eth_validate_addr, 165 .ndo_change_mtu = eth_change_mtu, 166 .ndo_set_mac_address = eth_mac_addr, 167}; 168 169static int __devinit ariadne_init_one(struct zorro_dev *z, 170 const struct zorro_device_id *ent) 171{ 172 unsigned long board = z->resource.start; 173 unsigned long base_addr = board+ARIADNE_LANCE; 174 unsigned long mem_start = board+ARIADNE_RAM; 175 struct resource *r1, *r2; 176 struct net_device *dev; 177 struct ariadne_private *priv; 178 int err; 179 180 r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960"); 181 if (!r1) 182 return -EBUSY; 183 r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM"); 184 if (!r2) { 185 release_mem_region(base_addr, sizeof(struct Am79C960)); 186 return -EBUSY; 187 } 188 189 dev = alloc_etherdev(sizeof(struct ariadne_private)); 190 if (dev == NULL) { 191 release_mem_region(base_addr, sizeof(struct Am79C960)); 192 release_mem_region(mem_start, ARIADNE_RAM_SIZE); 193 return -ENOMEM; 194 } 195 196 priv = netdev_priv(dev); 197 198 r1->name = dev->name; 199 r2->name = dev->name; 200 201 dev->dev_addr[0] = 0x00; 202 dev->dev_addr[1] = 0x60; 203 dev->dev_addr[2] = 0x30; 204 dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff; 205 dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff; 206 dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff; 207 dev->base_addr = ZTWO_VADDR(base_addr); 208 dev->mem_start = ZTWO_VADDR(mem_start); 209 dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; 210 211 dev->netdev_ops = &ariadne_netdev_ops; 212 dev->watchdog_timeo = 5*HZ; 213 214 err = register_netdev(dev); 215 if (err) { 216 release_mem_region(base_addr, sizeof(struct Am79C960)); 217 release_mem_region(mem_start, ARIADNE_RAM_SIZE); 218 free_netdev(dev); 219 return err; 220 } 221 zorro_set_drvdata(z, dev); 222 223 printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address %pM\n", 224 dev->name, board, dev->dev_addr); 225 226 return 0; 227} 228 229 230static int ariadne_open(struct net_device *dev) 231{ 232 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 233 u_short in; 234 u_long version; 235 int i; 236 237 /* Reset the LANCE */ 238 in = lance->Reset; 239 240 /* Stop the LANCE */ 241 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 242 lance->RDP = STOP; 243 244 /* Check the LANCE version */ 245 lance->RAP = CSR88; /* Chip ID */ 246 version = swapw(lance->RDP); 247 lance->RAP = CSR89; /* Chip ID */ 248 version |= swapw(lance->RDP)<<16; 249 if ((version & 0x00000fff) != 0x00000003) { 250 printk(KERN_WARNING "ariadne_open: Couldn't find AMD Ethernet Chip\n"); 251 return -EAGAIN; 252 } 253 if ((version & 0x0ffff000) != 0x00003000) { 254 printk(KERN_WARNING "ariadne_open: Couldn't find Am79C960 (Wrong part " 255 "number = %ld)\n", (version & 0x0ffff000)>>12); 256 return -EAGAIN; 257 } 258#if 0 259 printk(KERN_DEBUG "ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n", 260 (version & 0xf0000000)>>28); 261#endif 262 263 ariadne_init_ring(dev); 264 265 /* Miscellaneous Stuff */ 266 lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */ 267 lance->RDP = 0x0000; 268 lance->RAP = CSR4; /* Test and Features Control */ 269 lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM; 270 271 /* Set the Multicast Table */ 272 lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ 273 lance->RDP = 0x0000; 274 lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ 275 lance->RDP = 0x0000; 276 lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ 277 lance->RDP = 0x0000; 278 lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ 279 lance->RDP = 0x0000; 280 281 /* Set the Ethernet Hardware Address */ 282 lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */ 283 lance->RDP = ((u_short *)&dev->dev_addr[0])[0]; 284 lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */ 285 lance->RDP = ((u_short *)&dev->dev_addr[0])[1]; 286 lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */ 287 lance->RDP = ((u_short *)&dev->dev_addr[0])[2]; 288 289 /* Set the Init Block Mode */ 290 lance->RAP = CSR15; /* Mode Register */ 291 lance->RDP = 0x0000; 292 293 /* Set the Transmit Descriptor Ring Pointer */ 294 lance->RAP = CSR30; /* Base Address of Transmit Ring */ 295 lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); 296 lance->RAP = CSR31; /* Base Address of transmit Ring */ 297 lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); 298 299 /* Set the Receive Descriptor Ring Pointer */ 300 lance->RAP = CSR24; /* Base Address of Receive Ring */ 301 lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); 302 lance->RAP = CSR25; /* Base Address of Receive Ring */ 303 lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); 304 305 /* Set the Number of RX and TX Ring Entries */ 306 lance->RAP = CSR76; /* Receive Ring Length */ 307 lance->RDP = swapw(((u_short)-RX_RING_SIZE)); 308 lance->RAP = CSR78; /* Transmit Ring Length */ 309 lance->RDP = swapw(((u_short)-TX_RING_SIZE)); 310 311 /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */ 312 lance->RAP = ISACSR2; /* Miscellaneous Configuration */ 313 lance->IDP = ASEL; 314 315 /* LED Control */ 316 lance->RAP = ISACSR5; /* LED1 Status */ 317 lance->IDP = PSE|XMTE; 318 lance->RAP = ISACSR6; /* LED2 Status */ 319 lance->IDP = PSE|COLE; 320 lance->RAP = ISACSR7; /* LED3 Status */ 321 lance->IDP = PSE|RCVE; 322 323 netif_start_queue(dev); 324 325 i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED, 326 dev->name, dev); 327 if (i) return i; 328 329 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 330 lance->RDP = INEA|STRT; 331 332 return 0; 333} 334 335 336static void ariadne_init_ring(struct net_device *dev) 337{ 338 struct ariadne_private *priv = netdev_priv(dev); 339 volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; 340 int i; 341 342 netif_stop_queue(dev); 343 344 priv->tx_full = 0; 345 priv->cur_rx = priv->cur_tx = 0; 346 priv->dirty_tx = 0; 347 348 /* Set up TX Ring */ 349 for (i = 0; i < TX_RING_SIZE; i++) { 350 volatile struct TDRE *t = &lancedata->tx_ring[i]; 351 t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])); 352 t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) | 353 TF_STP | TF_ENP; 354 t->TMD2 = swapw((u_short)-PKT_BUF_SIZE); 355 t->TMD3 = 0; 356 priv->tx_ring[i] = &lancedata->tx_ring[i]; 357 priv->tx_buff[i] = lancedata->tx_buff[i]; 358#if 0 359 printk(KERN_DEBUG "TX Entry %2d at %p, Buf at %p\n", i, 360 &lancedata->tx_ring[i], lancedata->tx_buff[i]); 361#endif 362 } 363 364 /* Set up RX Ring */ 365 for (i = 0; i < RX_RING_SIZE; i++) { 366 volatile struct RDRE *r = &lancedata->rx_ring[i]; 367 r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])); 368 r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) | 369 RF_OWN; 370 r->RMD2 = swapw((u_short)-PKT_BUF_SIZE); 371 r->RMD3 = 0x0000; 372 priv->rx_ring[i] = &lancedata->rx_ring[i]; 373 priv->rx_buff[i] = lancedata->rx_buff[i]; 374#if 0 375 printk(KERN_DEBUG "RX Entry %2d at %p, Buf at %p\n", i, 376 &lancedata->rx_ring[i], lancedata->rx_buff[i]); 377#endif 378 } 379} 380 381 382static int ariadne_close(struct net_device *dev) 383{ 384 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 385 386 netif_stop_queue(dev); 387 388 lance->RAP = CSR112; /* Missed Frame Count */ 389 dev->stats.rx_missed_errors = swapw(lance->RDP); 390 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 391 392 if (ariadne_debug > 1) { 393 printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", 394 dev->name, lance->RDP); 395 printk(KERN_DEBUG "%s: %lu packets missed\n", dev->name, 396 dev->stats.rx_missed_errors); 397 } 398 399 /* We stop the LANCE here -- it occasionally polls memory if we don't. */ 400 lance->RDP = STOP; 401 402 free_irq(IRQ_AMIGA_PORTS, dev); 403 404 return 0; 405} 406 407 408static inline void ariadne_reset(struct net_device *dev) 409{ 410 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 411 412 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 413 lance->RDP = STOP; 414 ariadne_init_ring(dev); 415 lance->RDP = INEA|STRT; 416 netif_start_queue(dev); 417} 418 419 420static irqreturn_t ariadne_interrupt(int irq, void *data) 421{ 422 struct net_device *dev = (struct net_device *)data; 423 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 424 struct ariadne_private *priv; 425 int csr0, boguscnt; 426 int handled = 0; 427 428 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 429 430 if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ 431 return IRQ_NONE; /* generated by the board. */ 432 433 priv = netdev_priv(dev); 434 435 boguscnt = 10; 436 while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) { 437 /* Acknowledge all of the current interrupt sources ASAP. */ 438 lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT); 439 440#if 0 441 if (ariadne_debug > 5) { 442 printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.", 443 dev->name, csr0, lance->RDP); 444 printk("["); 445 if (csr0 & INTR) 446 printk(" INTR"); 447 if (csr0 & INEA) 448 printk(" INEA"); 449 if (csr0 & RXON) 450 printk(" RXON"); 451 if (csr0 & TXON) 452 printk(" TXON"); 453 if (csr0 & TDMD) 454 printk(" TDMD"); 455 if (csr0 & STOP) 456 printk(" STOP"); 457 if (csr0 & STRT) 458 printk(" STRT"); 459 if (csr0 & INIT) 460 printk(" INIT"); 461 if (csr0 & ERR) 462 printk(" ERR"); 463 if (csr0 & BABL) 464 printk(" BABL"); 465 if (csr0 & CERR) 466 printk(" CERR"); 467 if (csr0 & MISS) 468 printk(" MISS"); 469 if (csr0 & MERR) 470 printk(" MERR"); 471 if (csr0 & RINT) 472 printk(" RINT"); 473 if (csr0 & TINT) 474 printk(" TINT"); 475 if (csr0 & IDON) 476 printk(" IDON"); 477 printk(" ]\n"); 478 } 479#endif 480 481 if (csr0 & RINT) { /* Rx interrupt */ 482 handled = 1; 483 ariadne_rx(dev); 484 } 485 486 if (csr0 & TINT) { /* Tx-done interrupt */ 487 int dirty_tx = priv->dirty_tx; 488 489 handled = 1; 490 while (dirty_tx < priv->cur_tx) { 491 int entry = dirty_tx % TX_RING_SIZE; 492 int status = lowb(priv->tx_ring[entry]->TMD1); 493 494 if (status & TF_OWN) 495 break; /* It still hasn't been Txed */ 496 497 priv->tx_ring[entry]->TMD1 &= 0xff00; 498 499 if (status & TF_ERR) { 500 /* There was an major error, log it. */ 501 int err_status = priv->tx_ring[entry]->TMD3; 502 dev->stats.tx_errors++; 503 if (err_status & EF_RTRY) 504 dev->stats.tx_aborted_errors++; 505 if (err_status & EF_LCAR) 506 dev->stats.tx_carrier_errors++; 507 if (err_status & EF_LCOL) 508 dev->stats.tx_window_errors++; 509 if (err_status & EF_UFLO) { 510 /* Ackk! On FIFO errors the Tx unit is turned off! */ 511 dev->stats.tx_fifo_errors++; 512 /* Remove this verbosity later! */ 513 printk(KERN_ERR "%s: Tx FIFO error! Status %4.4x.\n", 514 dev->name, csr0); 515 /* Restart the chip. */ 516 lance->RDP = STRT; 517 } 518 } else { 519 if (status & (TF_MORE|TF_ONE)) 520 dev->stats.collisions++; 521 dev->stats.tx_packets++; 522 } 523 dirty_tx++; 524 } 525 526#ifndef final_version 527 if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) { 528 printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, " 529 "full=%d.\n", dirty_tx, priv->cur_tx, priv->tx_full); 530 dirty_tx += TX_RING_SIZE; 531 } 532#endif 533 534 if (priv->tx_full && netif_queue_stopped(dev) && 535 dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) { 536 /* The ring is no longer full. */ 537 priv->tx_full = 0; 538 netif_wake_queue(dev); 539 } 540 541 priv->dirty_tx = dirty_tx; 542 } 543 544 /* Log misc errors. */ 545 if (csr0 & BABL) { 546 handled = 1; 547 dev->stats.tx_errors++; /* Tx babble. */ 548 } 549 if (csr0 & MISS) { 550 handled = 1; 551 dev->stats.rx_errors++; /* Missed a Rx frame. */ 552 } 553 if (csr0 & MERR) { 554 handled = 1; 555 printk(KERN_ERR "%s: Bus master arbitration failure, status " 556 "%4.4x.\n", dev->name, csr0); 557 /* Restart the chip. */ 558 lance->RDP = STRT; 559 } 560 } 561 562 /* Clear any other interrupt, and set interrupt enable. */ 563 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 564 lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON; 565 566#if 0 567 if (ariadne_debug > 4) 568 printk(KERN_DEBUG "%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, 569 lance->RAP, lance->RDP); 570#endif 571 return IRQ_RETVAL(handled); 572} 573 574 575static void ariadne_tx_timeout(struct net_device *dev) 576{ 577 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 578 579 printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n", 580 dev->name, lance->RDP); 581 ariadne_reset(dev); 582 netif_wake_queue(dev); 583} 584 585 586static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb, 587 struct net_device *dev) 588{ 589 struct ariadne_private *priv = netdev_priv(dev); 590 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 591 int entry; 592 unsigned long flags; 593 int len = skb->len; 594 595#if 0 596 if (ariadne_debug > 3) { 597 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 598 printk(KERN_DEBUG "%s: ariadne_start_xmit() called, csr0 %4.4x.\n", 599 dev->name, lance->RDP); 600 lance->RDP = 0x0000; 601 } 602#endif 603 604 /* FIXME: is the 79C960 new enough to do its own padding right ? */ 605 if (skb->len < ETH_ZLEN) 606 { 607 if (skb_padto(skb, ETH_ZLEN)) 608 return NETDEV_TX_OK; 609 len = ETH_ZLEN; 610 } 611 612 /* Fill in a Tx ring entry */ 613 614#if 0 615{ 616 printk(KERN_DEBUG "TX pkt type 0x%04x from %pM to %pM " 617 " data 0x%08x len %d\n", 618 ((u_short *)skb->data)[6], 619 skb->data + 6, skb->data, 620 (int)skb->data, (int)skb->len); 621} 622#endif 623 624 local_irq_save(flags); 625 626 entry = priv->cur_tx % TX_RING_SIZE; 627 628 /* Caution: the write order is important here, set the base address with 629 the "ownership" bits last. */ 630 631 priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); 632 priv->tx_ring[entry]->TMD3 = 0x0000; 633 memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); 634 635#if 0 636 { 637 int i, len; 638 639 len = skb->len > 64 ? 64 : skb->len; 640 len >>= 1; 641 for (i = 0; i < len; i += 8) { 642 int j; 643 printk(KERN_DEBUG "%04x:", i); 644 for (j = 0; (j < 8) && ((i+j) < len); j++) { 645 if (!(j & 1)) 646 printk(" "); 647 printk("%04x", priv->tx_buff[entry][i+j]); 648 } 649 printk("\n"); 650 } 651 } 652#endif 653 654 priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1&0xff00)|TF_OWN|TF_STP|TF_ENP; 655 656 dev_kfree_skb(skb); 657 658 priv->cur_tx++; 659 if ((priv->cur_tx >= TX_RING_SIZE) && (priv->dirty_tx >= TX_RING_SIZE)) { 660 661#if 0 662 printk(KERN_DEBUG "*** Subtracting TX_RING_SIZE from cur_tx (%d) and " 663 "dirty_tx (%d)\n", priv->cur_tx, priv->dirty_tx); 664#endif 665 666 priv->cur_tx -= TX_RING_SIZE; 667 priv->dirty_tx -= TX_RING_SIZE; 668 } 669 dev->stats.tx_bytes += len; 670 671 /* Trigger an immediate send poll. */ 672 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 673 lance->RDP = INEA|TDMD; 674 675 if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) { 676 netif_stop_queue(dev); 677 priv->tx_full = 1; 678 } 679 local_irq_restore(flags); 680 681 return NETDEV_TX_OK; 682} 683 684 685static int ariadne_rx(struct net_device *dev) 686{ 687 struct ariadne_private *priv = netdev_priv(dev); 688 int entry = priv->cur_rx % RX_RING_SIZE; 689 int i; 690 691 /* If we own the next entry, it's a new packet. Send it up. */ 692 while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) { 693 int status = lowb(priv->rx_ring[entry]->RMD1); 694 695 if (status != (RF_STP|RF_ENP)) { /* There was an error. */ 696 /* There is a tricky error noted by John Murphy, 697 <murf@perftech.com> to Russ Nelson: Even with full-sized 698 buffers it's possible for a jabber packet to use two 699 buffers, with only the last correctly noting the error. */ 700 if (status & RF_ENP) 701 /* Only count a general error at the end of a packet.*/ 702 dev->stats.rx_errors++; 703 if (status & RF_FRAM) 704 dev->stats.rx_frame_errors++; 705 if (status & RF_OFLO) 706 dev->stats.rx_over_errors++; 707 if (status & RF_CRC) 708 dev->stats.rx_crc_errors++; 709 if (status & RF_BUFF) 710 dev->stats.rx_fifo_errors++; 711 priv->rx_ring[entry]->RMD1 &= 0xff00|RF_STP|RF_ENP; 712 } else { 713 /* Malloc up new buffer, compatible with net-3. */ 714 short pkt_len = swapw(priv->rx_ring[entry]->RMD3); 715 struct sk_buff *skb; 716 717 skb = dev_alloc_skb(pkt_len+2); 718 if (skb == NULL) { 719 printk(KERN_WARNING "%s: Memory squeeze, deferring packet.\n", 720 dev->name); 721 for (i = 0; i < RX_RING_SIZE; i++) 722 if (lowb(priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1) & RF_OWN) 723 break; 724 725 if (i > RX_RING_SIZE-2) { 726 dev->stats.rx_dropped++; 727 priv->rx_ring[entry]->RMD1 |= RF_OWN; 728 priv->cur_rx++; 729 } 730 break; 731 } 732 733 734 skb_reserve(skb,2); /* 16 byte align */ 735 skb_put(skb,pkt_len); /* Make room */ 736 skb_copy_to_linear_data(skb, (char *)priv->rx_buff[entry], pkt_len); 737 skb->protocol=eth_type_trans(skb,dev); 738#if 0 739{ 740 printk(KERN_DEBUG "RX pkt type 0x%04x from ", 741 ((u_short *)skb->data)[6]); 742 { 743 u_char *ptr = &((u_char *)skb->data)[6]; 744 printk("%pM", ptr); 745 } 746 printk(" to "); 747 { 748 u_char *ptr = (u_char *)skb->data; 749 printk("%pM", ptr); 750 } 751 printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len); 752} 753#endif 754 755 netif_rx(skb); 756 dev->stats.rx_packets++; 757 dev->stats.rx_bytes += pkt_len; 758 } 759 760 priv->rx_ring[entry]->RMD1 |= RF_OWN; 761 entry = (++priv->cur_rx) % RX_RING_SIZE; 762 } 763 764 priv->cur_rx = priv->cur_rx % RX_RING_SIZE; 765 766 /* We should check that at least two ring entries are free. If not, 767 we should free one and mark stats->rx_dropped++. */ 768 769 return 0; 770} 771 772 773static struct net_device_stats *ariadne_get_stats(struct net_device *dev) 774{ 775 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 776 short saved_addr; 777 unsigned long flags; 778 779 local_irq_save(flags); 780 saved_addr = lance->RAP; 781 lance->RAP = CSR112; /* Missed Frame Count */ 782 dev->stats.rx_missed_errors = swapw(lance->RDP); 783 lance->RAP = saved_addr; 784 local_irq_restore(flags); 785 786 return &dev->stats; 787} 788 789 790/* Set or clear the multicast filter for this adaptor. 791 num_addrs == -1 Promiscuous mode, receive all packets 792 num_addrs == 0 Normal mode, clear multicast list 793 num_addrs > 0 Multicast mode, receive normal and MC packets, and do 794 best-effort filtering. 795 */ 796static void set_multicast_list(struct net_device *dev) 797{ 798 volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; 799 800 if (!netif_running(dev)) 801 return; 802 803 netif_stop_queue(dev); 804 805 /* We take the simple way out and always enable promiscuous mode. */ 806 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 807 lance->RDP = STOP; /* Temporarily stop the lance. */ 808 ariadne_init_ring(dev); 809 810 if (dev->flags & IFF_PROMISC) { 811 lance->RAP = CSR15; /* Mode Register */ 812 lance->RDP = PROM; /* Set promiscuous mode */ 813 } else { 814 short multicast_table[4]; 815 int num_addrs = netdev_mc_count(dev); 816 int i; 817 /* We don't use the multicast table, but rely on upper-layer filtering. */ 818 memset(multicast_table, (num_addrs == 0) ? 0 : -1, 819 sizeof(multicast_table)); 820 for (i = 0; i < 4; i++) { 821 lance->RAP = CSR8+(i<<8); /* Logical Address Filter */ 822 lance->RDP = swapw(multicast_table[i]); 823 } 824 lance->RAP = CSR15; /* Mode Register */ 825 lance->RDP = 0x0000; /* Unset promiscuous mode */ 826 } 827 828 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ 829 lance->RDP = INEA|STRT|IDON; /* Resume normal operation. */ 830 831 netif_wake_queue(dev); 832} 833 834 835static void __devexit ariadne_remove_one(struct zorro_dev *z) 836{ 837 struct net_device *dev = zorro_get_drvdata(z); 838 839 unregister_netdev(dev); 840 release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960)); 841 release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE); 842 free_netdev(dev); 843} 844 845static int __init ariadne_init_module(void) 846{ 847 return zorro_register_driver(&ariadne_driver); 848} 849 850static void __exit ariadne_cleanup_module(void) 851{ 852 zorro_unregister_driver(&ariadne_driver); 853} 854 855module_init(ariadne_init_module); 856module_exit(ariadne_cleanup_module); 857 858MODULE_LICENSE("GPL");