1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * DC21x4x Ethernet Driver File: dev_tulip.c 5 * 6 ********************************************************************* 7 * 8 * Copyright 2000,2001,2002,2003 9 * Broadcom Corporation. All rights reserved. 10 * 11 * This software is furnished under license and may be used and 12 * copied only in accordance with the following terms and 13 * conditions. Subject to these conditions, you may download, 14 * copy, install, use, modify and distribute modified or unmodified 15 * copies of this software in source and/or binary form. No title 16 * or ownership is transferred hereby. 17 * 18 * 1) Any source code used, modified or distributed must reproduce 19 * and retain this copyright notice and list of conditions 20 * as they appear in the source file. 21 * 22 * 2) No right is granted to use any trade name, trademark, or 23 * logo of Broadcom Corporation. The "Broadcom Corporation" 24 * name may not be used to endorse or promote products derived 25 * from this software without the prior written permission of 26 * Broadcom Corporation. 27 * 28 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 29 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 30 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 31 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 32 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 33 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 36 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 38 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 39 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 40 * THE POSSIBILITY OF SUCH DAMAGE. 41 ********************************************************************* */ 42 43#include "sbmips.h" 44 45#ifndef _SB_MAKE64 46#define _SB_MAKE64(x) ((uint64_t)(x)) 47#endif 48#ifndef _SB_MAKEMASK1 49#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n)) 50#endif 51 52#include "lib_types.h" 53#include "lib_physio.h" 54#include "lib_malloc.h" 55#include "lib_string.h" 56#define blockcopy memcpy 57#include "lib_printf.h" 58#include "lib_queue.h" 59 60#include "cfe_iocb.h" 61#include "cfe_device.h" 62#include "cfe_ioctl.h" 63#include "cfe_timer.h" 64#include "cfe_error.h" 65#include "cfe_irq.h" 66 67#include "pcivar.h" 68#include "pcireg.h" 69 70#include "dc21143.h" 71#include "mii.h" 72 73/* This is a driver for specific configurations of the DC21040, DC21041, 74 DC21140A and DC21143, not a generic Tulip driver. The prefix 75 "tulip_" is used to indicate generic Tulip functions, while 76 "dc21040_", "dc21041_", "dc21140_" or "dc21143_" indicates functions 77 specific to a chip variant. 78 79 The 21041 driver assumes a 10BT HD interface, since autonegotiation 80 is known to be broken in the early revisons of that chip. Example 81 cards come from DEC and SMC. Essentially the same driver is used 82 for 21040 cards. 83 84 The 21140 driver assumes that the PHY uses a standard MII interface 85 for both 100BT and 10BT. Example cards come from DEC (National DP83840 86 plus Twister PHY) and Netgear (Level One PHY). 87 88 Some early 21140 boards are exceptions and use SYM plus SRL 89 with different PHY chips for 10 and 100 (limited support). 90 91 The 21143 driver assumes by default that the PHY uses the SYM ("5 92 wire") interface for 100BT with pass-through for 10BT. Example 93 cards come from DEC (MicroLinear ML6694 PHY) and Znyx (QS6611 or 94 Kendin KS8761 PHY). It also supports an MII interface for 95 recognized adapters. An example card comes from Adaptec (National 96 DP83840A and Twister PHY). There is no support for AUI interfaces. 97 98 This SB1250 version takes advantage of DMA coherence and uses 99 "preserve bit lanes" addresses for all accesses that cross the 100 ZBbus-PCI bridge. */ 101 102#ifndef TULIP_DEBUG 103#define TULIP_DEBUG 0 104#endif 105 106/* Set IPOLL to drive processing through the pseudo-interrupt 107 dispatcher. Set XPOLL to drive processing by an external polling 108 agent. Setting both is ok. */ 109 110#ifndef IPOLL 111#define IPOLL 0 112#endif 113#ifndef XPOLL 114#define XPOLL 1 115#endif 116 117#define ENET_ADDR_LEN 6 /* size of an ethernet address */ 118#define MAX_ETHER_PACK 1518 /* max size of a packet */ 119#define CRC_SIZE 4 /* size of CRC field */ 120 121/* Packet buffers. For tulip, the packet must be aligned to a 32-bit 122 word boundary, and we would like it aligned to a cache line 123 boundary for performance. */ 124 125#define CACHE_ALIGN 32 126 127#if __long64 128typedef struct eth_pkt_s { 129 queue_t next; /* 16 */ 130 uint8_t *buffer; /* 8 */ 131 uint32_t flags; /* 4 */ 132 int32_t length; /* 4 */ 133 uint8_t data[MAX_ETHER_PACK]; 134} eth_pkt_t; 135#else 136typedef struct eth_pkt_s { 137 queue_t next; /* 8 */ 138 uint8_t *buffer; /* 4 */ 139 uint32_t flags; /* 4 */ 140 int32_t length; /* 4 */ 141 uint32_t unused[3]; /* 12 */ 142 uint8_t data[MAX_ETHER_PACK]; 143} eth_pkt_t; 144#endif 145 146#define ETH_PKTBUF_LINES ((sizeof(eth_pkt_t) + (CACHE_ALIGN-1))/CACHE_ALIGN) 147#define ETH_PKTBUF_SIZE (ETH_PKTBUF_LINES*CACHE_ALIGN) 148#define ETH_PKTBUF_OFFSET (offsetof(eth_pkt_t, data)) 149 150#define ETH_PKT_BASE(data) ((eth_pkt_t *)((data) - ETH_PKTBUF_OFFSET)) 151 152/* packet flags */ 153#define ETH_TX_SETUP 1 /* assumes Perfect Filtering format */ 154 155static void 156show_packet(char c, eth_pkt_t *pkt) 157{ 158 int i; 159 int n = (pkt->length < 32 ? pkt->length : 32); 160 161 xprintf("%c[%4d]:", c, pkt->length); 162 for (i = 0; i < n; i++) { 163 if (i % 4 == 0) 164 xprintf(" "); 165 xprintf("%02x", pkt->buffer[i]); 166 } 167 xprintf("\n"); 168} 169 170 171/* Descriptor structures */ 172 173typedef struct rx_dscr { 174 uint32_t rxd_flags; 175 uint32_t rxd_bufsize; 176 pci_addr_t rxd_bufaddr1; 177 pci_addr_t rxd_bufaddr2; 178} rx_dscr; 179 180typedef struct tx_dscr { 181 uint32_t txd_flags; 182 uint32_t txd_bufsize; 183 pci_addr_t txd_bufaddr1; 184 pci_addr_t txd_bufaddr2; 185} tx_dscr; 186 187/* CAM structure */ 188 189typedef union { 190 struct { 191 uint32_t physical[CAM_PERFECT_ENTRIES][3]; 192 } p; 193 struct { 194 uint32_t hash[32]; 195 uint32_t mbz[7]; 196 uint32_t physical[3]; 197 } h; 198} tulip_cam; 199 200 201/* Driver data structures */ 202 203typedef enum { 204 eth_state_uninit, 205 eth_state_setup, 206 eth_state_off, 207 eth_state_on, 208 eth_state_broken 209} eth_state_t; 210 211#define ETH_PKTPOOL_SIZE 32 212#define ETH_PKT_SIZE MAX_ETHER_PACK 213 214typedef struct tulip_softc { 215 uint32_t membase; 216 uint8_t irq; /* interrupt mapping (used if IPOLL) */ 217 pcitag_t tag; /* tag for configuration registers */ 218 219 uint8_t hwaddr[ENET_ADDR_LEN]; 220 uint16_t device; /* chip device code */ 221 uint8_t revision; /* chip revision and step (Table 3-7) */ 222 223 /* current state */ 224 eth_state_t state; 225 226 /* These fields are the chip startup values. */ 227// uint16_t media; /* media type */ 228 uint32_t opmode; /* operating mode */ 229 uint32_t intmask; /* interrupt mask */ 230 uint32_t gpdata; /* output bits for csr15 (21143) */ 231 232 /* These fields are set before calling dc21x4x_hwinit */ 233 int linkspeed; /* encodings from cfe_ioctl */ 234 int loopback; 235 236 /* Packet free list */ 237 queue_t freelist; 238 uint8_t *pktpool; 239 queue_t rxqueue; 240 241 /* The descriptor tables */ 242 uint8_t *rxdscrmem; /* receive descriptors */ 243 uint8_t *txdscrmem; /* transmit descriptors */ 244 245 /* These fields keep track of where we are in tx/rx processing */ 246 volatile rx_dscr *rxdscr_start; /* beginning of ring */ 247 volatile rx_dscr *rxdscr_end; /* end of ring */ 248 volatile rx_dscr *rxdscr_remove; /* next one we expect tulip to use */ 249 volatile rx_dscr *rxdscr_add; /* next place to put a buffer */ 250 int rxdscr_onring; 251 252 volatile tx_dscr *txdscr_start; /* beginning of ring */ 253 volatile tx_dscr *txdscr_end; /* end of ring */ 254 volatile tx_dscr *txdscr_remove; /* next one we will use for tx */ 255 volatile tx_dscr *txdscr_add; /* next place to put a buffer */ 256 257 cfe_devctx_t *devctx; 258 259 /* These fields describe the PHY */ 260 enum {SRL, MII, SYM} phy_type; 261 int mii_addr; 262 263 /* Statistics */ 264 uint32_t inpkts; 265 uint32_t outpkts; 266 uint32_t interrupts; 267 uint32_t rx_interrupts; 268 uint32_t tx_interrupts; 269 uint32_t bus_errors; 270} tulip_softc; 271 272 273/* Entry to and exit from critical sections (currently relative to 274 interrupts only, not SMP) */ 275 276#if CFG_INTERRUPTS 277#define CS_ENTER(sc) cfe_disable_irq(sc->irq) 278#define CS_EXIT(sc) cfe_enable_irq(sc->irq) 279#else 280#define CS_ENTER(sc) ((void)0) 281#define CS_EXIT(sc) ((void)0) 282#endif 283 284 285/* Driver parameterization */ 286 287#define MAXRXDSCR 32 288#define MAXTXDSCR 32 289#define MINRXRING 8 290 291#define MEDIA_UNKNOWN 0 292#define MEDIA_AUI 1 293#define MEDIA_BNC 2 294#define MEDIA_UTP_FULL_DUPLEX 3 295#define MEDIA_UTP_NO_LINK_TEST 4 296#define MEDIA_UTP 5 297 298/* Prototypes */ 299 300static void tulip_ether_probe(cfe_driver_t *drv, 301 unsigned long probe_a, unsigned long probe_b, 302 void *probe_ptr); 303 304 305/* Address mapping macros */ 306 307/* Note that PTR_TO_PHYS only works with 32-bit addresses, but then 308 so does the Tulip. */ 309#define PTR_TO_PHYS(x) (K0_TO_PHYS((uintptr_t)(x))) 310#define PHYS_TO_PTR(a) ((uint8_t *)PHYS_TO_K0(a)) 311 312/* All mappings through the PCI host bridge use match bits mode. */ 313#define PHYS_TO_PCI(a) ((uint32_t) (a) | 0x20000000) 314#define PCI_TO_PHYS(a) ((uint32_t) (a) & 0x1FFFFFFF) 315 316#define PCI_TO_PTR(a) (PHYS_TO_PTR(PCI_TO_PHYS(a))) 317#define PTR_TO_PCI(x) (PHYS_TO_PCI(PTR_TO_PHYS(x))) 318 319#define READCSR(sc,csr) phys_read32((sc)->membase + (csr)) 320#define WRITECSR(sc,csr,val) phys_write32((sc)->membase + (csr), (val)) 321 322 323#define RESET_ADAPTER(sc) \ 324 { \ 325 WRITECSR((sc), R_CSR_BUSMODE, M_CSR0_SWRESET); \ 326 cfe_sleep(CFE_HZ/10); \ 327 } 328 329 330/* Debugging */ 331 332static void 333dumpstat(tulip_softc *sc) 334{ 335 xprintf("-- CSR 5 = %08X CSR 6 = %08x\n", 336 READCSR(sc, R_CSR_STATUS), READCSR(sc, R_CSR_OPMODE)); 337} 338 339static void 340dumpcsrs(tulip_softc *sc) 341{ 342 int idx; 343 344 xprintf("-------------\n"); 345 for (idx = 0; idx < 16; idx++) { 346 xprintf("CSR %2d = %08X\n", idx, READCSR(sc, idx*8)); 347 } 348 xprintf("-------------\n"); 349} 350 351 352/* Packet management */ 353 354/* ********************************************************************* 355 * ETH_ALLOC_PKT(sc) 356 * 357 * Allocate a packet from the free list. 358 * 359 * Input parameters: 360 * sc - eth structure 361 * 362 * Return value: 363 * pointer to packet structure, or NULL if none available 364 ********************************************************************* */ 365static eth_pkt_t * 366eth_alloc_pkt(tulip_softc *sc) 367{ 368 eth_pkt_t *pkt; 369 370 CS_ENTER(sc); 371 pkt = (eth_pkt_t *) q_deqnext(&sc->freelist); 372 CS_EXIT(sc); 373 if (!pkt) return NULL; 374 375 pkt->buffer = pkt->data; 376 pkt->length = ETH_PKT_SIZE; 377 pkt->flags = 0; 378 379 return pkt; 380} 381 382 383/* ********************************************************************* 384 * ETH_FREE_PKT(sc,pkt) 385 * 386 * Return a packet to the free list 387 * 388 * Input parameters: 389 * sc - sbmac structure 390 * pkt - packet to return 391 * 392 * Return value: 393 * nothing 394 ********************************************************************* */ 395static void 396eth_free_pkt(tulip_softc *sc, eth_pkt_t *pkt) 397{ 398 CS_ENTER(sc); 399 q_enqueue(&sc->freelist, &pkt->next); 400 CS_EXIT(sc); 401} 402 403 404/* ********************************************************************* 405 * ETH_INITFREELIST(sc) 406 * 407 * Initialize the buffer free list for this mac. The memory 408 * allocated to the free list is carved up and placed on a linked 409 * list of buffers for use by the mac. 410 * 411 * Input parameters: 412 * sc - eth structure 413 * 414 * Return value: 415 * nothing 416 ********************************************************************* */ 417static void 418eth_initfreelist(tulip_softc *sc) 419{ 420 int idx; 421 uint8_t *ptr; 422 eth_pkt_t *pkt; 423 424 q_init(&sc->freelist); 425 426 ptr = sc->pktpool; 427 for (idx = 0; idx < ETH_PKTPOOL_SIZE; idx++) { 428 pkt = (eth_pkt_t *) ptr; 429 eth_free_pkt(sc, pkt); 430 ptr += ETH_PKTBUF_SIZE; 431 } 432} 433 434 435/* Utilities */ 436 437static const char * 438tulip_devname(tulip_softc *sc) 439{ 440 return (sc->devctx != NULL ? cfe_device_name(sc->devctx) : "eth?"); 441} 442 443 444/* Descriptor ring management */ 445 446static int 447tulip_add_rcvbuf(tulip_softc *sc, eth_pkt_t *pkt) 448{ 449 volatile rx_dscr *rxd; 450 volatile rx_dscr *nextrxd; 451 uint32_t ctrl = 0; 452 453 rxd = sc->rxdscr_add; 454 455 /* Figure out where the next descriptor will go */ 456 nextrxd = rxd+1; 457 if (nextrxd == sc->rxdscr_end) { 458 nextrxd = sc->rxdscr_start; 459 ctrl = M_RDES1_ENDOFRING; 460 } 461 462 /* 463 * If the next one is the same as our remove pointer, 464 * the ring is considered full. (it actually has room for 465 * one more, but we reserve the remove == add case for "empty") 466 */ 467 if (nextrxd == sc->rxdscr_remove) return -1; 468 469 rxd->rxd_bufsize = V_RDES1_BUF1SIZE(1520) | ctrl; 470 rxd->rxd_bufaddr1 = PTR_TO_PCI(pkt->buffer); 471 rxd->rxd_bufaddr2 = 0; 472 rxd->rxd_flags = M_RDES0_OWNADAP; 473 474 /* success, advance the pointer */ 475 sc->rxdscr_add = nextrxd; 476 CS_ENTER(sc); 477 sc->rxdscr_onring++; 478 CS_EXIT(sc); 479 480 return 0; 481} 482 483static void 484tulip_fillrxring(tulip_softc *sc) 485{ 486 eth_pkt_t *pkt; 487 488 while (1) { 489 CS_ENTER(sc); 490 if (sc->rxdscr_onring >= MINRXRING) { 491 CS_EXIT(sc); 492 break; 493 } 494 CS_EXIT(sc); 495 pkt = eth_alloc_pkt(sc); 496 if (pkt == NULL) { 497 /* could not allocate a buffer */ 498 break; 499 } 500 if (tulip_add_rcvbuf(sc, pkt) != 0) { 501 /* could not add buffer to ring */ 502 eth_free_pkt(sc, pkt); 503 break; 504 } 505 } 506} 507 508 509/* ********************************************************************* 510 * TULIP_RX_CALLBACK(sc, pkt) 511 * 512 * Receive callback routine. This routine is invoked when a 513 * buffer queued for receives is filled. In this simple driver, 514 * all we do is add the packet to a per-MAC queue for later 515 * processing, and try to put a new packet in the place of the one 516 * that was removed from the queue. 517 * 518 * Input parameters: 519 * sc - interface 520 * ptk - packet context (eth_pkt structure) 521 * 522 * Return value: 523 * nothing 524 ********************************************************************* */ 525static void 526tulip_rx_callback(tulip_softc *sc, eth_pkt_t *pkt) 527{ 528 if (TULIP_DEBUG) show_packet('>', pkt); /* debug */ 529 530 CS_ENTER(sc); 531 q_enqueue(&sc->rxqueue, &pkt->next); 532 CS_EXIT(sc); 533 sc->inpkts++; 534 535 tulip_fillrxring(sc); 536} 537 538 539static void 540tulip_procrxring(tulip_softc *sc) 541{ 542 volatile rx_dscr *rxd; 543 eth_pkt_t *pkt; 544 eth_pkt_t *newpkt; 545 uint32_t flags; 546 547 for (;;) { 548 rxd = (volatile rx_dscr *) sc->rxdscr_remove; 549 550 flags = rxd->rxd_flags; 551 if (flags & M_RDES0_OWNADAP) { 552 /* end of ring, no more packets */ 553 break; 554 } 555 556 pkt = ETH_PKT_BASE(PCI_TO_PTR(rxd->rxd_bufaddr1)); 557 558 /* Drop error packets */ 559 if (flags & M_RDES0_ERRORSUM) { 560 xprintf("%s: rx error %04X\n", tulip_devname(sc), flags & 0xFFFF); 561 tulip_add_rcvbuf(sc, pkt); 562 goto next; 563 } 564 565 /* Pass up the packet */ 566 pkt->length = G_RDES0_FRAMELEN(flags) - CRC_SIZE; 567 tulip_rx_callback(sc, pkt); 568 569 /* put a buffer back on the ring to replace this one */ 570 newpkt = eth_alloc_pkt(sc); 571 if (newpkt) tulip_add_rcvbuf(sc, newpkt); 572 573next: 574 /* update the pointer, accounting for buffer wrap. */ 575 rxd++; 576 if (rxd == sc->rxdscr_end) 577 rxd = sc->rxdscr_start; 578 579 sc->rxdscr_remove = (rx_dscr *) rxd; 580 CS_ENTER(sc); 581 sc->rxdscr_onring--; 582 CS_EXIT(sc); 583 } 584} 585 586 587static int 588tulip_add_txbuf(tulip_softc *sc, eth_pkt_t *pkt) 589{ 590 volatile tx_dscr *txd; 591 volatile tx_dscr *nexttxd; 592 uint32_t bufsize = 0; 593 594 txd = sc->txdscr_add; 595 596 /* Figure out where the next descriptor will go */ 597 nexttxd = (txd+1); 598 if (nexttxd == sc->txdscr_end) { 599 nexttxd = sc->txdscr_start; 600 bufsize = M_TDES1_ENDOFRING; 601 } 602 603 /* If the next one is the same as our remove pointer, 604 the ring is considered full. (it actually has room for 605 one more, but we reserve the remove == add case for "empty") */ 606 607 if (nexttxd == sc->txdscr_remove) return -1; 608 609 bufsize |= V_TDES1_BUF1SIZE(pkt->length) | 610 M_TDES1_FIRSTSEG | M_TDES1_LASTSEG | M_TDES1_INTERRUPT; 611 if (pkt->flags & ETH_TX_SETUP) { 612 /* For a setup packet, FIRSTSEG and LASTSEG should be clear (!) */ 613 bufsize ^= M_TDES1_SETUP | M_TDES1_FIRSTSEG | M_TDES1_LASTSEG; 614 } 615 txd->txd_bufsize = bufsize; 616 txd->txd_bufaddr1 = PTR_TO_PCI(pkt->buffer); 617 txd->txd_bufaddr2 = 0; 618 txd->txd_flags = M_TDES0_OWNADAP; 619 620 /* success, advance the pointer */ 621 sc->txdscr_add = nexttxd; 622 623 return 0; 624} 625 626 627static int 628tulip_transmit(tulip_softc *sc,eth_pkt_t *pkt) 629{ 630 int rv; 631 632 if (TULIP_DEBUG) show_packet('<', pkt); /* debug */ 633 634 rv = tulip_add_txbuf(sc, pkt); 635 sc->outpkts++; 636 637 WRITECSR(sc, R_CSR_TXPOLL, 1); 638 return rv; 639} 640 641 642static void 643tulip_proctxring(tulip_softc *sc) 644{ 645 volatile tx_dscr *txd; 646 eth_pkt_t *pkt; 647 uint32_t flags; 648 649 for (;;) { 650 txd = (volatile tx_dscr *) sc->txdscr_remove; 651 652 if (txd == sc->txdscr_add) { 653 /* ring is empty, no buffers to process */ 654 break; 655 } 656 657 flags = txd->txd_flags; 658 if (flags & M_TDES0_OWNADAP) { 659 /* Reached a packet still being transmitted */ 660 break; 661 } 662 663 /* Check for a completed setup packet */ 664 pkt = ETH_PKT_BASE(PCI_TO_PTR(txd->txd_bufaddr1)); 665 if (pkt->flags & ETH_TX_SETUP) { 666 if (sc->state == eth_state_setup) { 667 uint32_t opmode; 668 669 /* check flag bits */ 670 opmode = READCSR(sc, R_CSR_OPMODE); 671 opmode |= M_CSR6_RXSTART; 672 WRITECSR(sc, R_CSR_OPMODE, opmode); 673 sc->inpkts = sc->outpkts = 0; 674 sc->state = eth_state_on; 675 } 676 pkt->flags &=~ ETH_TX_SETUP; 677 } 678 679 /* Just free the packet */ 680 eth_free_pkt(sc, pkt); 681 682 /* update the pointer, accounting for buffer wrap. */ 683 txd++; 684 if (txd == sc->txdscr_end) 685 txd = sc->txdscr_start; 686 687 sc->txdscr_remove = (tx_dscr *) txd; 688 } 689} 690 691 692static void 693tulip_initrings(tulip_softc *sc) 694{ 695 volatile tx_dscr *txd; 696 volatile rx_dscr *rxd; 697 698 /* Claim ownership of all descriptors for the driver */ 699 700 for (txd = sc->txdscr_start; txd != sc->txdscr_end; txd++) 701 txd->txd_flags = 0; 702 for (rxd = sc->rxdscr_start; rxd != sc->rxdscr_end; rxd++) 703 rxd->rxd_flags = 0; 704 705 /* Init the ring pointers */ 706 707 sc->txdscr_add = sc->txdscr_remove = sc->txdscr_start; 708 sc->rxdscr_add = sc->rxdscr_remove = sc->rxdscr_start; 709 sc->rxdscr_onring = 0; 710 711 /* Add stuff to the receive ring */ 712 713 tulip_fillrxring(sc); 714} 715 716 717static int 718tulip_init(tulip_softc *sc) 719{ 720 /* Allocate descriptor rings */ 721 sc->rxdscrmem = KMALLOC(MAXRXDSCR*sizeof(rx_dscr), sizeof(rx_dscr)); 722 sc->txdscrmem = KMALLOC(MAXTXDSCR*sizeof(tx_dscr), sizeof(tx_dscr)); 723 724 /* Allocate buffer pool */ 725 sc->pktpool = KMALLOC(ETH_PKTPOOL_SIZE*ETH_PKTBUF_SIZE, CACHE_ALIGN); 726 eth_initfreelist(sc); 727 q_init(&sc->rxqueue); 728 729 /* Fill in pointers to the rings */ 730 sc->rxdscr_start = (rx_dscr *) (sc->rxdscrmem); 731 sc->rxdscr_end = sc->rxdscr_start + MAXRXDSCR; 732 sc->rxdscr_add = sc->rxdscr_start; 733 sc->rxdscr_remove = sc->rxdscr_start; 734 sc->rxdscr_onring = 0; 735 736 sc->txdscr_start = (tx_dscr *) (sc->txdscrmem); 737 sc->txdscr_end = sc->txdscr_start + MAXTXDSCR; 738 sc->txdscr_add = sc->txdscr_start; 739 sc->txdscr_remove = sc->txdscr_start; 740 741 tulip_initrings(sc); 742 743 return 0; 744} 745 746 747static void 748tulip_resetrings(tulip_softc *sc) 749{ 750 volatile tx_dscr *txd; 751 volatile rx_dscr *rxd; 752 eth_pkt_t *pkt; 753 754 /* Free already-sent descriptors and buffers */ 755 tulip_proctxring(sc); 756 757 /* Free any pending but unsent */ 758 txd = (volatile tx_dscr *) sc->txdscr_remove; 759 while (txd != sc->txdscr_add) { 760 txd->txd_flags &=~ M_TDES0_OWNADAP; 761 pkt = ETH_PKT_BASE(PCI_TO_PTR(txd->txd_bufaddr1)); 762 eth_free_pkt(sc, pkt); 763 764 txd++; 765 if (txd == sc->txdscr_end) 766 txd = sc->txdscr_start; 767 } 768 sc->txdscr_add = sc->txdscr_remove; 769 770 /* Discard any received packets as well as all free buffers */ 771 rxd = (volatile rx_dscr *) sc->rxdscr_remove; 772 while (rxd != sc->rxdscr_add) { 773 rxd->rxd_flags &=~ M_RDES0_OWNADAP; 774 pkt = ETH_PKT_BASE(PCI_TO_PTR(rxd->rxd_bufaddr1)); 775 eth_free_pkt(sc, pkt); 776 777 rxd++; 778 if (rxd == sc->rxdscr_end) 779 rxd = sc->rxdscr_start; 780 CS_ENTER(sc); 781 sc->rxdscr_onring--; 782 CS_EXIT(sc); 783 } 784 785 /* Reestablish the initial state. */ 786 tulip_initrings(sc); 787} 788 789 790/* CRCs */ 791 792#define IEEE_CRC32_POLY 0xEDB88320UL /* CRC-32 Poly -- either endian */ 793 794static uint32_t 795tulip_crc32(const uint8_t *databuf, unsigned int datalen) 796{ 797 unsigned int idx, bit, data; 798 uint32_t crc; 799 800 crc = 0xFFFFFFFFUL; 801 for (idx = 0; idx < datalen; idx++) 802 for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) 803 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? IEEE_CRC32_POLY : 0); 804 return crc; 805} 806 807#define tulip_mchash(mca) (tulip_crc32((mca), 6) & 0x1FF) 808 809 810/* Serial ROM access */ 811 812/* 813 * Delays below (nsec) are chosen to meet specs for NS93C64 (slow M variant). 814 * Current parts are faster. 815 * Reference: NS Memory Data Book, 1994 816 */ 817 818#define SROM_SIZE 128 819#define SROM_MAX_CYCLES 32 820 821#define SROM_CMD_BITS 3 822#define SROM_ADDR_BITS 6 823 824#define K_SROM_READ_CMD 06 825#define K_SROM_WRITE_CMD 05 826#define K_SROM_WEN_CMD 04 /* WEN, WDS, also WRAL, ERAL */ 827 828#define SROM_VENDOR_INDEX 0x00 829#define SROM_FORMAT_INDEX 0x12 830#define SROM_ADDR_INDEX 0x14 831 832#define SROM_DEVICE0_INDEX 0x1A 833#define SROM_LEAF0_OFFSET_INDEX 0x1B 834 835#define SROM_CRC_INDEX (SROM_SIZE-2) 836/* Note recent chips supporting wake-on-lan have CRC in bytes 94, 95 */ 837 838#define SROM_WORD(rom,offset) ((rom)[offset] | ((rom)[offset+1] << 8)) 839 840static void 841srom_idle_state(tulip_softc *sc) 842{ 843 uint32_t csr9; 844 unsigned int i; 845 846 csr9 = READCSR(sc, R_CSR_ROM_MII); 847 848 csr9 |= M_CSR9_SROMCHIPSEL; 849 WRITECSR(sc, R_CSR_ROM_MII, csr9); 850 cfe_nsleep(100); /* CS setup (Tcss=100) */ 851 852 /* Run the clock through the maximum number of pending read cycles */ 853 for (i = 0; i < SROM_MAX_CYCLES*2; i++) { 854 csr9 ^= M_CSR9_SROMCLOCK; 855 WRITECSR(sc, R_CSR_ROM_MII, csr9); 856 cfe_nsleep(1000); /* SK period (Fsk=0.5MHz) */ 857 } 858 859 /* Deassert SROM Chip Select */ 860 csr9 &=~ M_CSR9_SROMCHIPSEL; 861 WRITECSR(sc, R_CSR_ROM_MII, csr9); 862 cfe_nsleep(50); /* CS recovery (Tsks=50) */ 863} 864 865static void 866srom_write_bit(tulip_softc *sc, unsigned int data) 867{ 868 uint32_t csr9; 869 870 csr9 = READCSR(sc, R_CSR_ROM_MII); 871 872 /* Place the data bit on the bus */ 873 if (data == 1) 874 csr9 |= M_CSR9_SROMDATAIN; 875 else 876 csr9 &=~ M_CSR9_SROMDATAIN; 877 878 WRITECSR(sc, R_CSR_ROM_MII, csr9); 879 cfe_nsleep(360); /* setup: Tdis=200 */ 880 881 /* Now clock the data into the SROM */ 882 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_SROMCLOCK); 883 cfe_nsleep(900); /* clock high, Tskh=500 */ 884 WRITECSR(sc, R_CSR_ROM_MII, csr9); 885 cfe_nsleep(450); /* clock low, Tskl=250 */ 886 887 /* Now clear the data bit */ 888 csr9 &=~ M_CSR9_SROMDATAIN; /* data invalid, Tidh=20 for SK^ */ 889 WRITECSR(sc, R_CSR_ROM_MII, csr9); 890 cfe_nsleep(270); /* min cycle, 1/Fsk=2000 */ 891} 892 893static uint16_t 894srom_read_bit(tulip_softc *sc) 895{ 896 uint32_t csr9; 897 898 csr9 = READCSR(sc, R_CSR_ROM_MII); 899 900 /* Generate a clock cycle before doing a read */ 901 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_SROMCLOCK); /* rising edge */ 902 cfe_nsleep(1000); /* clock high, Tskh=500, Tpd=1000 */ 903 WRITECSR(sc, R_CSR_ROM_MII, csr9); /* falling edge */ 904 cfe_nsleep(1000); /* clock low, 1/Fsk=2000 */ 905 906 csr9 = READCSR(sc, R_CSR_ROM_MII); 907 return ((csr9 & M_CSR9_SROMDATAOUT) != 0 ? 1 : 0); 908} 909 910#define CMD_BIT_MASK (1 << (SROM_CMD_BITS+SROM_ADDR_BITS-1)) 911 912static uint16_t 913srom_read_word(tulip_softc *sc, unsigned int index) 914{ 915 uint16_t command, word; 916 uint32_t csr9; 917 unsigned int i; 918 919 csr9 = READCSR(sc, R_CSR_ROM_MII) | M_CSR9_SROMCHIPSEL; 920 921 /* Assert the SROM CS line */ 922 WRITECSR(sc, R_CSR_ROM_MII, csr9); 923 cfe_nsleep(100); /* CS setup, Tcss = 100 */ 924 925 /* Send the read command to the SROM */ 926 command = (K_SROM_READ_CMD << SROM_ADDR_BITS) | index; 927 for (i = 0; i < SROM_CMD_BITS+SROM_ADDR_BITS; i++) { 928 srom_write_bit(sc, (command & CMD_BIT_MASK) != 0 ? 1 : 0); 929 command <<= 1; 930 } 931 932 /* Now read the bits from the SROM (MSB first) */ 933 word = 0; 934 for (i = 0; i < 16; ++i) { 935 word <<= 1; 936 word |= srom_read_bit(sc); 937 } 938 939 /* Clear the SROM CS Line, CS hold, Tcsh = 0 */ 940 WRITECSR(sc, R_CSR_ROM_MII, csr9 &~ M_CSR9_SROMCHIPSEL); 941 942 return word; 943} 944 945 946/**************************************************************************** 947 * srom_calc_crc() 948 * 949 * Calculate the CRC of the SROM and return it. We compute the 950 * CRC per Appendix A of the 21140A ROM/external register data 951 * sheet (EC-QPQWA-TE). 952 ***************************************************************************/ 953 954static uint16_t 955srom_calc_crc(tulip_softc *sc, uint8_t srom[], int length) 956{ 957 uint32_t crc = tulip_crc32(srom, length) ^ 0xFFFFFFFF; 958 959 return (uint16_t)(crc & 0xFFFF); 960} 961 962/**************************************************************************** 963 * srom_read_all(sc, uint8_t dest) 964 * 965 * Read the entire SROM into the srom array 966 * 967 * Input parameters: 968 * sc - tulip state 969 ***************************************************************************/ 970 971static int 972srom_read_all(tulip_softc *sc, uint8_t dest[]) 973{ 974 int i; 975 uint16_t crc, temp; 976 977 WRITECSR(sc, R_CSR_ROM_MII, M_CSR9_SERROMSEL|M_CSR9_ROMREAD); 978 979 srom_idle_state(sc); 980 981 for (i = 0; i < SROM_SIZE/2; i++) { 982 temp = srom_read_word(sc, i); 983 dest[2*i] = temp & 0xFF; 984 dest[2*i+1] =temp >> 8; 985 } 986 987 WRITECSR(sc, R_CSR_ROM_MII, 0); /* CS hold, Tcsh=0 */ 988 989 crc = srom_calc_crc(sc, dest, SROM_CRC_INDEX); 990 if (crc != SROM_WORD(dest, SROM_CRC_INDEX)) { 991 crc = srom_calc_crc(sc, dest, 94); /* "alternative" */ 992 if (crc != SROM_WORD(dest, 94)) { 993 xprintf("%s: Invalid SROM CRC, calc %04x, stored %04x\n", 994 tulip_devname(sc), crc, SROM_WORD(dest, 94)); 995 return 0/*-1*/; 996 } 997 } 998 return 0; 999} 1000 1001static int 1002srom_read_addr(tulip_softc *sc, uint8_t buf[]) 1003{ 1004 uint8_t srom[SROM_SIZE]; 1005 1006 if (srom_read_all(sc, srom) == 0) { 1007 memcpy(buf, &srom[SROM_ADDR_INDEX], ENET_ADDR_LEN); 1008 return 0; 1009 } 1010 1011 return -1; 1012} 1013 1014 1015/**************************************************************************** 1016 * earom_read_all(sc, uint8_t dest) 1017 * 1018 * Read the entire Ethernet address ROM into the srom array (21040 only) 1019 * 1020 * Input parameters: 1021 * sc - tulip state 1022 ***************************************************************************/ 1023 1024static int 1025earom_read_all(tulip_softc *sc, uint8_t dest[]) 1026{ 1027 int i; 1028 uint32_t csr9; 1029 1030 WRITECSR(sc, R_CSR_ROM_MII, 0); /* reset pointer */ 1031 1032 for (i = 0; i < SROM_SIZE; i++) { 1033 for (;;) { 1034 csr9 = READCSR(sc, R_CSR_ROM_MII); 1035 if ((csr9 & M_CSR9_DATANOTVALID) == 0) 1036 break; 1037 POLL(); 1038 } 1039 dest[i] = G_CSR9_ROMDATA(csr9); 1040 } 1041 1042 return 0; 1043} 1044 1045static int 1046earom_read_addr(tulip_softc *sc, uint8_t buf[]) 1047{ 1048 uint8_t srom[SROM_SIZE]; 1049 1050 if (earom_read_all(sc, srom) == 0) { 1051 memcpy(buf, &srom[0], ENET_ADDR_LEN); 1052 return 0; 1053 } 1054 1055 return -1; 1056} 1057 1058 1059static int 1060rom_read_all(tulip_softc *sc, uint8_t buf[]) 1061{ 1062 if (sc->device == K_PCI_ID_DC21040) 1063 return earom_read_all(sc, buf); 1064 else 1065 return srom_read_all(sc, buf); 1066} 1067 1068static int 1069rom_read_addr(tulip_softc *sc, uint8_t buf[]) 1070{ 1071 if (sc->device == K_PCI_ID_DC21040) 1072 return earom_read_addr(sc, buf); 1073 else 1074 return srom_read_addr(sc, buf); 1075} 1076 1077#define rom_dump(srom) 1078 1079 1080/**************************************************************************** 1081 * MII access utility routines 1082 ***************************************************************************/ 1083 1084/* MII clock limited to 2.5 MHz, transactions end with MDIO tristated */ 1085 1086static void 1087mii_write_bits(tulip_softc *sc, uint32_t data, unsigned int count) 1088{ 1089 uint32_t csr9; 1090 uint32_t bitmask; 1091 1092 csr9 = READCSR(sc, R_CSR_ROM_MII) &~ (M_CSR9_MDC | M_CSR9_MIIMODE); 1093 1094 for (bitmask = 1 << (count-1); bitmask != 0; bitmask >>= 1) { 1095 csr9 &=~ M_CSR9_MDO; 1096 if ((data & bitmask) != 0) csr9 |= M_CSR9_MDO; 1097 WRITECSR(sc, R_CSR_ROM_MII, csr9); 1098 1099 cfe_nsleep(2000); /* setup */ 1100 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_MDC); 1101 cfe_nsleep(2000); /* hold */ 1102 WRITECSR(sc, R_CSR_ROM_MII, csr9); 1103 } 1104} 1105 1106static void 1107mii_turnaround(tulip_softc *sc) 1108{ 1109 uint32_t csr9; 1110 1111 csr9 = READCSR(sc, R_CSR_ROM_MII) | M_CSR9_MIIMODE; 1112 1113 /* stop driving data */ 1114 WRITECSR(sc, R_CSR_ROM_MII, csr9); 1115 cfe_nsleep(2000); /* setup */ 1116 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_MDC); 1117 cfe_nsleep(2000); /* clock high */ 1118 WRITECSR(sc, R_CSR_ROM_MII, csr9); 1119 1120 /* read back and check for 0 here? */ 1121} 1122 1123/**************************************************************************** 1124 * mii_read_register 1125 * 1126 * This routine reads a register from the PHY chip using the MII 1127 * serial management interface. 1128 * 1129 * Input parameters: 1130 * index - index of register to read (0-31) 1131 * 1132 * Return value: 1133 * word read from register 1134 ***************************************************************************/ 1135 1136static uint16_t 1137mii_read_register(tulip_softc *sc, unsigned int index) 1138{ 1139 /* Send the command and address to the PHY. The sequence is 1140 a synchronization sequence (32 1 bits) 1141 a "start" command (2 bits) 1142 a "read" command (2 bits) 1143 the PHY addr (5 bits) 1144 the register index (5 bits) 1145 */ 1146 uint32_t csr9; 1147 uint16_t word; 1148 int i; 1149 1150 mii_write_bits(sc, 0xFF, 8); 1151 mii_write_bits(sc, 0xFFFFFFFF, 32); 1152 mii_write_bits(sc, MII_COMMAND_START, 2); 1153 mii_write_bits(sc, MII_COMMAND_READ, 2); 1154 mii_write_bits(sc, sc->mii_addr, 5); 1155 mii_write_bits(sc, index, 5); 1156 1157 mii_turnaround(sc); 1158 1159 csr9 = (READCSR(sc, R_CSR_ROM_MII) &~ M_CSR9_MDC) | M_CSR9_MIIMODE; 1160 word = 0; 1161 1162 for (i = 0; i < 16; i++) { 1163 WRITECSR(sc, R_CSR_ROM_MII, csr9); 1164 cfe_nsleep(2000); /* clock width low */ 1165 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_MDC); 1166 cfe_nsleep(2000); /* clock width high */ 1167 WRITECSR(sc, R_CSR_ROM_MII, csr9); 1168 cfe_nsleep(1000); /* output delay */ 1169 word <<= 1; 1170 if ((READCSR(sc, R_CSR_ROM_MII) & M_CSR9_MDI) != 0) 1171 word |= 0x0001; 1172 } 1173 1174 return word; 1175 1176 /* reset to output mode? */ 1177} 1178 1179/**************************************************************************** 1180 * mii_write_register 1181 * 1182 * This routine writes a register in the PHY chip using the MII 1183 * serial management interface. 1184 * 1185 * Input parameters: 1186 * index - index of register to write (0-31) 1187 * value - word to write 1188 ***************************************************************************/ 1189 1190static void 1191mii_write_register(tulip_softc *sc, unsigned int index, uint16_t value) 1192{ 1193 mii_write_bits(sc, 0xFF, 8); 1194 mii_write_bits(sc, 0xFFFFFFFF, 32); 1195 mii_write_bits(sc, MII_COMMAND_START, 2); 1196 mii_write_bits(sc, MII_COMMAND_WRITE, 2); 1197 mii_write_bits(sc, sc->mii_addr, 5); 1198 mii_write_bits(sc, index, 5); 1199 mii_write_bits(sc, MII_COMMAND_ACK, 2); 1200 mii_write_bits(sc, value, 16); 1201 1202 /* reset to input mode? */ 1203} 1204 1205 1206static int 1207mii_probe(tulip_softc *sc) 1208{ 1209 int i; 1210 uint16_t id1, id2; 1211 1212 for (i = 0; i < 32; i++) { 1213 sc->mii_addr = i; 1214 id1 = mii_read_register(sc, MII_PHYIDR1); 1215 id2 = mii_read_register(sc, MII_PHYIDR2); 1216 if ((id1 != 0x0000 && id1 != 0xFFFF) || 1217 (id2 != 0x0000 && id2 != 0xFFFF)) { 1218 return 0; 1219 } 1220 } 1221 return -1; 1222} 1223 1224#define mii_dump(sc,label) 1225 1226 1227/* The following functions are suitable for all tulips with MII 1228 interfaces. */ 1229 1230static void 1231mii_set_speed(tulip_softc *sc, int speed, int autoneg) 1232{ 1233 uint16_t control; 1234 uint16_t pcr; 1235 uint32_t opmode = 0; 1236 1237 /* This is really just for NS DP83840/A. Needed? */ 1238 pcr = mii_read_register(sc, 0x17); 1239 pcr |= (0x400|0x100|0x40|0x20); 1240 mii_write_register(sc, 0x17, pcr); 1241 1242 control = mii_read_register(sc, MII_BMCR); 1243 1244 if (!autoneg) { 1245 control &=~ (BMCR_ANENABLE | BMCR_RESTARTAN); 1246 mii_write_register(sc, MII_BMCR, control); 1247 control &=~ (BMCR_SPEED0 | BMCR_SPEED1 | BMCR_DUPLEX); 1248 } 1249 1250 switch (speed) { 1251 case ETHER_SPEED_10HDX: 1252 default: 1253 opmode = M_CSR6_SPEED_10_MII; 1254 break; 1255 case ETHER_SPEED_10FDX: 1256 control |= BMCR_DUPLEX; 1257 opmode = M_CSR6_SPEED_10_MII | M_CSR6_FULLDUPLEX; 1258 break; 1259 case ETHER_SPEED_100HDX: 1260 control |= BMCR_SPEED100; 1261 opmode = M_CSR6_SPEED_100_MII; 1262 break; 1263 case ETHER_SPEED_100FDX: 1264 control |= BMCR_SPEED100 | BMCR_DUPLEX ; 1265 opmode = M_CSR6_SPEED_100_MII | M_CSR6_FULLDUPLEX; 1266 break; 1267 } 1268 1269 if (!autoneg) 1270 mii_write_register(sc, MII_BMCR, control); 1271 1272 opmode |= M_CSR6_MBO; 1273 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72); 1274 WRITECSR(sc, R_CSR_OPMODE, opmode); 1275 mii_dump(sc, "setspeed PHY"); 1276} 1277 1278static void 1279mii_autonegotiate(tulip_softc *sc) 1280{ 1281 uint16_t control, status, cap; 1282 unsigned int timeout; 1283 int linkspeed; 1284 int autoneg; 1285 1286 linkspeed = ETHER_SPEED_UNKNOWN; 1287 1288 /* Read twice to clear latching bits */ 1289 status = mii_read_register(sc, MII_BMSR); 1290 status = mii_read_register(sc, MII_BMSR); 1291 mii_dump(sc, "query PHY"); 1292 1293 if ((status & (BMSR_AUTONEG | BMSR_LINKSTAT)) == 1294 (BMSR_AUTONEG | BMSR_LINKSTAT)) 1295 control = mii_read_register(sc, MII_BMCR); 1296 else { 1297 /* reset the PHY */ 1298 mii_write_register(sc, MII_BMCR, BMCR_RESET); 1299 timeout = 3000; 1300 for (;;) { 1301 control = mii_read_register(sc, MII_BMCR); 1302 if ((control && BMCR_RESET) == 0) break; 1303 cfe_sleep(CFE_HZ/2); 1304 timeout -= 500; 1305 if (timeout <= 0) break; 1306 } 1307 if ((control & BMCR_RESET) != 0) { 1308 xprintf("%s: PHY reset failed\n", tulip_devname(sc)); 1309 return; 1310 } 1311 1312 status = mii_read_register(sc, MII_BMSR); 1313 cap = ((status >> 6) & (ANAR_TXFD | ANAR_TXHD | ANAR_10FD | ANAR_10HD)) 1314 | PSB_802_3; 1315 mii_write_register(sc, MII_ANAR, cap); 1316 control |= (BMCR_ANENABLE | BMCR_RESTARTAN); 1317 mii_write_register(sc, MII_BMCR, control); 1318 1319 timeout = 3000; 1320 for (;;) { 1321 status = mii_read_register(sc, MII_BMSR); 1322 if ((status & BMSR_ANCOMPLETE) != 0) break; 1323 cfe_sleep(CFE_HZ/2); 1324 timeout -= 500; 1325 if (timeout <= 0) break; 1326 } 1327 mii_dump(sc, "done PHY"); 1328 } 1329 1330 xprintf("%s: Link speed: ", tulip_devname(sc)); 1331 if ((status & BMSR_ANCOMPLETE) != 0) { 1332 /* A link partner was negogiated... */ 1333 1334 uint16_t remote = mii_read_register(sc, MII_ANLPAR); 1335 1336 autoneg = 1; 1337 if ((remote & ANLPAR_TXFD) != 0) { 1338 xprintf("100BaseT FDX"); 1339 linkspeed = ETHER_SPEED_100FDX; 1340 } 1341 else if ((remote & ANLPAR_TXHD) != 0) { 1342 xprintf("100BaseT HDX"); 1343 linkspeed = ETHER_SPEED_100HDX; 1344 } 1345 else if ((remote & ANLPAR_10FD) != 0) { 1346 xprintf("10BaseT FDX"); 1347 linkspeed = ETHER_SPEED_10FDX; 1348 } 1349 else if ((remote & ANLPAR_10HD) != 0) { 1350 xprintf("10BaseT HDX"); 1351 linkspeed = ETHER_SPEED_10HDX; 1352 } 1353 xprintf("\n"); 1354 } 1355 else { 1356 /* no link partner negotiation */ 1357 1358 autoneg = 0; 1359 xprintf("Unknown, assuming 10BaseT\n"); 1360 control &=~ (BMCR_ANENABLE | BMCR_RESTARTAN); 1361 mii_write_register(sc, MII_BMCR, control); 1362 linkspeed = ETHER_SPEED_10HDX; 1363 } 1364 1365 if ((status & BMSR_LINKSTAT) == 0) 1366 mii_write_register(sc, MII_BMCR, control); 1367 mii_set_speed(sc, linkspeed, autoneg); 1368 1369 status = mii_read_register(sc, MII_BMSR); /* clear latching bits */ 1370 mii_dump(sc, "final PHY"); 1371} 1372 1373 1374/* Chip specific code */ 1375 1376static void 1377dc21143_set_speed(tulip_softc *sc, int speed) 1378{ 1379 uint32_t opmode = 0; 1380 1381 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1382 1383 switch (speed) { 1384 case ETHER_SPEED_AUTO: 1385 break; 1386 case ETHER_SPEED_10HDX: 1387 default: 1388 WRITECSR(sc, R_CSR_SIAMODE1, M_CSR14_10BT_HD); 1389 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata); 1390 opmode = M_CSR6_SPEED_10; 1391 break; 1392 case ETHER_SPEED_10FDX: 1393 WRITECSR(sc, R_CSR_SIAMODE1, M_CSR14_10BT_FD); 1394 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata); 1395 opmode = M_CSR6_SPEED_10 | M_CSR6_FULLDUPLEX; 1396 break; 1397 case ETHER_SPEED_100HDX: 1398 WRITECSR(sc, R_CSR_SIAMODE1, 0); 1399 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata); 1400 opmode = M_CSR6_SPEED_100; 1401 break; 1402 case ETHER_SPEED_100FDX: 1403 WRITECSR(sc, R_CSR_SIAMODE1, 0); 1404 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata); 1405 opmode = M_CSR6_SPEED_100 | M_CSR6_FULLDUPLEX; 1406 break; 1407 } 1408 1409 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET); 1410 1411 opmode |= M_CSR6_MBO; 1412 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72); 1413 WRITECSR(sc, R_CSR_OPMODE, opmode); 1414} 1415 1416static void 1417dc21143_autonegotiate(tulip_softc *sc) 1418{ 1419 uint32_t opmode; 1420 uint32_t tempword; 1421 int count; 1422 int linkspeed; 1423 1424 linkspeed = ETHER_SPEED_UNKNOWN; 1425 1426 /* Program the media setup into the CSRs. */ 1427 /* reset SIA */ 1428 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1429 1430 /* set to speed_10, fullduplex to start_nway */ 1431 opmode = 1432 M_CSR6_SPEED_10 | 1433 M_CSR6_FULLDUPLEX | 1434 M_CSR6_MBO; 1435 WRITECSR(sc, R_CSR_OPMODE, opmode); 1436 1437 /* Choose advertised capabilities */ 1438 tempword = 1439 M_CSR14_100BASETHALFDUP | 1440 M_CSR14_100BASETFULLDUP | 1441 M_CSR14_HALFDUPLEX10BASET; 1442 WRITECSR(sc, R_CSR_SIAMODE1, tempword); 1443 1444 /* Enable autonegotiation */ 1445 tempword |= M_CSR14_AUTONEGOTIATE | 0xFFFF; 1446 WRITECSR(sc, R_CSR_SIAMODE1, tempword); 1447 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata); 1448 WRITECSR(sc, R_CSR_OPMODE, opmode); 1449 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET); 1450 1451 /* STATE check nway, poll until a valid 10/100mbs signal seen */ 1452 WRITECSR(sc, R_CSR_STATUS, M_CSR5_LINKPASS); /* try to clear this... */ 1453 1454 /* (Re)start negotiation */ 1455 tempword = READCSR(sc, R_CSR_SIASTATUS); 1456 tempword &=~ M_CSR12_AUTONEGARBIT; 1457 tempword |= V_CSR12_AUTONEGARBIT(0x1); 1458 1459 for (count = 0; count <= 13; count++) { 1460 tempword = READCSR(sc, R_CSR_STATUS); 1461 if (tempword & M_CSR5_LINKPASS) 1462 break; 1463 cfe_sleep(CFE_HZ/10); 1464 } 1465 1466 if (count > 13) 1467 xprintf("%s: Link autonegotiation failed\n", tulip_devname(sc)); 1468 1469 /* STATE configure nway, check to see if any abilities common to us. 1470 If they do, set to highest mode, if not, we will see if the partner 1471 will do 100mb or 10mb - then set it */ 1472 1473 tempword = READCSR(sc, R_CSR_SIASTATUS); 1474 /* clear the autonegogiate complete bit */ 1475 WRITECSR(sc, R_CSR_STATUS, M_CSR5_LINKPASS); 1476 1477 if (tempword & M_CSR12_LINKPARTNEG) { 1478 /* A link partner was negogiated... */ 1479 1480 xprintf("%s: Link speed: ", tulip_devname(sc)); 1481 if (tempword & 0x01000000) { /* 100FD */ 1482 xprintf("100BaseT FDX"); 1483 linkspeed = ETHER_SPEED_100FDX; 1484 } 1485 else if (tempword & 0x00800000) { /* 100HD */ 1486 xprintf("100BaseT HDX"); 1487 linkspeed = ETHER_SPEED_100HDX; 1488 } 1489 else if (tempword & 0x00400000) { /* 10FD */ 1490 xprintf("10BaseT FDX"); 1491 linkspeed = ETHER_SPEED_10FDX; 1492 } 1493 else if (tempword & 0x00200000) { /* 10HD */ 1494 xprintf("10BaseT HDX"); 1495 linkspeed = ETHER_SPEED_10HDX; 1496 } 1497 xprintf("\n"); 1498 } 1499 else { 1500 /* no link partner negotiation */ 1501 /* disable link for 1.3 seconds to break any existing connections */ 1502 1503 xprintf("%s: ", tulip_devname(sc)); 1504 dc21143_set_speed(sc, ETHER_SPEED_10HDX); 1505 cfe_sleep(CFE_HZ/8); 1506 1507 tempword = READCSR(sc, R_CSR_SIASTATUS); 1508 1509 if ((tempword & 0x02) == 0) { 1510 /* 100 mb signal present set to 100mb */ 1511 xprintf("No link partner... setting to 100BaseT HDX\n"); 1512 linkspeed = ETHER_SPEED_100HDX; 1513 } 1514 else if ((tempword & 0x04) == 0) { 1515 /* 10 mb signal present */ 1516 xprintf("No link partner... setting to 10BaseT HDX\n"); 1517 linkspeed = ETHER_SPEED_10HDX; 1518 } 1519 else { 1520 /* couldn't determine line speed, so set to 10mbs */ 1521 xprintf("Unknown; defaulting to 10BaseT HDX\n"); 1522 linkspeed = ETHER_SPEED_10HDX; 1523 } 1524 } 1525 1526 dc21143_set_speed(sc, linkspeed); 1527} 1528 1529static void 1530dc21143_set_loopback(tulip_softc *sc, int mode) 1531{ 1532 uint32_t v; 1533 1534 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1535 if (mode == ETHER_LOOPBACK_EXT) { 1536 /* deal with CSRs 13-15 */ 1537 } 1538 cfe_sleep(CFE_HZ/10); /* check this */ 1539 1540 /* Update the SIA registers */ 1541 v = READCSR(sc, R_CSR_SIAMODE0); 1542 WRITECSR(sc, R_CSR_SIAMODE0, v &~ 0xFFFF); 1543 v = READCSR(sc, R_CSR_SIAMODE1); 1544 WRITECSR(sc, R_CSR_SIAMODE1, v &~ 0xFFFF); 1545 v = READCSR(sc, R_CSR_SIAMODE2); 1546 WRITECSR(sc, R_CSR_SIAMODE2, v | 0xC000); /* WC of HCKR, RMP */ 1547 if (mode == ETHER_LOOPBACK_OFF) 1548 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata); 1549 else 1550 WRITECSR(sc, R_CSR_SIAMODE2, (v &~ 0xFFFF) | M_CSR15_GP_AUIBNC); 1551 1552 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET); 1553 1554 sc->loopback = mode; 1555} 1556 1557/* Known vendors with cards requiring special initialization. */ 1558#define K_PCI_VENDOR_COGENT 0x1109 /* inherited by Adaptec */ 1559#define K_PCI_VENDOR_PHOBOS 0x13D8 1560#define K_PCI_VENDOR_ZNYZ 0x110D 1561#define K_PCI_VENDOR_KINGSTON 0x2646 1562 1563static void 1564dc21143_hwinit(tulip_softc *sc, uint8_t srom[]) 1565{ 1566 uint32_t v; 1567 uint32_t csr6word, csr14word; 1568 1569 if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_COGENT) { 1570 /* Cogent/Adaptec MII (ANA-6911A). */ 1571 sc->phy_type = MII; 1572 WRITECSR(sc, R_CSR_SIAMODE2, 0x0821 << 16); 1573 WRITECSR(sc, R_CSR_SIAMODE2, 0x0001 << 16); 1574 cfe_sleep(CFE_HZ/10); 1575 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000 << 16); 1576 cfe_sleep(CFE_HZ/2); 1577 sc->gpdata = 0; 1578 } 1579 else if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_ZNYZ) { 1580 /* Znyz 34xQ adapters */ 1581 sc->phy_type = SYM; 1582 1583 /* The ZX345Q with wake-on-LAN enabled apparently clears ANE and 1584 TAS on power up (but not cold reset) */ 1585 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFFFFFF); 1586 1587 WRITECSR(sc, R_CSR_SIAMODE2, 1588 M_CSR15_GP_CONTROLWRITE | 1589 0xF0000 | /* all outputs */ 1590 M_CSR15_GP_LED1 | 1591 M_CSR15_GP_AUIBNC); 1592 cfe_sleep(CFE_HZ/5); 1593 WRITECSR(sc, R_CSR_SIAMODE2, 0x40000); /* release reset */ 1594 cfe_sleep(CFE_HZ/5); 1595 sc->gpdata = 0x40000 | M_CSR15_GP_AUIBNC; 1596 } 1597 else if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_KINGSTON) { 1598 /* Kingston KNE100TX */ 1599 sc->phy_type = MII; 1600 sc->gpdata = 0; 1601 } 1602 else if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_PHOBOS) { 1603 /* Phobos 430TX quad card */ 1604 sc->phy_type = MII; 1605 WRITECSR(sc, R_CSR_SIAMODE2, 0x0821 << 16); 1606 WRITECSR(sc, R_CSR_SIAMODE2, 0x0001 << 16); 1607 cfe_sleep(CFE_HZ/10); 1608 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000 << 16); 1609 cfe_sleep(CFE_HZ/2); 1610 sc->gpdata = 0; 1611 } 1612 else { 1613 /* Most 21143 cards use the SYM interface. */ 1614 sc->phy_type = SYM; 1615 WRITECSR(sc, R_CSR_SIAMODE2, M_CSR15_CONFIG_GEPS_LEDS); 1616 sc->gpdata = M_CSR15_DEFAULT_VALUE; 1617 } 1618 1619 if (sc->phy_type == MII) { 1620 mii_probe(sc); 1621 } 1622 1623 /* CSR0 - bus mode */ 1624 v = V_CSR0_SKIPLEN(0) | 1625 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) | 1626 M_CSR0_READMULTENAB | M_CSR0_READLINEENAB | 1627 M_CSR0_WRITEINVALENAB | 1628 V_CSR0_BURSTLEN(K_CSR0_BURSTANY); 1629#ifdef __MIPSEB 1630 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */ 1631#endif 1632 WRITECSR(sc, R_CSR_BUSMODE, v); 1633 1634 /* CSR6 - operation mode */ 1635 v = M_CSR6_PORTSEL | 1636 V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72) | 1637 M_CSR6_MBO; 1638 if (sc->phy_type == SYM) 1639 v |= M_CSR6_PCSFUNC |M_CSR6_SCRAMMODE; 1640 WRITECSR(sc, R_CSR_OPMODE, v); 1641 1642 /* About to muck with the SIA, reset it.(?) */ 1643 /* WRITECSR(sc, R_CSR_SIASTATUS, 0); */ 1644 1645 /* Must shut off all transmit/receive in order to attempt to 1646 achieve Full Duplex */ 1647 csr6word = READCSR(sc, R_CSR_OPMODE); 1648 WRITECSR(sc, R_CSR_OPMODE, csr6word &~ (M_CSR6_TXSTART | M_CSR6_RXSTART)); 1649 csr6word = READCSR(sc, R_CSR_OPMODE); 1650 1651 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start)); 1652 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start)); 1653 1654 if (sc->phy_type == MII) { 1655 if (sc->linkspeed == ETHER_SPEED_AUTO) 1656 mii_autonegotiate(sc); 1657 else 1658 mii_set_speed(sc, sc->linkspeed, 0); 1659 } 1660 else { 1661 if (sc->linkspeed == ETHER_SPEED_AUTO) { 1662 dc21143_autonegotiate(sc); 1663 } 1664 else { 1665 /* disable autonegotiate so we can set full duplex to on */ 1666 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1667 csr14word = READCSR(sc, R_CSR_SIAMODE1); 1668 csr14word &=~ M_CSR14_AUTONEGOTIATE; 1669 WRITECSR(sc, R_CSR_SIAMODE1, csr14word); 1670 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET); 1671 1672 dc21143_set_speed(sc, sc->linkspeed); 1673 } 1674 } 1675} 1676 1677 1678static void 1679dc21140_set_speed(tulip_softc *sc, int speed, int autoneg) 1680{ 1681 mii_set_speed(sc, speed, autoneg); 1682} 1683 1684static void 1685dc21140_set_loopback(tulip_softc *sc, int mode) 1686{ 1687 if (mode == ETHER_LOOPBACK_EXT) { 1688 xprintf("%s: external loopback mode NYI\n", tulip_devname(sc)); 1689 mode = ETHER_LOOPBACK_OFF; 1690 } 1691 else if (mode != ETHER_LOOPBACK_INT) 1692 mode = ETHER_LOOPBACK_OFF; 1693 1694 sc->loopback = mode; 1695} 1696 1697static void 1698dc21140_hwinit(tulip_softc *sc, uint8_t srom[]) 1699{ 1700 uint16_t leaf; 1701 uint8_t gpr_control, gpr_data; 1702 uint32_t v; 1703 uint32_t opmode; 1704 1705 if (srom[SROM_FORMAT_INDEX] == 0 || srom[SROM_FORMAT_INDEX] > 4) { 1706 gpr_control = 0x1F; 1707 gpr_data = 0x00; 1708 sc->phy_type = MII; /* Most 21140 cards use MII */ 1709 } 1710 else if (srom[SROM_ADDR_INDEX+0] == 0x00 && srom[SROM_ADDR_INDEX+1] == 0xC0 1711 && srom[SROM_ADDR_INDEX+2] == 0x95) { 1712 /* Znyx 34x apparently has non-standard leaf info. */ 1713 gpr_control = 0x00; /* All inputs, per Znyx docs */ 1714 gpr_data = 0x00; 1715 sc->phy_type = MII; 1716 } 1717 else { 1718 leaf = SROM_WORD(srom, SROM_LEAF0_OFFSET_INDEX); 1719 gpr_control = srom[leaf+2]; 1720 if ((srom[leaf+4] & 0x80) == 0) { 1721 gpr_data = 0x85; /* SYM, 100 Mb/s */ 1722 sc->phy_type = SYM; 1723 } 1724 else { 1725 gpr_data = 0x00; /* MII */ 1726 sc->phy_type = MII; 1727 } 1728 } 1729 1730 /* Assume that we will use MII or SYM interface */ 1731 WRITECSR(sc, R_CSR_OPMODE, M_CSR6_PORTSEL); 1732 RESET_ADAPTER(sc); 1733 1734 WRITECSR(sc, R_CSR_GENPORT, M_CSR12_CONTROL | gpr_control); 1735 cfe_nsleep(100); /* CS setup (Tcss=100) */ 1736 WRITECSR(sc, R_CSR_GENPORT, gpr_data); /* setup PHY */ 1737 1738 if (sc->phy_type == MII) { 1739 mii_probe(sc); 1740 } 1741 1742 /* CSR0 - bus mode */ 1743 v = V_CSR0_SKIPLEN(0) | 1744 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) | 1745 M_CSR0_READMULTENAB | M_CSR0_READLINEENAB | 1746 M_CSR0_WRITEINVALENAB | 1747 V_CSR0_BURSTLEN(K_CSR0_BURSTANY); 1748#ifdef __MIPSEB 1749 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */ 1750#endif 1751 WRITECSR(sc, R_CSR_BUSMODE, v); 1752 1753 /* CSR6 - operation mode */ 1754 v = M_CSR6_PORTSEL | 1755 V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72) | 1756 M_CSR6_MBO; 1757 WRITECSR(sc, R_CSR_OPMODE, v); 1758 1759 /* Must shut off all transmit/receive in order to attempt to 1760 achieve Full Duplex */ 1761 opmode = READCSR(sc, R_CSR_OPMODE); 1762 WRITECSR(sc, R_CSR_OPMODE, opmode &~ (M_CSR6_TXSTART | M_CSR6_RXSTART)); 1763 opmode = READCSR(sc, R_CSR_OPMODE); 1764 1765 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start)); 1766 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start)); 1767 1768 if (sc->phy_type == MII) { 1769 if (sc->linkspeed == ETHER_SPEED_AUTO) 1770 mii_autonegotiate(sc); 1771 else 1772 mii_set_speed(sc, sc->linkspeed, 0); 1773 } 1774 else { 1775 switch (sc->linkspeed) { 1776 default: 1777 sc->linkspeed = ETHER_SPEED_100HDX; /* for now */ 1778 /* fall through */ 1779 case ETHER_SPEED_100HDX: 1780 opmode |= M_CSR6_SPEED_100; 1781 break; 1782 case ETHER_SPEED_100FDX: 1783 opmode |= M_CSR6_SPEED_100 | M_CSR6_FULLDUPLEX; 1784 break; 1785 } 1786 1787 WRITECSR(sc, R_CSR_OPMODE, opmode); 1788 } 1789} 1790 1791 1792static void 1793dc21041_set_speed(tulip_softc *sc, int speed) 1794{ 1795 uint32_t opmode = 0; 1796 1797 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1798 1799 /* For now, always force 10BT, HDX (21041, Table 3-62) */ 1800 switch (speed) { 1801 case ETHER_SPEED_10HDX: 1802 default: 1803 WRITECSR(sc, R_CSR_SIAMODE1, 0x7F3F); 1804 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008); 1805 opmode = M_CSR6_SPEED_10; 1806 break; 1807 } 1808 1809 WRITECSR(sc, R_CSR_SIAMODE0, 0xEF00 | M_CSR13_CONN_NOT_RESET); 1810 cfe_sleep(CFE_HZ/10); 1811 1812 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72); 1813 WRITECSR(sc, R_CSR_OPMODE, opmode); 1814} 1815 1816static void 1817dc21041_set_loopback(tulip_softc *sc, int mode) 1818{ 1819 /* For now, always assume 10BT */ 1820 uint32_t mode0; 1821 1822 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1823 cfe_sleep(CFE_HZ/10); /* check this */ 1824 1825 /* Update the SIA registers */ 1826 if (mode == ETHER_LOOPBACK_EXT) { 1827 /* NB: this is really just internal but through the 10BT endec */ 1828 WRITECSR(sc, R_CSR_SIAMODE1, 0x7A3F); 1829 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008); 1830 mode0 = 0; 1831 } 1832 else if (mode == ETHER_LOOPBACK_INT) { 1833 /* MAC internal loopback, no SIA */ 1834 WRITECSR(sc, R_CSR_SIAMODE1, 0x0000); 1835 WRITECSR(sc, R_CSR_SIAMODE2, 0x000E); 1836 mode0 = M_CSR13_CONN_AUI_10BT; 1837 } 1838 else { 1839 mode = ETHER_LOOPBACK_OFF; 1840 WRITECSR(sc, R_CSR_SIAMODE1, 0x7F3F); 1841 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008); 1842 mode0 = 0; 1843 } 1844 1845 WRITECSR(sc, R_CSR_SIAMODE0, 0xEF00 | mode0 | M_CSR13_CONN_NOT_RESET ); 1846 1847 sc->loopback = mode; 1848} 1849 1850static void 1851dc21041_hwinit(tulip_softc *sc, uint8_t srom[]) 1852{ 1853 uint32_t v; 1854 1855 sc->phy_type = SRL; 1856 1857 /* CSR0 - bus mode */ 1858 v = V_CSR0_SKIPLEN(0) | 1859 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) | 1860 V_CSR0_BURSTLEN(K_CSR0_BURSTANY); 1861#ifdef __MIPSEB 1862 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */ 1863#endif 1864 WRITECSR(sc, R_CSR_BUSMODE, v); 1865 1866 WRITECSR(sc, R_CSR_INTMASK, 0); 1867 1868 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start)); 1869 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start)); 1870 1871 /* For now, always force 10BT, HDX (21041, Table 3-62) */ 1872 dc21041_set_speed(sc, ETHER_SPEED_10HDX); 1873} 1874 1875 1876static void 1877dc21040_set_speed(tulip_softc *sc, int speed) 1878{ 1879 uint32_t opmode = 0; 1880 1881 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1882 1883 /* For now, force 10BT, HDX unless FDX requested (21040, Table 3-53) */ 1884 switch (speed) { 1885 case ETHER_SPEED_10HDX: 1886 default: 1887 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFF); 1888 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000); 1889 opmode = 0; 1890 break; 1891 case ETHER_SPEED_10FDX: 1892 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFD); 1893 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000); 1894 opmode = M_CSR6_FULLDUPLEX; 1895 break; 1896 } 1897 1898 WRITECSR(sc, R_CSR_SIAMODE0, 0xEF00 | M_CSR13_CONN_NOT_RESET); 1899 cfe_sleep(CFE_HZ/10); 1900 1901 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72); 1902 WRITECSR(sc, R_CSR_OPMODE, opmode); 1903} 1904 1905static void 1906dc21040_set_loopback(tulip_softc *sc, int mode) 1907{ 1908 WRITECSR(sc, R_CSR_SIAMODE0, 0); 1909 cfe_sleep(CFE_HZ/10); /* check this */ 1910 1911 /* Update the SIA registers */ 1912 if (mode == ETHER_LOOPBACK_EXT) { 1913 /* NB: this is on-chip loopback through the 10BT endec */ 1914 WRITECSR(sc, R_CSR_SIAMODE1, 0xFEFB); 1915 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008); 1916 } 1917 else if (mode == ETHER_LOOPBACK_INT) { 1918 /* MAC internal loopback, no SIA */ 1919 WRITECSR(sc, R_CSR_SIAMODE1, 0x0000); 1920 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000); 1921 } 1922 else { 1923 mode = ETHER_LOOPBACK_OFF; 1924 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFF); 1925 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000); 1926 } 1927 1928 WRITECSR(sc, R_CSR_SIAMODE0, 0x8F00 | M_CSR13_CONN_NOT_RESET ); 1929 1930 sc->loopback = mode; 1931} 1932 1933static void 1934dc21040_hwinit(tulip_softc *sc, uint8_t srom[]) 1935{ 1936 uint32_t v; 1937 1938 sc->phy_type = SRL; 1939 1940 /* CSR0 - bus mode */ 1941 v = V_CSR0_SKIPLEN(0) | 1942 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) | 1943 V_CSR0_BURSTLEN(K_CSR0_BURST32); 1944#ifdef __MIPSEB 1945 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */ 1946#endif 1947 WRITECSR(sc, R_CSR_BUSMODE, v); 1948 1949 WRITECSR(sc, R_CSR_INTMASK, 0); 1950 1951 dc21040_set_speed(sc, sc->linkspeed); 1952} 1953 1954 1955static void 1956tulip_hwinit(tulip_softc *sc) 1957{ 1958 if (sc->state == eth_state_uninit) { 1959 uint8_t srom[SROM_SIZE]; 1960 1961 /* Wake-on-LAN apparently powers up with PORTSEL = 1 */ 1962 WRITECSR(sc, R_CSR_OPMODE, 1963 READCSR(sc, R_CSR_OPMODE) &~ M_CSR6_PORTSEL); 1964 1965 RESET_ADAPTER(sc); 1966 sc->state = eth_state_off; 1967 sc->bus_errors = 0; 1968 1969 rom_read_all(sc, srom); 1970 rom_dump(srom); 1971 1972 switch (sc->device) { 1973 case K_PCI_ID_DC21040: 1974 dc21040_hwinit(sc, srom); 1975 break; 1976 case K_PCI_ID_DC21041: 1977 dc21041_hwinit(sc, srom); 1978 break; 1979 case K_PCI_ID_DC21140: 1980 dc21140_hwinit(sc, srom); 1981 break; 1982 case K_PCI_ID_DC21143: 1983 dc21143_hwinit(sc, srom); 1984 break; 1985 default: 1986 break; 1987 } 1988 } 1989} 1990 1991static void 1992tulip_setaddr(tulip_softc *sc) 1993{ 1994 int idx; 1995 tulip_cam *cam; 1996 eth_pkt_t *pkt; 1997 1998 pkt = eth_alloc_pkt(sc); 1999 if (pkt) { 2000 pkt->length = CAM_SETUP_BUFFER_SIZE; 2001 cam = (tulip_cam *) pkt->buffer; 2002 2003#ifdef __MIPSEB 2004 cam->p.physical[0][0] = (((uint32_t) sc->hwaddr[0] << 8) | 2005 (uint32_t) sc->hwaddr[1]) << 16; 2006 cam->p.physical[0][1] = (((uint32_t) sc->hwaddr[2] << 8) | 2007 (uint32_t) sc->hwaddr[3]) << 16; 2008 cam->p.physical[0][2] = (((uint32_t) sc->hwaddr[4] << 8) | 2009 (uint32_t) sc->hwaddr[5]) << 16; 2010 for (idx = 1; idx < CAM_PERFECT_ENTRIES; idx++) { 2011 cam->p.physical[idx][0] = 0xFFFF0000; 2012 cam->p.physical[idx][1] = 0xFFFF0000; 2013 cam->p.physical[idx][2] = 0xFFFF0000; 2014 } 2015#else 2016 cam->p.physical[0][0] = ((uint32_t) sc->hwaddr[0]) | 2017 (((uint32_t) sc->hwaddr[1]) << 8); 2018 cam->p.physical[0][1] = ((uint32_t) sc->hwaddr[2]) | 2019 (((uint32_t) sc->hwaddr[3]) << 8); 2020 cam->p.physical[0][2] = ((uint32_t) sc->hwaddr[4]) | 2021 (((uint32_t) sc->hwaddr[5]) << 8); 2022 for (idx = 1; idx < CAM_PERFECT_ENTRIES; idx++) { 2023 cam->p.physical[idx][0] = 0x0000FFFF; 2024 cam->p.physical[idx][1] = 0x0000FFFF; 2025 cam->p.physical[idx][2] = 0x0000FFFF; 2026 } 2027#endif 2028 2029 pkt->flags |= ETH_TX_SETUP; 2030 sc->state = eth_state_setup; 2031 if (tulip_transmit(sc, pkt) != 0) { 2032 xprintf("%s: failed setup\n", tulip_devname(sc)); 2033 dumpstat(sc); 2034 eth_free_pkt(sc, pkt); 2035 } 2036 } 2037} 2038 2039static void 2040tulip_setspeed(tulip_softc *sc, int speed) 2041{ 2042 switch (sc->device) { 2043 case K_PCI_ID_DC21040: 2044 dc21040_set_speed(sc, speed); 2045 break; 2046 case K_PCI_ID_DC21041: 2047 dc21041_set_speed(sc, speed); 2048 break; 2049 case K_PCI_ID_DC21140: 2050 dc21140_set_speed(sc, speed, 0); 2051 break; 2052 case K_PCI_ID_DC21143: 2053 dc21143_set_speed(sc, speed); 2054 break; 2055 default: 2056 break; 2057 } 2058} 2059 2060static void 2061tulip_setloopback(tulip_softc *sc, int mode) 2062{ 2063 switch (sc->device) { 2064 case K_PCI_ID_DC21040: 2065 dc21040_set_loopback(sc, mode); 2066 break; 2067 case K_PCI_ID_DC21041: 2068 dc21041_set_loopback(sc, mode); 2069 break; 2070 case K_PCI_ID_DC21140: 2071 dc21140_set_loopback(sc, mode); 2072 break; 2073 case K_PCI_ID_DC21143: 2074 dc21143_set_loopback(sc, mode); 2075 break; 2076 default: 2077 break; 2078 } 2079 cfe_sleep(CFE_HZ/10); 2080} 2081 2082 2083static void 2084tulip_isr(void *arg) 2085{ 2086 uint32_t status; 2087 uint32_t csr5; 2088 tulip_softc *sc = (tulip_softc *)arg; 2089 2090#if IPOLL 2091 sc->interrupts++; 2092#endif 2093 2094 for (;;) { 2095 2096 /* Read the interrupt status. */ 2097 csr5 = READCSR(sc, R_CSR_STATUS); 2098 status = csr5 & ( 2099 M_CSR5_RXINT | M_CSR5_RXBUFUNAVAIL | 2100 M_CSR5_TXINT | M_CSR5_TXUNDERFLOW | 2101 M_CSR5_FATALBUSERROR); 2102 2103 /* if there are no more interrupts, leave now. */ 2104 if (status == 0) break; 2105 2106 /* Clear the pending interrupt. */ 2107 WRITECSR(sc, R_CSR_STATUS, status); 2108 2109 /* Now, test each unmasked bit in the interrupt register and 2110 handle each interrupt type appropriately. */ 2111 2112 if (status & M_CSR5_FATALBUSERROR) { 2113 WRITECSR(sc, R_CSR_INTMASK, 0); 2114 2115 xprintf("%s: bus error %02x\n", 2116 tulip_devname(sc), G_CSR5_ERRORBITS(csr5)); 2117 dumpstat(sc); 2118 sc->bus_errors++; 2119 if (sc->bus_errors >= 2) { 2120 dumpcsrs(sc); 2121 RESET_ADAPTER(sc); 2122 sc->state = eth_state_off; 2123 sc->bus_errors = 0; 2124 } 2125#if IPOLL 2126 else 2127 WRITECSR(sc, R_CSR_INTMASK, sc->intmask); 2128#endif 2129 } 2130 2131 if (status & M_CSR5_RXINT) { 2132#if IPOLL 2133 sc->rx_interrupts++; 2134#endif 2135 tulip_procrxring(sc); 2136 } 2137 2138 if (status & M_CSR5_TXINT) { 2139#if IPOLL 2140 sc->tx_interrupts++; 2141#endif 2142 tulip_proctxring(sc); 2143 } 2144 2145 if (status & (M_CSR5_TXUNDERFLOW | M_CSR5_RXBUFUNAVAIL)) { 2146 if (status & M_CSR5_TXUNDERFLOW) { 2147 xprintf("%s: tx underrun, %08x\n", tulip_devname(sc), csr5); 2148 /* Try to restart */ 2149 WRITECSR(sc, R_CSR_TXPOLL, 1); 2150 } 2151 if (status & M_CSR5_RXBUFUNAVAIL) { 2152 /* Try to restart */ 2153 WRITECSR(sc, R_CSR_RXPOLL, 1); 2154 } 2155 } 2156 } 2157} 2158 2159 2160static void 2161tulip_start(tulip_softc *sc) 2162{ 2163 uint32_t opmode; 2164 2165 tulip_hwinit(sc); 2166 2167 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start)); 2168 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start)); 2169 2170 opmode = READCSR(sc, R_CSR_OPMODE); 2171 opmode &=~ M_CSR6_OPMODE; /* no loopback */ 2172 if (sc->loopback != ETHER_LOOPBACK_OFF) { 2173 opmode &=~ M_CSR6_FULLDUPLEX; 2174 opmode |= M_CSR6_PORTSEL; 2175 if (sc->loopback == ETHER_LOOPBACK_EXT) 2176 opmode |= M_CSR6_EXTLOOPBACK; 2177 else 2178 opmode |= M_CSR6_INTLOOPBACK; 2179 } 2180 2181 sc->intmask = 0; 2182 WRITECSR(sc, R_CSR_INTMASK, 0); /* no interrupts */ 2183 WRITECSR(sc, R_CSR_STATUS, 0x1FFFF); /* clear any pending */ 2184 READCSR(sc, R_CSR_STATUS); /* push the write */ 2185 2186 sc->interrupts = 0; 2187 sc->rx_interrupts = sc->tx_interrupts = 0; 2188 2189#if IPOLL 2190 cfe_request_irq(sc->irq, tulip_isr, sc, CFE_IRQ_FLAGS_SHARED, 0); 2191 2192 sc->intmask = M_CSR7_RXINT | M_CSR7_TXINT | 2193 M_CSR7_NORMALINT; 2194 sc->intmask |= M_CSR7_FATALBUSERROR | M_CSR7_TXUNDERFLOW | 2195 M_CSR7_ABNORMALINT; 2196 WRITECSR(sc, R_CSR_INTMASK, sc->intmask); 2197#endif 2198 2199 if (sc->loopback == ETHER_LOOPBACK_OFF) { 2200 opmode |= M_CSR6_TXSTART; 2201 WRITECSR(sc, R_CSR_OPMODE, opmode); 2202 tulip_setaddr(sc); 2203 } 2204 else { 2205 opmode |= M_CSR6_TXSTART | M_CSR6_RXSTART; 2206 WRITECSR(sc, R_CSR_OPMODE, opmode); 2207 } 2208} 2209 2210static void 2211tulip_stop(tulip_softc *sc) 2212{ 2213 uint32_t opmode; 2214 uint32_t status; 2215 int count; 2216 2217 WRITECSR(sc, R_CSR_INTMASK, 0); 2218 sc->intmask = 0; 2219#if IPOLL 2220 cfe_free_irq(sc->irq, 0); 2221#endif 2222 WRITECSR(sc, R_CSR_STATUS, 0x1FFFF); 2223 opmode = READCSR(sc, R_CSR_OPMODE); 2224 opmode &=~ (M_CSR6_TXSTART | M_CSR6_RXSTART); 2225 WRITECSR(sc, R_CSR_OPMODE, opmode); 2226 2227 /* wait for any DMA activity to terminate */ 2228 for (count = 0; count <= 13; count++) { 2229 status = READCSR(sc, R_CSR_STATUS); 2230 if ((status & (M_CSR5_RXPROCSTATE | M_CSR5_TXPROCSTATE)) == 0) 2231 break; 2232 cfe_sleep(CFE_HZ/10); 2233 } 2234 if (count > 13) { 2235 xprintf("%s: idle state not achieved\n", tulip_devname(sc)); 2236 dumpstat(sc); 2237 RESET_ADAPTER(sc); 2238 sc->state = eth_state_uninit; 2239 sc->linkspeed = ETHER_SPEED_AUTO; 2240 } 2241 else if (sc->loopback != ETHER_LOOPBACK_OFF) { 2242 tulip_setloopback(sc, ETHER_LOOPBACK_OFF); 2243 opmode &=~ M_CSR6_OPMODE; 2244 WRITECSR(sc, R_CSR_OPMODE, opmode); 2245 } 2246 2247 if (sc->outpkts > 1) { 2248 /* heuristic: suppress stats for initial mode changes */ 2249 xprintf("%s: %d sent, %d received, %d interrupts\n", 2250 tulip_devname(sc), sc->outpkts, sc->inpkts, sc->interrupts); 2251 xprintf(" %d rx interrupts, %d tx interrupts\n", 2252 sc->rx_interrupts, sc->tx_interrupts); 2253 } 2254} 2255 2256 2257/* ********************************************************************* 2258 * ETH_PARSE_XDIGIT(c) 2259 * 2260 * Parse a hex digit, returning its value 2261 * 2262 * Input parameters: 2263 * c - character 2264 * 2265 * Return value: 2266 * hex value, or -1 if invalid 2267 ********************************************************************* */ 2268static int 2269eth_parse_xdigit(char c) 2270{ 2271 int digit; 2272 2273 if ((c >= '0') && (c <= '9')) digit = c - '0'; 2274 else if ((c >= 'a') && (c <= 'f')) digit = c - 'a' + 10; 2275 else if ((c >= 'A') && (c <= 'F')) digit = c - 'A' + 10; 2276 else digit = -1; 2277 2278 return digit; 2279} 2280 2281/* ********************************************************************* 2282 * ETH_PARSE_HWADDR(str,hwaddr) 2283 * 2284 * Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte 2285 * Ethernet address. 2286 * 2287 * Input parameters: 2288 * str - string 2289 * hwaddr - pointer to hardware address 2290 * 2291 * Return value: 2292 * 0 if ok, else -1 2293 ********************************************************************* */ 2294static int 2295eth_parse_hwaddr(char *str, uint8_t *hwaddr) 2296{ 2297 int digit1, digit2; 2298 int idx = ENET_ADDR_LEN; 2299 2300 while (*str && (idx > 0)) { 2301 digit1 = eth_parse_xdigit(*str); 2302 if (digit1 < 0) return -1; 2303 str++; 2304 if (!*str) return -1; 2305 2306 if ((*str == ':') || (*str == '-')) { 2307 digit2 = digit1; 2308 digit1 = 0; 2309 } 2310 else { 2311 digit2 = eth_parse_xdigit(*str); 2312 if (digit2 < 0) return -1; 2313 str++; 2314 } 2315 2316 *hwaddr++ = (digit1 << 4) | digit2; 2317 idx--; 2318 2319 if ((*str == ':') || (*str == '-')) 2320 str++; 2321 } 2322 return 0; 2323} 2324 2325/* ********************************************************************* 2326 * ETH_INCR_HWADDR(hwaddr,incr) 2327 * 2328 * Increment a 6-byte Ethernet hardware address, with carries 2329 * 2330 * Input parameters: 2331 * hwaddr - pointer to hardware address 2332 * incr - desired increment 2333 * 2334 * Return value: 2335 * none 2336 ********************************************************************* */ 2337static void 2338eth_incr_hwaddr(uint8_t *hwaddr, unsigned incr) 2339{ 2340 int idx; 2341 int carry; 2342 2343 idx = 5; 2344 carry = incr; 2345 while (idx >= 0 && carry != 0) { 2346 unsigned sum = hwaddr[idx] + carry; 2347 2348 hwaddr[idx] = sum & 0xFF; 2349 carry = sum >> 8; 2350 idx--; 2351 } 2352} 2353 2354 2355/* ********************************************************************* 2356 * Declarations for CFE Device Driver Interface routines 2357 ********************************************************************* */ 2358 2359static int tulip_ether_open(cfe_devctx_t *ctx); 2360static int tulip_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 2361static int tulip_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat); 2362static int tulip_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 2363static int tulip_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 2364static int tulip_ether_close(cfe_devctx_t *ctx); 2365 2366/* ********************************************************************* 2367 * CFE Device Driver dispatch structure 2368 ********************************************************************* */ 2369 2370const static cfe_devdisp_t tulip_ether_dispatch = { 2371 tulip_ether_open, 2372 tulip_ether_read, 2373 tulip_ether_inpstat, 2374 tulip_ether_write, 2375 tulip_ether_ioctl, 2376 tulip_ether_close, 2377 NULL, /* tulip_ether_poll */ 2378 NULL /* tulip_ether_reset */ 2379}; 2380 2381/* ********************************************************************* 2382 * CFE Device Driver descriptor 2383 ********************************************************************* */ 2384 2385const cfe_driver_t dc21143drv = { 2386 "DC21x4x Ethernet", 2387 "eth", 2388 CFE_DEV_NETWORK, 2389 &tulip_ether_dispatch, 2390 tulip_ether_probe 2391}; 2392 2393 2394static int 2395tulip_ether_attach(cfe_driver_t *drv, 2396 pcitag_t tag, int index, uint8_t hwaddr[]) 2397{ 2398 tulip_softc *sc; 2399 uint32_t device; 2400 uint32_t class; 2401 uint32_t reg; 2402 phys_addr_t pa; 2403 const char *devname; 2404 char descr[100]; 2405 uint8_t romaddr[ENET_ADDR_LEN]; 2406 2407 device = pci_conf_read(tag, R_CFG_CFID); 2408 class = pci_conf_read(tag, R_CFG_CFRV); 2409 2410 reg = pci_conf_read(tag, R_CFG_CPMS); 2411 2412 reg = pci_conf_read(tag, R_CFG_CFDD); 2413 pci_conf_write(tag, R_CFG_CFDD, 0); 2414 reg = pci_conf_read(tag, R_CFG_CFDD); 2415 2416 /* Use memory space for the CSRs */ 2417 pci_map_mem(tag, R_CFG_CBMA, PCI_MATCH_BITS, &pa); 2418 2419 sc = (tulip_softc *) KMALLOC(sizeof(tulip_softc), 0); 2420 if (sc == NULL) { 2421 xprintf("DC21x4x: No memory to complete probe\n"); 2422 return 0; 2423 } 2424 memset(sc, 0, sizeof(*sc)); 2425 2426 sc->membase = (uint32_t)pa; 2427 sc->irq = pci_conf_read(tag, R_CFG_CFIT) & 0xFF; 2428 2429 sc->tag = tag; 2430 sc->device = PCI_PRODUCT(device); 2431 sc->revision = PCI_REVISION(class); 2432 sc->devctx = NULL; 2433 2434 sc->linkspeed = ETHER_SPEED_AUTO; /* select autonegotiation */ 2435 sc->loopback = ETHER_LOOPBACK_OFF; 2436 memcpy(sc->hwaddr, hwaddr, ENET_ADDR_LEN); 2437 2438 tulip_init(sc); 2439 2440 /* Prefer address in srom */ 2441 if (rom_read_addr(sc, romaddr) == 0) { 2442 memcpy(sc->hwaddr, romaddr, ENET_ADDR_LEN); 2443 } 2444 2445 sc->state = eth_state_uninit; 2446 2447 switch (sc->device) { 2448 case K_PCI_ID_DC21040: 2449 devname = "DC21040"; break; 2450 case K_PCI_ID_DC21041: 2451 devname = "DC21041"; break; 2452 case K_PCI_ID_DC21140: 2453 devname = "DC21140"; break; 2454 case K_PCI_ID_DC21143: 2455 devname = "DC21143"; break; 2456 default: 2457 devname = "DC21x4x"; break; 2458 } 2459 2460 xsprintf(descr, "%s Ethernet at 0x%X (%02X-%02X-%02X-%02X-%02X-%02X)", 2461 devname, sc->membase, 2462 sc->hwaddr[0], sc->hwaddr[1], sc->hwaddr[2], 2463 sc->hwaddr[3], sc->hwaddr[4], sc->hwaddr[5]); 2464 2465 cfe_attach(drv, sc, NULL, descr); 2466 return 1; 2467} 2468 2469 2470/* ********************************************************************* 2471 * TULIP_ETHER_PROBE(drv,probe_a,probe_b,probe_ptr) 2472 * 2473 * Probe and install drivers for all DC21x4x Ethernet controllers. 2474 * For each, create a context structure and attach to the 2475 * specified network device. 2476 * 2477 * Input parameters: 2478 * drv - driver descriptor 2479 * probe_a - not used 2480 * probe_b - not used 2481 * probe_ptr - string pointer to hardware address for the first 2482 * MAC, in the form xx:xx:xx:xx:xx:xx 2483 * 2484 * Return value: 2485 * nothing 2486 ********************************************************************* */ 2487static void 2488tulip_ether_probe(cfe_driver_t *drv, 2489 unsigned long probe_a, unsigned long probe_b, 2490 void *probe_ptr) 2491{ 2492 int index; 2493 int n; 2494 uint8_t hwaddr[ENET_ADDR_LEN]; 2495 2496 if (probe_ptr) 2497 eth_parse_hwaddr((char *) probe_ptr, hwaddr); 2498 else { 2499 /* use default address 40-00-00-10-11-11 */ 2500 hwaddr[0] = 0x40; hwaddr[1] = 0x00; hwaddr[2] = 0x00; 2501 hwaddr[3] = 0x10; hwaddr[4] = 0x11; hwaddr[5] = 0x11; 2502 } 2503 2504 n = 0; 2505 index = 0; 2506 for (;;) { 2507 pcitag_t tag; 2508 pcireg_t device; 2509 2510 if (pci_find_class(PCI_CLASS_NETWORK, index, &tag) != 0) 2511 break; 2512 2513 index++; 2514 2515 device = pci_conf_read(tag, R_CFG_CFID); 2516 if (PCI_VENDOR(device) == K_PCI_VENDOR_DEC) { 2517 if (PCI_PRODUCT(device) == K_PCI_ID_DC21040 || 2518 PCI_PRODUCT(device) == K_PCI_ID_DC21041 || 2519 PCI_PRODUCT(device) == K_PCI_ID_DC21140 || 2520 PCI_PRODUCT(device) == K_PCI_ID_DC21143) { 2521 2522 tulip_ether_attach(drv, tag, n, hwaddr); 2523 n++; 2524 eth_incr_hwaddr(hwaddr, 1); 2525 } 2526 } 2527 } 2528} 2529 2530 2531/* The functions below are called via the dispatch vector for the 21x4x. */ 2532 2533/* ********************************************************************* 2534 * TULIP_ETHER_OPEN(ctx) 2535 * 2536 * Open the Ethernet device. The MAC is reset, initialized, and 2537 * prepared to receive and send packets. 2538 * 2539 * Input parameters: 2540 * ctx - device context (includes ptr to our softc) 2541 * 2542 * Return value: 2543 * status, 0 = ok 2544 ********************************************************************* */ 2545static int 2546tulip_ether_open(cfe_devctx_t *ctx) 2547{ 2548 tulip_softc *sc = ctx->dev_softc; 2549 2550 if (sc->state == eth_state_on) 2551 tulip_stop(sc); 2552 2553 sc->devctx = ctx; 2554 tulip_start(sc); 2555 2556#if XPOLL 2557 tulip_isr(sc); 2558#endif 2559 2560 return 0; 2561} 2562 2563/* ********************************************************************* 2564 * TULIP_ETHER_READ(ctx,buffer) 2565 * 2566 * Read a packet from the Ethernet device. If no packets are 2567 * available, the read will succeed but return 0 bytes. 2568 * 2569 * Input parameters: 2570 * ctx - device context (includes ptr to our softc) 2571 * buffer - pointer to buffer descriptor. 2572 * 2573 * Return value: 2574 * status, 0 = ok 2575 ********************************************************************* */ 2576static int 2577tulip_ether_read(cfe_devctx_t *ctx, iocb_buffer_t *buffer) 2578{ 2579 tulip_softc *sc = ctx->dev_softc; 2580 eth_pkt_t *pkt; 2581 int blen; 2582 2583#if XPOLL 2584 tulip_isr(sc); 2585#endif 2586 2587 if (sc->state != eth_state_on) return -1; 2588 2589 CS_ENTER(sc); 2590 pkt = (eth_pkt_t *) q_deqnext(&(sc->rxqueue)); 2591 CS_EXIT(sc); 2592 2593 if (pkt == NULL) { 2594 buffer->buf_retlen = 0; 2595 return 0; 2596 } 2597 2598 blen = buffer->buf_length; 2599 if (blen > pkt->length) blen = pkt->length; 2600 2601 blockcopy(buffer->buf_ptr, pkt->buffer, blen); 2602 buffer->buf_retlen = blen; 2603 2604 eth_free_pkt(sc, pkt); 2605 tulip_fillrxring(sc); 2606 2607#if XPOLL 2608 tulip_isr(sc); 2609#endif 2610 2611 return 0; 2612} 2613 2614/* ********************************************************************* 2615 * TULIP_ETHER_INPSTAT(ctx,inpstat) 2616 * 2617 * Check for received packets on the Ethernet device 2618 * 2619 * Input parameters: 2620 * ctx - device context (includes ptr to our softc) 2621 * inpstat - pointer to input status structure 2622 * 2623 * Return value: 2624 * status, 0 = ok 2625 ********************************************************************* */ 2626static int 2627tulip_ether_inpstat(cfe_devctx_t *ctx, iocb_inpstat_t *inpstat) 2628{ 2629 tulip_softc *sc = ctx->dev_softc; 2630 2631#if XPOLL 2632 tulip_isr(sc); 2633#endif 2634 2635 if (sc->state != eth_state_on) return -1; 2636 2637 /* We avoid an interlock here because the result is a hint and an 2638 interrupt cannot turn a non-empty queue into an empty one. */ 2639 inpstat->inp_status = (q_isempty(&(sc->rxqueue))) ? 0 : 1; 2640 2641 return 0; 2642} 2643 2644/* ********************************************************************* 2645 * TULIP_ETHER_WRITE(ctx,buffer) 2646 * 2647 * Write a packet to the Ethernet device. 2648 * 2649 * Input parameters: 2650 * ctx - device context (includes ptr to our softc) 2651 * buffer - pointer to buffer descriptor. 2652 * 2653 * Return value: 2654 * status, 0 = ok 2655 ********************************************************************* */ 2656static int 2657tulip_ether_write(cfe_devctx_t *ctx, iocb_buffer_t *buffer) 2658{ 2659 tulip_softc *sc = ctx->dev_softc; 2660 eth_pkt_t *pkt; 2661 int blen; 2662 2663#if XPOLL 2664 tulip_isr(sc); 2665#endif 2666 2667 if (sc->state != eth_state_on) return -1; 2668 2669 pkt = eth_alloc_pkt(sc); 2670 if (!pkt) return CFE_ERR_NOMEM; 2671 2672 blen = buffer->buf_length; 2673 if (blen > pkt->length) blen = pkt->length; 2674 2675 blockcopy(pkt->buffer, buffer->buf_ptr, blen); 2676 pkt->length = blen; 2677 2678 if (tulip_transmit(sc, pkt) != 0) { 2679 eth_free_pkt(sc,pkt); 2680 return CFE_ERR_IOERR; 2681 } 2682 2683#if XPOLL 2684 tulip_isr(sc); 2685#endif 2686 2687 return 0; 2688} 2689 2690/* ********************************************************************* 2691 * TULIP_ETHER_IOCTL(ctx,buffer) 2692 * 2693 * Do device-specific I/O control operations for the device 2694 * 2695 * Input parameters: 2696 * ctx - device context (includes ptr to our softc) 2697 * buffer - pointer to buffer descriptor. 2698 * 2699 * Return value: 2700 * status, 0 = ok 2701 ********************************************************************* */ 2702static int 2703tulip_ether_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer) 2704{ 2705 tulip_softc *sc = ctx->dev_softc; 2706 int *argp; 2707 int mode; 2708 int speed; 2709 2710 switch ((int)buffer->buf_ioctlcmd) { 2711 case IOCTL_ETHER_GETHWADDR: 2712 memcpy(buffer->buf_ptr, sc->hwaddr, sizeof(sc->hwaddr)); 2713 return 0; 2714 2715 case IOCTL_ETHER_SETHWADDR: 2716 return -1; /* not supported */ 2717 2718 case IOCTL_ETHER_GETSPEED: 2719 argp = (int *) buffer->buf_ptr; 2720 *argp = sc->linkspeed; 2721 return 0; 2722 2723 case IOCTL_ETHER_SETSPEED: 2724 tulip_stop(sc); 2725 tulip_resetrings(sc); 2726 speed = *((int *) buffer->buf_ptr); 2727 tulip_setspeed(sc, speed); 2728 tulip_start(sc); 2729 sc->state = eth_state_on; 2730 return 0; 2731 2732 case IOCTL_ETHER_GETLINK: 2733 argp = (int *) buffer->buf_ptr; 2734 *argp = sc->linkspeed; 2735 return 0; 2736 2737 case IOCTL_ETHER_GETLOOPBACK: 2738 *((int *) buffer) = sc->loopback; 2739 return 0; 2740 2741 case IOCTL_ETHER_SETLOOPBACK: 2742 tulip_stop(sc); 2743 tulip_resetrings(sc); 2744 mode = *((int *) buffer->buf_ptr); 2745 sc->loopback = ETHER_LOOPBACK_OFF; /* default */ 2746 if (mode == ETHER_LOOPBACK_INT || mode == ETHER_LOOPBACK_EXT) { 2747 tulip_setloopback(sc, mode); 2748 } 2749 tulip_start(sc); 2750 sc->state = eth_state_on; 2751 return 0; 2752 2753 default: 2754 return -1; 2755 } 2756} 2757 2758/* ********************************************************************* 2759 * TULIP_ETHER_CLOSE(ctx) 2760 * 2761 * Close the Ethernet device. 2762 * 2763 * Input parameters: 2764 * ctx - device context (includes ptr to our softc) 2765 * 2766 * Return value: 2767 * status, 0 = ok 2768 ********************************************************************* */ 2769static int 2770tulip_ether_close(cfe_devctx_t *ctx) 2771{ 2772 tulip_softc *sc = ctx->dev_softc; 2773 2774 sc->state = eth_state_off; 2775 tulip_stop(sc); 2776 2777 /* resynchronize descriptor rings */ 2778 tulip_resetrings(sc); 2779 2780 sc->devctx = NULL; 2781 return 0; 2782} 2783 2784 2785