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.13-rc2 616 lines 16 kB view raw
1/* 2 * sonic.c 3 * 4 * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) 5 * 6 * This driver is based on work from Andreas Busse, but most of 7 * the code is rewritten. 8 * 9 * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) 10 * 11 * Core code included by system sonic drivers 12 */ 13 14/* 15 * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook, 16 * National Semiconductors data sheet for the DP83932B Sonic Ethernet 17 * controller, and the files "8390.c" and "skeleton.c" in this directory. 18 */ 19 20 21 22/* 23 * Open/initialize the SONIC controller. 24 * 25 * This routine should set everything up anew at each open, even 26 * registers that "should" only need to be set once at boot, so that 27 * there is non-reboot way to recover if something goes wrong. 28 */ 29static int sonic_open(struct net_device *dev) 30{ 31 if (sonic_debug > 2) 32 printk("sonic_open: initializing sonic driver.\n"); 33 34 /* 35 * We don't need to deal with auto-irq stuff since we 36 * hardwire the sonic interrupt. 37 */ 38/* 39 * XXX Horrible work around: We install sonic_interrupt as fast interrupt. 40 * This means that during execution of the handler interrupt are disabled 41 * covering another bug otherwise corrupting data. This doesn't mean 42 * this glue works ok under all situations. 43 */ 44// if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) { 45 if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT, 46 "sonic", dev)) { 47 printk("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); 48 return -EAGAIN; 49 } 50 51 /* 52 * Initialize the SONIC 53 */ 54 sonic_init(dev); 55 56 netif_start_queue(dev); 57 58 if (sonic_debug > 2) 59 printk("sonic_open: Initialization done.\n"); 60 61 return 0; 62} 63 64 65/* 66 * Close the SONIC device 67 */ 68static int sonic_close(struct net_device *dev) 69{ 70 unsigned int base_addr = dev->base_addr; 71 72 if (sonic_debug > 2) 73 printk("sonic_close\n"); 74 75 netif_stop_queue(dev); 76 77 /* 78 * stop the SONIC, disable interrupts 79 */ 80 SONIC_WRITE(SONIC_ISR, 0x7fff); 81 SONIC_WRITE(SONIC_IMR, 0); 82 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); 83 84 sonic_free_irq(dev->irq, dev); /* release the IRQ */ 85 86 return 0; 87} 88 89static void sonic_tx_timeout(struct net_device *dev) 90{ 91 struct sonic_local *lp = (struct sonic_local *) dev->priv; 92 printk("%s: transmit timed out.\n", dev->name); 93 94 /* Try to restart the adaptor. */ 95 sonic_init(dev); 96 lp->stats.tx_errors++; 97 dev->trans_start = jiffies; 98 netif_wake_queue(dev); 99} 100 101/* 102 * transmit packet 103 */ 104static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) 105{ 106 struct sonic_local *lp = (struct sonic_local *) dev->priv; 107 unsigned int base_addr = dev->base_addr; 108 unsigned int laddr; 109 int entry, length; 110 111 netif_stop_queue(dev); 112 113 if (sonic_debug > 2) 114 printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); 115 116 /* 117 * Map the packet data into the logical DMA address space 118 */ 119 if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) { 120 printk("%s: no VDMA entry for transmit available.\n", 121 dev->name); 122 dev_kfree_skb(skb); 123 netif_start_queue(dev); 124 return 1; 125 } 126 entry = lp->cur_tx & SONIC_TDS_MASK; 127 lp->tx_laddr[entry] = laddr; 128 lp->tx_skb[entry] = skb; 129 130 length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; 131 flush_cache_all(); 132 133 /* 134 * Setup the transmit descriptor and issue the transmit command. 135 */ 136 lp->tda[entry].tx_status = 0; /* clear status */ 137 lp->tda[entry].tx_frag_count = 1; /* single fragment */ 138 lp->tda[entry].tx_pktsize = length; /* length of packet */ 139 lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff; 140 lp->tda[entry].tx_frag_ptr_h = laddr >> 16; 141 lp->tda[entry].tx_frag_size = length; 142 lp->cur_tx++; 143 lp->stats.tx_bytes += length; 144 145 if (sonic_debug > 2) 146 printk("sonic_send_packet: issueing Tx command\n"); 147 148 SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); 149 150 dev->trans_start = jiffies; 151 152 if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS) 153 netif_start_queue(dev); 154 else 155 lp->tx_full = 1; 156 157 return 0; 158} 159 160/* 161 * The typical workload of the driver: 162 * Handle the network interface interrupts. 163 */ 164static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) 165{ 166 struct net_device *dev = (struct net_device *) dev_id; 167 unsigned int base_addr = dev->base_addr; 168 struct sonic_local *lp; 169 int status; 170 171 if (dev == NULL) { 172 printk("sonic_interrupt: irq %d for unknown device.\n", irq); 173 return IRQ_NONE; 174 } 175 176 lp = (struct sonic_local *) dev->priv; 177 178 status = SONIC_READ(SONIC_ISR); 179 SONIC_WRITE(SONIC_ISR, 0x7fff); /* clear all bits */ 180 181 if (sonic_debug > 2) 182 printk("sonic_interrupt: ISR=%x\n", status); 183 184 if (status & SONIC_INT_PKTRX) { 185 sonic_rx(dev); /* got packet(s) */ 186 } 187 188 if (status & SONIC_INT_TXDN) { 189 int dirty_tx = lp->dirty_tx; 190 191 while (dirty_tx < lp->cur_tx) { 192 int entry = dirty_tx & SONIC_TDS_MASK; 193 int status = lp->tda[entry].tx_status; 194 195 if (sonic_debug > 3) 196 printk 197 ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n", 198 status, lp->cur_tx, lp->dirty_tx); 199 200 if (status == 0) { 201 /* It still hasn't been Txed, kick the sonic again */ 202 SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); 203 break; 204 } 205 206 /* put back EOL and free descriptor */ 207 lp->tda[entry].tx_frag_count = 0; 208 lp->tda[entry].tx_status = 0; 209 210 if (status & 0x0001) 211 lp->stats.tx_packets++; 212 else { 213 lp->stats.tx_errors++; 214 if (status & 0x0642) 215 lp->stats.tx_aborted_errors++; 216 if (status & 0x0180) 217 lp->stats.tx_carrier_errors++; 218 if (status & 0x0020) 219 lp->stats.tx_window_errors++; 220 if (status & 0x0004) 221 lp->stats.tx_fifo_errors++; 222 } 223 224 /* We must free the original skb */ 225 if (lp->tx_skb[entry]) { 226 dev_kfree_skb_irq(lp->tx_skb[entry]); 227 lp->tx_skb[entry] = 0; 228 } 229 /* and the VDMA address */ 230 vdma_free(lp->tx_laddr[entry]); 231 dirty_tx++; 232 } 233 234 if (lp->tx_full 235 && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) { 236 /* The ring is no longer full, clear tbusy. */ 237 lp->tx_full = 0; 238 netif_wake_queue(dev); 239 } 240 241 lp->dirty_tx = dirty_tx; 242 } 243 244 /* 245 * check error conditions 246 */ 247 if (status & SONIC_INT_RFO) { 248 printk("%s: receive fifo underrun\n", dev->name); 249 lp->stats.rx_fifo_errors++; 250 } 251 if (status & SONIC_INT_RDE) { 252 printk("%s: receive descriptors exhausted\n", dev->name); 253 lp->stats.rx_dropped++; 254 } 255 if (status & SONIC_INT_RBE) { 256 printk("%s: receive buffer exhausted\n", dev->name); 257 lp->stats.rx_dropped++; 258 } 259 if (status & SONIC_INT_RBAE) { 260 printk("%s: receive buffer area exhausted\n", dev->name); 261 lp->stats.rx_dropped++; 262 } 263 264 /* counter overruns; all counters are 16bit wide */ 265 if (status & SONIC_INT_FAE) 266 lp->stats.rx_frame_errors += 65536; 267 if (status & SONIC_INT_CRC) 268 lp->stats.rx_crc_errors += 65536; 269 if (status & SONIC_INT_MP) 270 lp->stats.rx_missed_errors += 65536; 271 272 /* transmit error */ 273 if (status & SONIC_INT_TXER) 274 lp->stats.tx_errors++; 275 276 /* 277 * clear interrupt bits and return 278 */ 279 SONIC_WRITE(SONIC_ISR, status); 280 return IRQ_HANDLED; 281} 282 283/* 284 * We have a good packet(s), get it/them out of the buffers. 285 */ 286static void sonic_rx(struct net_device *dev) 287{ 288 unsigned int base_addr = dev->base_addr; 289 struct sonic_local *lp = (struct sonic_local *) dev->priv; 290 sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK]; 291 int status; 292 293 while (rd->in_use == 0) { 294 struct sk_buff *skb; 295 int pkt_len; 296 unsigned char *pkt_ptr; 297 298 status = rd->rx_status; 299 if (sonic_debug > 3) 300 printk("status %x, cur_rx %d, cur_rra %x\n", 301 status, lp->cur_rx, lp->cur_rra); 302 if (status & SONIC_RCR_PRX) { 303 pkt_len = rd->rx_pktlen; 304 pkt_ptr = 305 (char *) 306 sonic_chiptomem((rd->rx_pktptr_h << 16) + 307 rd->rx_pktptr_l); 308 309 if (sonic_debug > 3) 310 printk 311 ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", 312 pkt_ptr, lp->rba, rd->rx_pktptr_h, 313 rd->rx_pktptr_l, 314 SONIC_READ(SONIC_RBWC1), 315 SONIC_READ(SONIC_RBWC0)); 316 317 /* Malloc up new buffer. */ 318 skb = dev_alloc_skb(pkt_len + 2); 319 if (skb == NULL) { 320 printk 321 ("%s: Memory squeeze, dropping packet.\n", 322 dev->name); 323 lp->stats.rx_dropped++; 324 break; 325 } 326 skb->dev = dev; 327 skb_reserve(skb, 2); /* 16 byte align */ 328 skb_put(skb, pkt_len); /* Make room */ 329 eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0); 330 skb->protocol = eth_type_trans(skb, dev); 331 netif_rx(skb); /* pass the packet to upper layers */ 332 dev->last_rx = jiffies; 333 lp->stats.rx_packets++; 334 lp->stats.rx_bytes += pkt_len; 335 336 } else { 337 /* This should only happen, if we enable accepting broken packets. */ 338 lp->stats.rx_errors++; 339 if (status & SONIC_RCR_FAER) 340 lp->stats.rx_frame_errors++; 341 if (status & SONIC_RCR_CRCR) 342 lp->stats.rx_crc_errors++; 343 } 344 345 rd->in_use = 1; 346 rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK]; 347 /* now give back the buffer to the receive buffer area */ 348 if (status & SONIC_RCR_LPKT) { 349 /* 350 * this was the last packet out of the current receice buffer 351 * give the buffer back to the SONIC 352 */ 353 lp->cur_rra += sizeof(sonic_rr_t); 354 if (lp->cur_rra > 355 (lp->rra_laddr + 356 (SONIC_NUM_RRS - 357 1) * sizeof(sonic_rr_t))) lp->cur_rra = 358 lp->rra_laddr; 359 SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff); 360 } else 361 printk 362 ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", 363 dev->name); 364 } 365 /* 366 * If any worth-while packets have been received, dev_rint() 367 * has done a mark_bh(NET_BH) for us and will work on them 368 * when we get to the bottom-half routine. 369 */ 370} 371 372 373/* 374 * Get the current statistics. 375 * This may be called with the device open or closed. 376 */ 377static struct net_device_stats *sonic_get_stats(struct net_device *dev) 378{ 379 struct sonic_local *lp = (struct sonic_local *) dev->priv; 380 unsigned int base_addr = dev->base_addr; 381 382 /* read the tally counter from the SONIC and reset them */ 383 lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT); 384 SONIC_WRITE(SONIC_CRCT, 0xffff); 385 lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET); 386 SONIC_WRITE(SONIC_FAET, 0xffff); 387 lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT); 388 SONIC_WRITE(SONIC_MPT, 0xffff); 389 390 return &lp->stats; 391} 392 393 394/* 395 * Set or clear the multicast filter for this adaptor. 396 */ 397static void sonic_multicast_list(struct net_device *dev) 398{ 399 struct sonic_local *lp = (struct sonic_local *) dev->priv; 400 unsigned int base_addr = dev->base_addr; 401 unsigned int rcr; 402 struct dev_mc_list *dmi = dev->mc_list; 403 unsigned char *addr; 404 int i; 405 406 rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC); 407 rcr |= SONIC_RCR_BRD; /* accept broadcast packets */ 408 409 if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ 410 rcr |= SONIC_RCR_PRO; 411 } else { 412 if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) { 413 rcr |= SONIC_RCR_AMC; 414 } else { 415 if (sonic_debug > 2) 416 printk 417 ("sonic_multicast_list: mc_count %d\n", 418 dev->mc_count); 419 lp->cda.cam_enable = 1; /* always enable our own address */ 420 for (i = 1; i <= dev->mc_count; i++) { 421 addr = dmi->dmi_addr; 422 dmi = dmi->next; 423 lp->cda.cam_desc[i].cam_cap0 = 424 addr[1] << 8 | addr[0]; 425 lp->cda.cam_desc[i].cam_cap1 = 426 addr[3] << 8 | addr[2]; 427 lp->cda.cam_desc[i].cam_cap2 = 428 addr[5] << 8 | addr[4]; 429 lp->cda.cam_enable |= (1 << i); 430 } 431 SONIC_WRITE(SONIC_CDC, 16); 432 /* issue Load CAM command */ 433 SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff); 434 SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM); 435 } 436 } 437 438 if (sonic_debug > 2) 439 printk("sonic_multicast_list: setting RCR=%x\n", rcr); 440 441 SONIC_WRITE(SONIC_RCR, rcr); 442} 443 444 445/* 446 * Initialize the SONIC ethernet controller. 447 */ 448static int sonic_init(struct net_device *dev) 449{ 450 unsigned int base_addr = dev->base_addr; 451 unsigned int cmd; 452 struct sonic_local *lp = (struct sonic_local *) dev->priv; 453 unsigned int rra_start; 454 unsigned int rra_end; 455 int i; 456 457 /* 458 * put the Sonic into software-reset mode and 459 * disable all interrupts 460 */ 461 SONIC_WRITE(SONIC_ISR, 0x7fff); 462 SONIC_WRITE(SONIC_IMR, 0); 463 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); 464 465 /* 466 * clear software reset flag, disable receiver, clear and 467 * enable interrupts, then completely initialize the SONIC 468 */ 469 SONIC_WRITE(SONIC_CMD, 0); 470 SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS); 471 472 /* 473 * initialize the receive resource area 474 */ 475 if (sonic_debug > 2) 476 printk("sonic_init: initialize receive resource area\n"); 477 478 rra_start = lp->rra_laddr & 0xffff; 479 rra_end = 480 (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff; 481 482 for (i = 0; i < SONIC_NUM_RRS; i++) { 483 lp->rra[i].rx_bufadr_l = 484 (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff; 485 lp->rra[i].rx_bufadr_h = 486 (lp->rba_laddr + i * SONIC_RBSIZE) >> 16; 487 lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1; 488 lp->rra[i].rx_bufsize_h = 0; 489 } 490 491 /* initialize all RRA registers */ 492 SONIC_WRITE(SONIC_RSA, rra_start); 493 SONIC_WRITE(SONIC_REA, rra_end); 494 SONIC_WRITE(SONIC_RRP, rra_start); 495 SONIC_WRITE(SONIC_RWP, rra_end); 496 SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); 497 SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE - 2) >> 1); 498 499 lp->cur_rra = 500 lp->rra_laddr + (SONIC_NUM_RRS - 1) * sizeof(sonic_rr_t); 501 502 /* load the resource pointers */ 503 if (sonic_debug > 3) 504 printk("sonic_init: issueing RRRA command\n"); 505 506 SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); 507 i = 0; 508 while (i++ < 100) { 509 if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA) 510 break; 511 } 512 513 if (sonic_debug > 2) 514 printk("sonic_init: status=%x\n", SONIC_READ(SONIC_CMD)); 515 516 /* 517 * Initialize the receive descriptors so that they 518 * become a circular linked list, ie. let the last 519 * descriptor point to the first again. 520 */ 521 if (sonic_debug > 2) 522 printk("sonic_init: initialize receive descriptors\n"); 523 for (i = 0; i < SONIC_NUM_RDS; i++) { 524 lp->rda[i].rx_status = 0; 525 lp->rda[i].rx_pktlen = 0; 526 lp->rda[i].rx_pktptr_l = 0; 527 lp->rda[i].rx_pktptr_h = 0; 528 lp->rda[i].rx_seqno = 0; 529 lp->rda[i].in_use = 1; 530 lp->rda[i].link = 531 lp->rda_laddr + (i + 1) * sizeof(sonic_rd_t); 532 } 533 /* fix last descriptor */ 534 lp->rda[SONIC_NUM_RDS - 1].link = lp->rda_laddr; 535 lp->cur_rx = 0; 536 SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16); 537 SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff); 538 539 /* 540 * initialize transmit descriptors 541 */ 542 if (sonic_debug > 2) 543 printk("sonic_init: initialize transmit descriptors\n"); 544 for (i = 0; i < SONIC_NUM_TDS; i++) { 545 lp->tda[i].tx_status = 0; 546 lp->tda[i].tx_config = 0; 547 lp->tda[i].tx_pktsize = 0; 548 lp->tda[i].tx_frag_count = 0; 549 lp->tda[i].link = 550 (lp->tda_laddr + 551 (i + 1) * sizeof(sonic_td_t)) | SONIC_END_OF_LINKS; 552 } 553 lp->tda[SONIC_NUM_TDS - 1].link = 554 (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS; 555 556 SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); 557 SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); 558 lp->cur_tx = lp->dirty_tx = 0; 559 560 /* 561 * put our own address to CAM desc[0] 562 */ 563 lp->cda.cam_desc[0].cam_cap0 = 564 dev->dev_addr[1] << 8 | dev->dev_addr[0]; 565 lp->cda.cam_desc[0].cam_cap1 = 566 dev->dev_addr[3] << 8 | dev->dev_addr[2]; 567 lp->cda.cam_desc[0].cam_cap2 = 568 dev->dev_addr[5] << 8 | dev->dev_addr[4]; 569 lp->cda.cam_enable = 1; 570 571 for (i = 0; i < 16; i++) 572 lp->cda.cam_desc[i].cam_entry_pointer = i; 573 574 /* 575 * initialize CAM registers 576 */ 577 SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff); 578 SONIC_WRITE(SONIC_CDC, 16); 579 580 /* 581 * load the CAM 582 */ 583 SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM); 584 585 i = 0; 586 while (i++ < 100) { 587 if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD) 588 break; 589 } 590 if (sonic_debug > 2) { 591 printk("sonic_init: CMD=%x, ISR=%x\n", 592 SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR)); 593 } 594 595 /* 596 * enable receiver, disable loopback 597 * and enable all interrupts 598 */ 599 SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN | SONIC_CR_STP); 600 SONIC_WRITE(SONIC_RCR, SONIC_RCR_DEFAULT); 601 SONIC_WRITE(SONIC_TCR, SONIC_TCR_DEFAULT); 602 SONIC_WRITE(SONIC_ISR, 0x7fff); 603 SONIC_WRITE(SONIC_IMR, SONIC_IMR_DEFAULT); 604 605 cmd = SONIC_READ(SONIC_CMD); 606 if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) 607 printk("sonic_init: failed, status=%x\n", cmd); 608 609 if (sonic_debug > 2) 610 printk("sonic_init: new status=%x\n", 611 SONIC_READ(SONIC_CMD)); 612 613 return 0; 614} 615 616MODULE_LICENSE("GPL");