1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Broadcom BCM4401 Ethernet Driver File: dev_bcm4401.c 5 * 6 * Author: Ed Satterthwaite 7 * 8 ********************************************************************* 9 * 10 * Copyright 2000,2001,2002,2003 11 * Broadcom Corporation. All rights reserved. 12 * 13 * This software is furnished under license and may be used and 14 * copied only in accordance with the following terms and 15 * conditions. Subject to these conditions, you may download, 16 * copy, install, use, modify and distribute modified or unmodified 17 * copies of this software in source and/or binary form. No title 18 * or ownership is transferred hereby. 19 * 20 * 1) Any source code used, modified or distributed must reproduce 21 * and retain this copyright notice and list of conditions 22 * as they appear in the source file. 23 * 24 * 2) No right is granted to use any trade name, trademark, or 25 * logo of Broadcom Corporation. The "Broadcom Corporation" 26 * name may not be used to endorse or promote products derived 27 * from this software without the prior written permission of 28 * Broadcom Corporation. 29 * 30 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 31 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 32 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 33 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 34 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 35 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 38 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 40 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 41 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 42 * THE POSSIBILITY OF SUCH DAMAGE. 43 ********************************************************************* */ 44 45 46#include "cfe.h" 47#include "lib_try.h" 48#include "lib_physio.h" 49#ifdef CPUCFG_MEMCPY 50#error "this is broken now." 51extern void *CPUCFG_MEMCPY(void *dest, const void *src, size_t cnt); 52#define blockcopy CPUCFG_MEMCPY 53#else 54#define blockcopy memcpy 55#endif 56#include "cfe_irq.h" 57 58#include "net_enet.h" 59 60#include "pcivar.h" 61#include "pcireg.h" 62 63#include "bcm4401.h" 64#include "mii.h" 65 66 67/* This is a driver for the Broadcom 4401 10/100 MAC with integrated PHY. 68 69 This SB1250 version takes advantage of DMA coherence. The BCM4401 70 does not have a big-endian mode for DMA. This driver therefore 71 uses "preserve byte lanes" addresses for all DMA accesses that 72 cross the ZBbus-PCI bridge. Descriptors and packets headers as 73 seen by a big-endian CPU must be byte-swapped for the DMA engine. */ 74 75#ifndef B44_DEBUG 76#define B44_DEBUG 0 77#endif 78 79#if ((ENDIAN_BIG + ENDIAN_LITTLE) != 1) 80#error "dev_bcm4401: system endian not set" 81#endif 82 83/* Temporary, until configs supply MATCH_BYTES */ 84#if defined(MPC824X) /* any machine without preserve-bits for PIO */ 85#define MATCH_BYTES 1 86#else 87#define MATCH_BYTES 0 88#endif 89 90/* Set IPOLL to drive processing through the pseudo-interrupt 91 dispatcher. Set XPOLL to drive processing by an external polling 92 agent. Setting both is ok. */ 93 94#ifndef IPOLL 95#define IPOLL 0 96#endif 97#ifndef XPOLL 98#define XPOLL 1 99#endif 100 101#define CACHE_ALIGN 32 102#define PAGE_ALIGN 4096 103#define ALIGN(n,align) (((n)+((align)-1)) & ~((align)-1)) 104 105#define MIN_ETHER_PACK (ENET_MIN_PKT+ENET_CRC_SIZE) /* size of min packet */ 106#define MAX_ETHER_PACK (ENET_MAX_PKT+ENET_CRC_SIZE) /* size of max packet */ 107 108/* Packet buffers. For the BCM4401, an rx packet is preceded by 109 status information written into the rx buffer. The packet itself 110 begins at a programmable offset (PKTBUF_RX_OFFSET), which must be 111 at least 28. The DMA engine allows arbitrary buffer and packet 112 alignment, but aligning to a cache line boundary can reduce lines 113 touched on the copies. */ 114 115#define PKTBUF_RX_OFFSET CACHE_ALIGN 116#define ETH_PKTBUF_LEN ALIGN(PKTBUF_RX_OFFSET+MAX_ETHER_PACK, CACHE_ALIGN) 117#define ETH_PKTPOOL_SIZE 32 118 119typedef struct eth_pkt_s { 120 queue_t next; /* 8 */ 121 uint8_t *buffer; /* 4 */ 122 uint32_t flags; /* 4 */ 123 int32_t length; /* 4 */ 124 uint32_t unused[3]; /* 12 */ 125 uint8_t data[ETH_PKTBUF_LEN]; 126} eth_pkt_t; 127 128#define ETH_PKTBUF_SIZE ALIGN(sizeof(eth_pkt_t), CACHE_ALIGN) 129#define ETH_PKTBUF_OFFSET (offsetof(eth_pkt_t, data)) 130 131#define ETH_PKT_BASE(data) ((eth_pkt_t *)((data) - ETH_PKTBUF_OFFSET)) 132 133static void 134show_packet(char c, eth_pkt_t *pkt, int offset) 135{ 136 int i; 137 int n = (pkt->length < 32 ? pkt->length : 32); 138 139 xprintf("%c[%4d]:", c, pkt->length); 140 for (i = 0; i < n; i++) { 141 if (i % 4 == 0) 142 xprintf(" "); 143 xprintf("%02x", pkt->buffer[offset+i]); 144 } 145 xprintf("\n"); 146} 147 148 149/* Descriptor structures. The descriptor ring must begin on a 4K 150 boundary and cannot exceed 512 entries. Note that descriptors are 151 referenced by the DMA engine using match-bytes addresses. */ 152 153typedef struct rx_dscr { 154 uint32_t rxd_cmdsts; 155 pci_addr_t rxd_bufptr; 156} rx_dscr; 157 158typedef struct tx_dscr { 159 uint32_t txd_cmdsts; 160 pci_addr_t txd_bufptr; 161} tx_dscr; 162 163 164/* Driver data structures */ 165 166typedef enum { 167 eth_state_uninit, 168 eth_state_off, 169 eth_state_on, 170 eth_state_broken 171} eth_state_t; 172 173typedef struct bcm4401_softc { 174 uint32_t membase; 175 uint8_t irq; /* interrupt mapping (used if IPOLL) */ 176 pcitag_t tag; /* tag for configuration registers */ 177 178 uint8_t hwaddr[ENET_ADDR_LEN]; 179 uint16_t device; /* chip device code */ 180 uint8_t revision; /* chip revision and step */ 181 182 eth_state_t state; /* current state */ 183 uint32_t intmask; /* interrupt mask */ 184 185 /* These fields are set before calling bcm4401_hwinit */ 186 int linkspeed; /* encodings from cfe_ioctl */ 187 int loopback; 188 189 /* Packet free list */ 190 queue_t freelist; 191 uint8_t *pktpool; 192 queue_t rxqueue; 193 194 /* The descriptor tables */ 195 uint8_t *rxdscrmem; /* receive descriptors */ 196 uint8_t *txdscrmem; /* transmit descriptors */ 197 198 /* These fields keep track of where we are in tx/rx processing */ 199 volatile rx_dscr *rxdscr_start; /* beginning of ring */ 200 volatile rx_dscr *rxdscr_end; /* end of ring */ 201 volatile rx_dscr *rxdscr_remove; /* oldest one owned by DMA */ 202 volatile rx_dscr *rxdscr_add; /* next place to put a buffer */ 203 int rxdscr_onring; 204 205 volatile tx_dscr *txdscr_start; /* beginning of ring */ 206 volatile tx_dscr *txdscr_end; /* end of ring */ 207 volatile tx_dscr *txdscr_remove; /* oldest one owned by DMA */ 208 volatile tx_dscr *txdscr_add; /* next place to put a buffer */ 209 210 cfe_devctx_t *devctx; 211 212 int phy_addr; 213 int slow_poll; 214 uint32_t phy_vendor; 215 uint16_t phy_device; 216 217 /* Statistics */ 218 uint32_t inpkts; 219 uint32_t outpkts; 220 uint32_t interrupts; 221 uint32_t rx_interrupts; 222 uint32_t tx_interrupts; 223} bcm4401_softc; 224 225 226/* Entry to and exit from critical sections (currently relative to 227 interrupts only, not SMP) */ 228 229#if CFG_INTERRUPTS 230#define CS_ENTER(sc) cfe_disable_irq(sc->irq) 231#define CS_EXIT(sc) cfe_enable_irq(sc->irq) 232#else 233#define CS_ENTER(sc) ((void)0) 234#define CS_EXIT(sc) ((void)0) 235#endif 236 237 238/* Chip parameterization */ 239 240#define GP_TIMER_HZ 62500000 241 242 243/* Driver parameterization */ 244 245#define MAXRXDSCR 32 246#define MAXTXDSCR 32 247#define MINRXRING 8 248 249 250/* Prototypes */ 251 252static void bcm4401_ether_probe(cfe_driver_t *drv, 253 unsigned long probe_a, unsigned long probe_b, 254 void *probe_ptr); 255 256 257/* Address mapping macros. Accesses in which the BCM4401 is the 258 target are to registers and use match bits mode. Accesses in which 259 it is the initiator always assume little-endian responses and must 260 use match bytes, per the macros below. For big-endian hosts, the 261 DMA status word must be byte-swapped. Also, the PCI interface 262 does address translation so that DMA addresses must be offset. */ 263 264/* Note that PTR_TO_PHYS only works with 32-bit addresses, but then 265 so does the BCM4401. */ 266#define PTR_TO_PHYS(x) (PHYSADDR((uintptr_t)(x))) 267#define PHYS_TO_PTR(a) ((uint8_t *)KERNADDR(a)) 268 269/* The DMA engine does not have a big-endian option for descriptors 270 and data. All its accesses through the host bridge use match bytes 271 mode. The CPU must construct descriptors and headers accordingly. 272 PIO accesses to the configuration and host interface registers use 273 match bits. In addition, the PCI interface does address shifting. 274 Thus the definitions used for most other device drivers don't work 275 here. */ 276#undef PHYS_TO_PCI 277#undef PCI_TO_PHYS 278#define PHYS_TO_PCI(a) ((uint32_t) (a) + 0x40000000) 279#define PCI_TO_PHYS(a) ((uint32_t) (a) - 0x40000000) 280 281#define PCI_TO_PTR(a) (PHYS_TO_PTR(PCI_TO_PHYS(a))) 282#define PTR_TO_PCI(x) (PHYS_TO_PCI(PTR_TO_PHYS(x))) 283 284#if (ENDIAN_BIG && MATCH_BYTES) 285#define CSR_MATCH_MODE PCI_MATCH_BYTES 286#define READCSR(sc,csr) (phys_read32_swapped((sc)->membase + (csr))) 287#define WRITECSR(sc,csr,val) (phys_write32_swapped((sc)->membase + (csr), (val))) 288#else 289#define CSR_MATCH_MODE PCI_MATCH_BITS 290#define READCSR(sc,csr) (phys_read32((sc)->membase + (csr))) 291#define WRITECSR(sc,csr,val) (phys_write32((sc)->membase + (csr), (val))) 292#endif 293 294/* Byte swap utilities: host to/from little-endian */ 295 296#if ENDIAN_BIG 297#define HTOL4(x) \ 298 ((((x) & 0x00FF) << 24) | \ 299 (((x) & 0xFF00) << 8) | \ 300 (((x) >> 8) & 0xFF00) | \ 301 (((x) >> 24) & 0x00FF)) 302 303static uint32_t 304htol4(uint32_t x) 305{ 306 uint32_t t; 307 308 t = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8); 309 return (t >> 16) | ((t & 0xFFFF) << 16); 310} 311#else 312#define HTOL4(x) (x) 313#define htol4(x) (x) 314#endif 315 316#define ltoh4 htol4 /* self-inverse */ 317 318 319/* Packet management */ 320 321static eth_pkt_t * 322eth_alloc_pkt(bcm4401_softc *sc) 323{ 324 eth_pkt_t *pkt; 325 326 CS_ENTER(sc); 327 pkt = (eth_pkt_t *) q_deqnext(&sc->freelist); 328 CS_EXIT(sc); 329 if (!pkt) return NULL; 330 331 pkt->buffer = pkt->data; 332 pkt->length = ETH_PKTBUF_LEN; 333 pkt->flags = 0; 334 335 return pkt; 336} 337 338static void 339eth_free_pkt(bcm4401_softc *sc, eth_pkt_t *pkt) 340{ 341 CS_ENTER(sc); 342 q_enqueue(&sc->freelist, &pkt->next); 343 CS_EXIT(sc); 344} 345 346 347static void 348eth_initfreelist(bcm4401_softc *sc) 349{ 350 int idx; 351 uint8_t *ptr; 352 eth_pkt_t *pkt; 353 354 q_init(&sc->freelist); 355 356 ptr = sc->pktpool; 357 for (idx = 0; idx < ETH_PKTPOOL_SIZE; idx++) { 358 pkt = (eth_pkt_t *) ptr; 359 eth_free_pkt(sc, pkt); 360 ptr += ETH_PKTBUF_SIZE; 361 } 362} 363 364 365/* Utilities */ 366 367static const char * 368bcm4401_devname(bcm4401_softc *sc) 369{ 370 return (sc->devctx != NULL ? cfe_device_name(sc->devctx) : "eth?"); 371} 372 373 374/* Descriptor ring management */ 375 376static int 377bcm4401_add_rcvbuf(bcm4401_softc *sc, eth_pkt_t *pkt) 378{ 379 volatile rx_dscr *rxd; 380 volatile rx_dscr *nextrxd; 381 382 rxd = sc->rxdscr_add; 383 384 nextrxd = rxd+1; 385 if (nextrxd == sc->rxdscr_end) { 386 nextrxd = sc->rxdscr_start; 387 } 388 389 /* If the next one is the same as our remove pointer, the ring is 390 considered full. */ 391 if (nextrxd == sc->rxdscr_remove) return -1; 392 393 /* Only the buffer pointer needs updating. */ 394 rxd->rxd_bufptr = htol4(V_DSCR1_DB(PTR_TO_PCI(pkt->buffer))); 395 396 sc->rxdscr_add = nextrxd; 397 398 WRITECSR(sc, R_RCV_PTR, V_RPTR_LD(PTR_TO_PCI(nextrxd) & 0xFFF)); 399 400 return 0; 401} 402 403static void 404bcm4401_fillrxring(bcm4401_softc *sc) 405{ 406 eth_pkt_t *pkt; 407 408 CS_ENTER(sc); 409 while (1) { 410 if (sc->rxdscr_onring >= MINRXRING) { 411 CS_EXIT(sc); 412 break; 413 } 414 CS_EXIT(sc); 415 pkt = eth_alloc_pkt(sc); 416 if (pkt == NULL) { 417 /* could not allocate a buffer */ 418 break; 419 } 420 if (bcm4401_add_rcvbuf(sc, pkt) != 0) { 421 /* could not add buffer to ring */ 422 eth_free_pkt(sc, pkt); 423 break; 424 } 425 CS_ENTER(sc); 426 sc->rxdscr_onring++; 427 } 428} 429 430 431/* Receive buffer processing. */ 432 433static void 434bcm4401_rx_callback(bcm4401_softc *sc, eth_pkt_t *pkt) 435{ 436 if (B44_DEBUG) show_packet('>', pkt, PKTBUF_RX_OFFSET); 437 438 CS_ENTER(sc); 439 q_enqueue(&sc->rxqueue, &pkt->next); 440 CS_EXIT(sc); 441 sc->inpkts++; 442} 443 444static void 445bcm4401_procrxring(bcm4401_softc *sc) 446{ 447 uint32_t rxstat; 448 volatile rx_dscr *rxcurr; 449 volatile rx_dscr *rxd; 450 eth_pkt_t *pkt; 451 eth_pkt_t *newpkt; 452 uint32_t hdr0; 453 454 rxstat = READCSR(sc, R_RCV_STATUS); 455 rxcurr = (volatile rx_dscr *) 456 ((uint8_t *)sc->rxdscr_start + G_RSTAT_CD(rxstat)); 457 458 for (;;) { 459 rxd = sc->rxdscr_remove; 460 461 if (rxd == rxcurr) { 462 /* all packets processed */ 463 break; 464 } 465 466 pkt = ETH_PKT_BASE(PCI_TO_PTR(ltoh4(rxd->rxd_bufptr))); 467 468 hdr0 = ltoh4(*(uint32_t *)(pkt->buffer)); 469 /* Drop error packets */ 470 /* The header word apparently reports this (undocumented for 4401). 471 MISC (1 << 7) Promiscuous mode enabled. 472 BRDCAST (1 << 6) Broadcast dest 473 MULT (1 << 5) Multicast dest 474 LG (1 << 4) Overlength 475 NO (1 << 3) Odd number of nibbles 476 RXER (1 << 2) Symbol error 477 CRC (1 << 1) CRC error 478 OV (1 << 0) FIFO overflow 479 */ 480 if (hdr0 & M_RCVHDR0_ERRORS) { 481 xprintf("BCM4401: rx error %08X\n", hdr0); 482 newpkt = pkt; /* recycle the buffer */ 483 } 484 else { 485 /* Pass up the packet */ 486 pkt->length = G_RCVHDR0_CD(hdr0) - ENET_CRC_SIZE; 487 bcm4401_rx_callback(sc, pkt); 488 /* put a buffer back on the ring to replace this one */ 489 newpkt = eth_alloc_pkt(sc); 490 } 491 492 /* update the pointer, accounting for buffer wrap. */ 493 rxd++; 494 if (rxd == sc->rxdscr_end) 495 rxd = sc->rxdscr_start; 496 sc->rxdscr_remove = rxd; 497 498 if (newpkt) { 499 /* The ring must have space now. */ 500 bcm4401_add_rcvbuf(sc, newpkt); 501 } 502 else { 503 CS_ENTER(sc); 504 sc->rxdscr_onring--; 505 CS_EXIT(sc); 506 } 507 } 508 509 /* XXX Check for error stops. */ 510} 511 512 513/* Transmit ring processing. */ 514 515static int 516bcm4401_add_txbuf(bcm4401_softc *sc, eth_pkt_t *pkt) 517{ 518 volatile tx_dscr *txd; 519 volatile tx_dscr *nexttxd; 520 uint32_t cmdsts; 521 522 txd = sc->txdscr_add; 523 cmdsts = M_DSCR0_SF | M_DSCR0_EF | M_DSCR0_IC; 524 nexttxd = (txd+1); 525 if (nexttxd == sc->txdscr_end) { 526 cmdsts |= M_DSCR0_ET; 527 nexttxd = sc->txdscr_start; 528 } 529 530 /* If the next one is the same as our remove pointer, the ring is 531 considered full. */ 532 if (nexttxd == sc->txdscr_remove) return -1; 533 534 txd->txd_bufptr = htol4(V_DSCR1_DB(PTR_TO_PCI(pkt->buffer))); 535 cmdsts |= V_DSCR0_BC(pkt->length); 536 txd->txd_cmdsts = htol4(cmdsts); 537 538 sc->txdscr_add = nexttxd; 539 540 return 0; 541} 542 543 544static int 545bcm4401_transmit(bcm4401_softc *sc, eth_pkt_t *pkt) 546{ 547 int rv; 548 549 if (B44_DEBUG) show_packet('<', pkt, 0); 550 551 rv = bcm4401_add_txbuf(sc, pkt); 552 if (rv == 0) { 553 WRITECSR(sc, R_XMT_PTR, V_XPTR_LD(PTR_TO_PCI(sc->txdscr_add) & 0xFFF)); 554 } 555 556 sc->outpkts++; 557 return rv; 558} 559 560static void 561bcm4401_proctxring(bcm4401_softc *sc) 562{ 563 uint32_t txstat; 564 volatile tx_dscr *txcurr; 565 volatile tx_dscr *txd; 566 eth_pkt_t *pkt; 567 568 txstat = READCSR(sc, R_XMT_STATUS); 569 txcurr = (volatile tx_dscr *) 570 ((uint8_t *)sc->txdscr_start + G_XSTAT_CD(txstat)); 571 572 for (;;) { 573 txd = sc->txdscr_remove; 574 575 if (txd == txcurr) { 576 /* ring is empty, no buffers to process */ 577 break; 578 } 579 580 /* Just free the packet */ 581 pkt = ETH_PKT_BASE(PCI_TO_PTR(V_DSCR1_DB(ltoh4(txd->txd_bufptr)))); 582 eth_free_pkt(sc, pkt); 583 584 /* update the pointer, accounting for buffer wrap. */ 585 txd++; 586 if (txd == sc->txdscr_end) 587 txd = sc->txdscr_start; 588 589 sc->txdscr_remove = txd; 590 } 591 592 /* XXX Check for error halt. */ 593} 594 595 596static void 597bcm4401_initrings(bcm4401_softc *sc) 598{ 599 volatile tx_dscr *txd; 600 volatile rx_dscr *rxd; 601 602 for (txd = sc->txdscr_start; txd != sc->txdscr_end; txd++) { 603 txd->txd_cmdsts = HTOL4(M_DSCR0_SF | M_DSCR0_EF | M_DSCR0_IC); 604 txd->txd_bufptr = 0; 605 } 606 (txd-1)->txd_cmdsts |= HTOL4(M_DSCR0_ET); 607 608 for (rxd = sc->rxdscr_start; rxd != sc->rxdscr_end; rxd++) { 609 rxd->rxd_cmdsts = HTOL4(M_DSCR0_SF | M_DSCR0_EF /* XXX needed? */ 610 | V_DSCR0_BC(ETH_PKTBUF_LEN)); 611 rxd->rxd_bufptr = 0; 612 } 613 (rxd-1)->rxd_cmdsts |= HTOL4(M_DSCR0_ET); 614 615 sc->txdscr_add = sc->txdscr_remove = sc->txdscr_start; 616 sc->rxdscr_add = sc->rxdscr_remove = sc->rxdscr_start; 617 sc->rxdscr_onring = 0; 618 619 /* Precharge the receive ring */ 620 bcm4401_fillrxring(sc); 621} 622 623 624static int 625bcm4401_init(bcm4401_softc *sc) 626{ 627 /* Allocate descriptor rings */ 628 sc->rxdscrmem = KMALLOC(MAXRXDSCR*sizeof(rx_dscr), PAGE_ALIGN); 629 sc->txdscrmem = KMALLOC(MAXTXDSCR*sizeof(tx_dscr), PAGE_ALIGN); 630 631 /* Allocate buffer pool */ 632 sc->pktpool = KMALLOC(ETH_PKTPOOL_SIZE*ETH_PKTBUF_SIZE, CACHE_ALIGN); 633 if (sc->pktpool == NULL) { 634 xprintf("%s: No buffer memory available.\n", bcm4401_devname(sc)); 635 return -1; 636 } 637 eth_initfreelist(sc); 638 q_init(&sc->rxqueue); 639 640 /* Fill in pointers to the rings */ 641 sc->rxdscr_start = (volatile rx_dscr *) (sc->rxdscrmem); 642 sc->rxdscr_end = sc->rxdscr_start + MAXRXDSCR; 643 644 sc->txdscr_start = (volatile tx_dscr *) (sc->txdscrmem); 645 sc->txdscr_end = sc->txdscr_start + MAXTXDSCR; 646 647 bcm4401_initrings(sc); 648 649 return 0; 650} 651 652 653static void 654bcm4401_resetrings(bcm4401_softc *sc) 655{ 656 volatile tx_dscr *txd; 657 volatile rx_dscr *rxd; 658 eth_pkt_t *pkt; 659 660 /* Free any pending transmit packets (sent and unsent) */ 661 txd = sc->txdscr_remove; 662 while (txd != sc->txdscr_add) { 663 pkt = ETH_PKT_BASE(PCI_TO_PTR(ltoh4(txd->txd_bufptr))); 664 eth_free_pkt(sc, pkt); 665 666 txd++; 667 if (txd == sc->txdscr_end) 668 txd = sc->txdscr_start; 669 } 670 sc->txdscr_remove = txd; 671 672 /* Discard any received packets as well as all free buffers */ 673 rxd = sc->rxdscr_remove; 674 while (rxd != sc->rxdscr_add) { 675 pkt = ETH_PKT_BASE(PCI_TO_PTR(ltoh4(rxd->rxd_bufptr))); 676 eth_free_pkt(sc, pkt); 677 678 rxd++; 679 if (rxd == sc->rxdscr_end) 680 rxd = sc->rxdscr_start; 681 CS_ENTER(sc); 682 sc->rxdscr_onring--; 683 CS_EXIT(sc); 684 } 685 sc->rxdscr_remove = rxd; 686 687 /* Reestablish the initial state. */ 688 bcm4401_initrings(sc); 689} 690 691 692/* CRC */ 693 694 695/* MII access */ 696 697static void 698mii_enable(bcm4401_softc *sc) 699{ 700 uint32_t devctl; 701 702 WRITECSR(sc, R_MII_STATUS_CONTROL, M_MIICTL_PR | V_MIICTL_MD(0xD)); 703 devctl = READCSR(sc, R_DEV_CONTROL); 704 if ((devctl & M_DVCTL_ER) != 0) { 705 devctl &= ~M_DVCTL_ER; 706 WRITECSR(sc, R_DEV_CONTROL, devctl); 707 cfe_usleep(100); 708 } 709} 710 711static uint16_t 712mii_read(bcm4401_softc *sc, int reg) 713{ 714 uint32_t cmd, status; 715 uint32_t data; 716 int timeout; 717 718 WRITECSR(sc, R_ENET_INT_STATUS, M_EINT_MI); 719 cmd = (V_MIIDATA_OP(K_MII_OP_READ) | V_MIIDATA_TA(K_TA_VALID) | 720 V_MIIDATA_RA(reg) | V_MIIDATA_PM(sc->phy_addr)); 721 WRITECSR(sc, R_MII_DATA, cmd | V_MIIDATA_SB(K_MII_START)); 722 723 for (timeout = 5000; timeout > 0; timeout -= 100) { 724 status = READCSR(sc, R_ENET_INT_STATUS); 725 if ((status & M_EINT_MI) != 0) 726 break; 727 cfe_usleep(100); 728 } 729 730 if (timeout <= 0) 731 return 0xFFFF; 732 733 data = G_MIIDATA_D(READCSR(sc, R_MII_DATA)); 734 return data; 735} 736 737static void 738mii_write(bcm4401_softc *sc, int reg, uint16_t value) 739{ 740 uint32_t cmd, status; 741 int timeout; 742 743 WRITECSR(sc, R_ENET_INT_STATUS, M_EINT_MI); 744 cmd = (V_MIIDATA_OP(K_MII_OP_WRITE) | V_MIIDATA_TA(0x2) | 745 V_MIIDATA_RA(reg) | V_MIIDATA_PM(sc->phy_addr) | 746 V_MIIDATA_D(value)); 747 WRITECSR(sc, R_MII_DATA, cmd | V_MIIDATA_SB(K_MII_START)); 748 749 for (timeout = 5000; timeout > 0; timeout -= 100) { 750 status = READCSR(sc, R_ENET_INT_STATUS); 751 if ((status & M_EINT_MI) != 0) 752 break; 753 cfe_usleep(100); 754 } 755} 756 757static int 758mii_probe(bcm4401_softc *sc) 759{ 760 int i; 761 uint16_t id1, id2; 762 763 for (i = 1; i < 32; i++) { 764 sc->phy_addr = i; 765 id1 = mii_read(sc, R_PHYIDR1); 766 id2 = mii_read(sc, R_PHYIDR2); 767 if ((id1 != 0x0000 && id1 != 0xFFFF) || 768 (id2 != 0x0000 && id2 != 0xFFFF)) { 769 if (id1 != id2) { 770 sc->phy_vendor = ((uint32_t)id1 << 6) | ((id2 >> 10) & 0x3F); 771 sc->phy_device = (id2 >> 4) & 0x3F; 772 return 0; 773 } 774 } 775 } 776 xprintf("mii_probe: No PHY found\n"); 777 sc->phy_addr = 0x1; /* Try the default internal PHY */ 778 sc->phy_vendor = sc->phy_device = 0; 779 return -1; 780} 781 782static void 783mii_set_leds(bcm4401_softc *sc) 784{ 785 uint16_t aux2; 786 787 aux2 = mii_read(sc, R_AUX_MODE_2); 788 aux2 |= M_PHYAUX2_TM; 789 mii_write(sc, R_AUX_MODE_2, aux2); 790} 791 792static void 793mii_set_speed(bcm4401_softc *sc, int speed) 794{ 795 /* NYI */ 796 (void)mii_write; 797} 798 799static uint16_t 800mii_interrupt(bcm4401_softc *sc) 801{ 802 /* The read also clears any interrupt bits. */ 803 return mii_read(sc, R_INTERRUPT); 804} 805 806 807static void 808mii_autonegotiate(bcm4401_softc *sc) 809{ 810 uint16_t control, status, remote; 811 unsigned int timeout; 812 int linkspeed; 813 814 linkspeed = ETHER_SPEED_UNKNOWN; 815 816 /* Read twice to clear latching bits */ 817 status = mii_read(sc, MII_BMSR); 818 status = mii_read(sc, MII_BMSR); 819 820 if ((status & (BMSR_AUTONEG | BMSR_LINKSTAT)) == 821 (BMSR_AUTONEG | BMSR_LINKSTAT)) 822 control = mii_read(sc, MII_BMCR); 823 else { 824 for (timeout = 4*CFE_HZ; timeout > 0; timeout -= CFE_HZ/2) { 825 status = mii_read(sc, MII_BMSR); 826 if ((status & BMSR_ANCOMPLETE) != 0) 827 break; 828 cfe_sleep(CFE_HZ/2); 829 } 830 } 831 832 xprintf("%s: Link speed: ", bcm4401_devname(sc)); 833 remote = mii_read(sc, MII_ANLPAR); 834 if ((status & BMSR_ANCOMPLETE) != 0) { 835 /* A link partner was negotiated... */ 836 837 if ((remote & ANLPAR_TXFD) != 0) { 838 xprintf("100BaseT FDX\n"); 839 linkspeed = ETHER_SPEED_100FDX; 840 } 841 else if ((remote & ANLPAR_TXHD) != 0) { 842 xprintf("100BaseT HDX\n"); 843 linkspeed = ETHER_SPEED_100HDX; 844 } 845 else if ((remote & ANLPAR_10FD) != 0) { 846 xprintf("10BaseT FDX\n"); 847 linkspeed = ETHER_SPEED_10FDX; 848 } 849 else if ((remote & ANLPAR_10HD) != 0) { 850 xprintf("10BaseT HDX\n"); 851 linkspeed = ETHER_SPEED_10HDX; 852 } 853 } 854 else { 855 /* no link partner convergence */ 856 xprintf("Unknown\n"); 857 linkspeed = ETHER_SPEED_UNKNOWN; 858 } 859 sc->linkspeed = linkspeed; 860 861 /* clear latching bits */ 862 status = mii_read(sc, MII_BMSR); 863} 864 865 866static int 867bcm4401_reset(bcm4401_softc *sc) 868{ 869 return 0; 870} 871 872 873/* SPROM access routines. Random read access to the SPROM will 874 produce a bus error due to PCI timeouts. As an apparent 875 (undocumented) side effect, the requested word will be fetched to a 876 local buffer so that the next access will succeed. */ 877 878#define SPROM_SIZE 0x80 879 880static int 881sprom_read_all(bcm4401_softc *sc, uint8_t dest[]) 882{ 883 int i; 884 uint32_t t; 885 jmpbuf_t *jb; 886 887 jb = exc_initialize_block(); 888 if (jb == NULL) 889 return -1; 890 891 for (i = 0; i < SPROM_SIZE; i += 4) { 892 if (exc_try(jb) == 0) { 893 /* On pass 2 parts, the following read gets a bus error */ 894 t = READCSR(sc, SPROM_BASE + i); 895 cfe_usleep(10000); 896 /* the read with valid data (pass 1). */ 897 t = READCSR(sc, SPROM_BASE + i); 898 } 899 else { 900 /* and this one doesn't (pass 2). */ 901 cfe_usleep(10000); /* Delay needed; value is empirical. */ 902 t = READCSR(sc, SPROM_BASE + i); 903 } 904 905 dest[i+0] = (t >> 8) & 0xFF; dest[i+1] = (t >> 0) & 0xFF; 906 t >>= 16; 907 dest[i+2] = (t >> 8) & 0xFF; dest[i+3] = (t >> 0) & 0xFF; 908 909 /* The following is a kludge, but otherwise setjmp is a one-shot. */ 910 exc_handler.catch_exc = 1; 911 } 912 913 exc_cleanup_block(jb); 914 return 0; 915} 916 917static void 918sprom_dump(uint8_t srom[]) 919{ 920 int i; 921 922 xprintf("BCM4401: SPROM data:"); 923 for (i = 0; i < SPROM_SIZE; i++) { 924 if (i % 16 == 0) 925 xprintf("\n %02x: ", i); 926 xprintf(" %02x", srom[i]); 927 } 928 xprintf("\n"); 929} 930 931 932static int 933bcm4401_set_hw_addr(bcm4401_softc *sc, uint8_t addr[]) 934{ 935 uint32_t enet_upper, enet_lower; 936 int timeout; 937 938 enet_upper = (addr[0] << 8) | addr[1]; 939 enet_lower = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; 940 941 WRITECSR(sc, R_CAM_DATA_H, M_CAM_VB | V_CAM_CD_H(enet_upper)); 942 WRITECSR(sc, R_CAM_DATA_L, V_CAM_CD_L(enet_lower)); 943 944 WRITECSR(sc, R_CAM_CONTROL, V_CAMCTL_IX(0) | M_CAMCTL_CW); 945 for (timeout = CFE_HZ; timeout > 0; timeout -= CFE_HZ/10) { 946 if ((READCSR(sc, R_CAM_CONTROL) & M_CAMCTL_CB) != 0) 947 break; 948 cfe_sleep(1); 949 } 950 if (timeout <= 0) 951 return -1; 952 953 return 0; 954} 955 956 957static void 958bcm4401_pciconfig(bcm4401_softc *sc) 959{ 960 uint32_t oldsb; 961 uint32_t idhigh; 962 uint32_t xlat; 963 964 oldsb = pci_conf_read(sc->tag, PCI_PCIBAR0WINDOW_REG); 965 pci_conf_write(sc->tag, PCI_PCIBAR0WINDOW_REG, SB_PCI_BASE); 966 (void)pci_conf_read(sc->tag, PCI_PCIBAR0WINDOW_REG); /* push */ 967 968 idhigh = READCSR(sc, R_SBIDHIGH); 969 if (G_SBID_RV(idhigh) < 6) { 970 /* A0 and A1 parts */ 971 WRITECSR(sc, R_SBINTVEC, V_SBINT_MK(K_SBINT_ENET_MAC)); 972 } 973 else { 974 /* B0 parts (PCI Rev 2.3 support) */ 975 uint32_t mask; 976 977 mask = pci_conf_read(sc->tag, PCI_PCIINTMASK_REG); 978 mask |= V_SBINT_IM(K_SBINT_ENET_MAC); 979 pci_conf_write(sc->tag, PCI_PCIINTMASK_REG, mask); 980 } 981 982 xlat = READCSR(sc, R_SB_TO_PCI_TRANSLATION2); 983 xlat |= (M_SBXLAT_PE | M_SBXLAT_WB); 984 WRITECSR(sc, R_SB_TO_PCI_TRANSLATION2, xlat); 985 986 (void)READCSR(sc, R_SB_TO_PCI_TRANSLATION2); /* push */ 987 988 pci_conf_write(sc->tag, PCI_PCIBAR0WINDOW_REG, oldsb); 989 (void)pci_conf_read(sc->tag, PCI_PCIBAR0WINDOW_REG); /* push */ 990} 991 992 993static void 994bcm4401_set_linkspeed(bcm4401_softc *sc) 995{ 996 uint32_t ctrl; 997 998 ctrl = READCSR(sc, R_XMT_CONTROL1); 999 switch (sc->linkspeed) { 1000 case ETHER_SPEED_100FDX: 1001 case ETHER_SPEED_10FDX: 1002 ctrl |= (M_TCTL_FD | M_TCTL_SB); 1003 break; 1004 default: 1005 ctrl &= ~(M_TCTL_FD | M_TCTL_SB); 1006 break; 1007 } 1008 WRITECSR(sc, R_XMT_CONTROL1, ctrl); 1009} 1010 1011static void 1012bcm4401_hwinit(bcm4401_softc *sc) 1013{ 1014 if (sc->state == eth_state_uninit) { 1015 uint32_t ctrl; 1016 1017 bcm4401_reset(sc); 1018 1019 mii_probe(sc); 1020 mii_write(sc, R_INTERRUPT, M_PHYINT_IE); 1021 mii_autonegotiate(sc); 1022 mii_set_leds(sc); 1023 (void)mii_read(sc, R_INTERRUPT); /* clear any pending */ 1024 1025 bcm4401_set_hw_addr(sc, sc->hwaddr); 1026 WRITECSR(sc, R_CAM_CONTROL, M_CAMCTL_CE); 1027 1028 /* XXX Set the transmit watermark here, if needed. */ 1029 1030 /* Initialize the receive channel. */ 1031 WRITECSR(sc, R_RCV_PTR, 0); 1032 WRITECSR(sc, R_RCV_CONTROL, M_RCTL_RE | V_RCTL_RO(PKTBUF_RX_OFFSET)); 1033 WRITECSR(sc, R_RCV_ADDR, PTR_TO_PCI(sc->rxdscrmem)); 1034 WRITECSR(sc, R_RCV_PTR, PTR_TO_PCI(sc->rxdscr_add) & 0xFFF); 1035 1036 /* Initialize the transmit channel. */ 1037 WRITECSR(sc, R_XMT_PTR, 0); 1038 WRITECSR(sc, R_XMT_CONTROL, M_XCTL_XE); 1039 WRITECSR(sc, R_XMT_ADDR, PTR_TO_PCI(sc->txdscrmem)); 1040 1041 /* Modify Ethernet RX MAC settings (probably obsolete). */ 1042 WRITECSR(sc, R_EMAC_XMT_MAX_BURST, 32); 1043 WRITECSR(sc, R_EMAC_RCV_MAX_BURST, 32); 1044#if 0 1045 WRITECSR(sc, R_RCV_CONFIG, M_RCFG_AM); /* All multicast */ 1046#else 1047 WRITECSR(sc, R_RCV_CONFIG, 0); 1048#endif 1049 WRITECSR(sc, R_RCV_MAX_LENGTH, MAX_ETHER_PACK); 1050 1051 ctrl = READCSR(sc, R_EMAC_CONTROL); 1052 ctrl |= M_EMCTL_CC; 1053 WRITECSR(sc, R_EMAC_CONTROL, ctrl); 1054 1055 bcm4401_set_linkspeed(sc); 1056 1057 WRITECSR(sc, R_XMT_MAX_LENGTH, MAX_ETHER_PACK); 1058 1059 WRITECSR(sc, R_INT_RECV_LAZY, V_INTLZY_FC(1) | V_INTLZY_TO(100)); 1060 1061 /* Enable the MAC */ 1062 ctrl = READCSR(sc, R_ENET_CONTROL); 1063 ctrl |= M_ECTL_EE; 1064 WRITECSR(sc, R_ENET_CONTROL, ctrl); 1065 1066 sc->state = eth_state_on; 1067 } 1068} 1069 1070 1071static void 1072bcm4401_setspeed(bcm4401_softc *sc, int speed) 1073{ 1074 /* XXX Not yet implemented - autonegotiation only. */ 1075 (void)mii_set_speed; 1076} 1077 1078static void 1079bcm4401_setloopback(bcm4401_softc *sc, int mode) 1080{ 1081 /* XXX Not yet implemented. */ 1082} 1083 1084 1085static void 1086bcm4401_isr(void *arg) 1087{ 1088 bcm4401_softc *sc = (bcm4401_softc *)arg; 1089 uint32_t status; 1090 1091#if IPOLL 1092 sc->interrupts++; 1093#endif 1094 1095 for (;;) { 1096 1097 /* Read and clear the interrupt status. */ 1098 status = READCSR(sc, R_INT_STATUS); 1099 status &= sc->intmask; 1100 if (status == 0) 1101 break; 1102 1103 WRITECSR(sc, R_INT_STATUS, status); /* write-to-clear */ 1104 1105 /* XXX Handle SERR, etc. */ 1106 1107 if (status & M_INT_RI) { 1108#if IPOLL 1109 sc->rx_interrupts++; 1110#endif 1111 bcm4401_procrxring(sc); 1112 } 1113 1114 if (status & M_INT_XI) { 1115#if IPOLL 1116 sc->tx_interrupts++; 1117#endif 1118 bcm4401_proctxring(sc); 1119 } 1120 1121 if (status & M_INT_TO) { 1122 sc->slow_poll = 1; 1123 } 1124 1125 if (status & (M_INT_XU | M_INT_RO)) { 1126 if (status & M_INT_XU) { 1127 xprintf("BCM4401: tx underrun, %08x\n", status); 1128 /* XXX Try to restart */ 1129 } 1130 if (status & M_INT_RO) { 1131 xprintf("BCM4401: rx overrun, %08x\n", status); 1132 /* XXX Try to restart */ 1133 } 1134 } 1135 } 1136} 1137 1138 1139static void 1140bcm4401_start(bcm4401_softc *sc) 1141{ 1142 bcm4401_hwinit(sc); 1143 1144 /* Set up loopback here */ 1145 1146 WRITECSR(sc, R_GP_TIMER, 0); /* stop the timer */ 1147 1148 sc->intmask = 0; 1149 WRITECSR(sc, R_INT_MASK, 0); 1150 (void)READCSR(sc, R_INT_STATUS); /* clear any pending */ 1151 1152 sc->intmask = (M_INT_RI | M_INT_XI | M_INT_TO); /* XXX add errors */ 1153 1154#if IPOLL 1155 cfe_request_irq(sc->irq, bcm4401_isr, sc, CFE_IRQ_FLAGS_SHARED, 0); 1156 WRITECSR(sc, R_INT_MASK, sc->intmask); 1157#endif 1158 1159 sc->slow_poll = 0; 1160 WRITECSR(sc, R_GP_TIMER, GP_TIMER_HZ/4); 1161 1162 sc->state = eth_state_on; 1163} 1164 1165static void 1166bcm4401_stop(bcm4401_softc *sc) 1167{ 1168 uint32_t ctl, status; 1169 int i; 1170 1171 /* Cancel the timer */ 1172 WRITECSR(sc, R_GP_TIMER, 0); 1173 (void)READCSR(sc, R_GP_TIMER); 1174 sc->slow_poll = 0; 1175 1176 /* Make sure that no further interrupts will be processed. */ 1177 sc->intmask = 0; 1178 WRITECSR(sc, R_INT_MASK, 0); 1179 (void)READCSR(sc, R_INT_MASK); /* push */ 1180 (void)READCSR(sc, R_INT_STATUS); 1181 1182 /* Shut down MAC */ 1183 WRITECSR(sc, R_ENET_CONTROL, M_ECTL_ED); 1184 for (i = 1000; i > 0; i--) { 1185 ctl = READCSR(sc, R_ENET_CONTROL); 1186 if ((ctl & M_ECTL_ED) == 0) 1187 break; 1188 cfe_usleep(100); 1189 } 1190 if (i == 0) 1191 xprintf("%s: cannot clear MAC\n", bcm4401_devname(sc)); 1192 1193 /* Shut down DMA engines */ 1194 WRITECSR(sc, R_XMT_CONTROL, 0); 1195 for (i = 1000; i > 0; i--) { 1196 status = READCSR(sc, R_XMT_STATUS); 1197 if (G_XSTAT_XS(status) == K_XS_DISABLED) 1198 break; 1199 cfe_usleep(100); 1200 } 1201 if (i == 0) 1202 xprintf("%s: cannot clear tx DMA\n", bcm4401_devname(sc)); 1203 1204 WRITECSR(sc, R_RCV_CONTROL, 0); 1205 for (i = 1000; i > 0; i--) { 1206 status = READCSR(sc, R_RCV_STATUS); 1207 if (G_RSTAT_RS(status) == K_RS_DISABLED) 1208 break; 1209 cfe_usleep(100); 1210 } 1211 if (i == 0) 1212 xprintf("%s: cannot clear rx DMA\n", bcm4401_devname(sc)); 1213 1214 status = READCSR(sc, R_INT_STATUS); 1215 WRITECSR(sc, R_INT_STATUS, status); 1216#if IPOLL 1217 cfe_free_irq(sc->irq, 0); 1218#endif 1219 1220 /* Leave the mii inteface enabled */ 1221 mii_enable(sc); 1222} 1223 1224 1225/* Declarations for CFE Device Driver Interface routines */ 1226 1227static int bcm4401_ether_open(cfe_devctx_t *ctx); 1228static int bcm4401_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 1229static int bcm4401_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat); 1230static int bcm4401_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 1231static int bcm4401_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 1232static int bcm4401_ether_close(cfe_devctx_t *ctx); 1233static void bcm4401_ether_poll(cfe_devctx_t *ctx, int64_t ticks); 1234static void bcm4401_ether_reset(void *softc); 1235 1236 1237/* CFE Device Driver dispatch structure */ 1238 1239const static cfe_devdisp_t bcm4401_ether_dispatch = { 1240 bcm4401_ether_open, 1241 bcm4401_ether_read, 1242 bcm4401_ether_inpstat, 1243 bcm4401_ether_write, 1244 bcm4401_ether_ioctl, 1245 bcm4401_ether_close, 1246 bcm4401_ether_poll, 1247 bcm4401_ether_reset 1248}; 1249 1250 1251/* CFE Device Driver descriptor */ 1252 1253const cfe_driver_t bcm4401drv = { 1254 "BCM4401 Ethernet", 1255 "eth", 1256 CFE_DEV_NETWORK, 1257 &bcm4401_ether_dispatch, 1258 bcm4401_ether_probe 1259}; 1260 1261 1262/* CFE Device Driver probe functions. */ 1263 1264static int 1265bcm4401_ether_attach(cfe_driver_t *drv, pcitag_t tag) 1266{ 1267 bcm4401_softc *sc; 1268 uint32_t device; 1269 uint32_t class; 1270 phys_addr_t pa; 1271 uint8_t sprom[SPROM_SIZE]; 1272 char descr[100]; 1273 1274 device = pci_conf_read(tag, PCI_ID_REG); 1275 class = pci_conf_read(tag, PCI_CLASS_REG); 1276 1277 /* Use memory space for the CSRs */ 1278 pci_map_mem(tag, PCI_MAPREG(0), CSR_MATCH_MODE, &pa); 1279 1280 sc = (bcm4401_softc *) KMALLOC(sizeof(bcm4401_softc), 0); 1281 1282 if (sc == NULL) { 1283 xprintf("BCM4401: No memory to complete probe\n"); 1284 return 0; 1285 } 1286 memset(sc, 0, sizeof(*sc)); 1287 1288 sc->membase = (uint32_t)pa; 1289 sc->irq = pci_conf_read(tag, PCI_BPARAM_INTERRUPT_REG) & 0xFF; 1290 sc->tag = tag; 1291 sc->device = PCI_PRODUCT(device); 1292 sc->revision = PCI_REVISION(class); 1293 sc->devctx = NULL; 1294 1295#if 1 1296 sc->linkspeed = ETHER_SPEED_AUTO; /* select autonegotiation */ 1297#else 1298 sc->linkspeed = ETHER_SPEED_100FDX; /* 100 Mbps, full duplex */ 1299#endif 1300 sc->loopback = ETHER_LOOPBACK_OFF; 1301 1302 /* Enable the core by enabling the core clocks and then clearing 1303 RESET. The backplane mapping registers have been initialized 1304 from the SPROM, but a more paranoid implementation would 1305 reconfigure at this point. */ 1306 WRITECSR(sc, R_SBTMSTATELOW, M_SBTS_RS | M_SBTS_CE | M_SBTS_FC); 1307 (void)READCSR(sc, R_SBTMSTATELOW); /* push */ 1308 cfe_usleep(100); 1309 1310 /* "PR3158 workaround - not fixed in any chip yet" */ 1311 if ((READCSR(sc, R_SBTMSTATEHI) & M_SBTS_SE) != 0) { 1312 WRITECSR(sc, R_SBTMSTATEHI, 0); 1313 } 1314 if ((READCSR(sc, R_SBIMSTATE) & (M_SBIS_IE | M_SBIS_TO)) != 0) { 1315 uint32_t sbis; 1316 sbis = READCSR(sc, R_SBIMSTATE); 1317 sbis &= ~(M_SBIS_IE | M_SBIS_TO); 1318 WRITECSR(sc, R_SBIMSTATE, sbis); 1319 } 1320 /* End of workaround */ 1321 1322 WRITECSR(sc, R_SBTMSTATELOW, M_SBTS_CE | M_SBTS_FC); 1323 (void)READCSR(sc, R_SBTMSTATELOW); /* push */ 1324 cfe_usleep(100); 1325 WRITECSR(sc, R_SBTMSTATELOW, M_SBTS_CE); 1326 (void)READCSR(sc, R_SBTMSTATELOW); /* push */ 1327 cfe_usleep(100); 1328 1329 bcm4401_pciconfig(sc); 1330 1331 mii_enable(sc); 1332 1333 bcm4401_init(sc); 1334 1335 sprom_read_all(sc, sprom); 1336 if (B44_DEBUG) sprom_dump(sprom); 1337 1338 /* Use the address in EEPROM. */ 1339 memcpy(sc->hwaddr, &sprom[SPROM_MAC_ADDR], ENET_ADDR_LEN); 1340 sc->phy_addr = sprom[SPROM_PHY_ADDR] & 0x1F; 1341 1342 sc->state = eth_state_uninit; 1343 1344 xsprintf(descr, "%s at 0x%X (%a)", 1345 drv->drv_description, sc->membase, sc->hwaddr); 1346 1347 cfe_attach(drv, sc, NULL, descr); 1348 return 1; 1349} 1350 1351static void 1352bcm4401_ether_probe(cfe_driver_t *drv, 1353 unsigned long probe_a, unsigned long probe_b, 1354 void *probe_ptr) 1355{ 1356 int index; 1357 1358 index = 0; 1359 for (;;) { 1360 pcitag_t tag; 1361 pcireg_t device; 1362 1363 if (pci_find_class(PCI_CLASS_NETWORK, index, &tag) != 0) 1364 break; 1365 1366 index++; 1367 1368 device = pci_conf_read(tag, PCI_ID_REG); 1369 if (PCI_VENDOR(device) == K_PCI_VENDOR_BROADCOM) { 1370 switch (PCI_PRODUCT(device)) { 1371 case K_PCI_ID_BCM4401: 1372 case K_PCI_ID_BCM4401_B: 1373 case K_PCI_ID_BCM4402: 1374 bcm4401_ether_attach(drv, tag); 1375 break; 1376 default: 1377 break; 1378 } 1379 } 1380 } 1381} 1382 1383 1384/* The functions below are called via the dispatch vector for the 4401. */ 1385 1386static int 1387bcm4401_ether_open(cfe_devctx_t *ctx) 1388{ 1389 bcm4401_softc *sc = ctx->dev_softc; 1390 1391 if (sc->state == eth_state_on) 1392 bcm4401_stop(sc); 1393 1394 sc->devctx = ctx; 1395 1396 sc->inpkts = sc->outpkts = 0; 1397 sc->interrupts = 0; 1398 sc->rx_interrupts = sc->tx_interrupts = 0; 1399 1400 bcm4401_start(sc); 1401 1402#if XPOLL 1403 bcm4401_isr(sc); 1404#endif 1405 1406 return 0; 1407} 1408 1409static int 1410bcm4401_ether_read(cfe_devctx_t *ctx, iocb_buffer_t *buffer) 1411{ 1412 bcm4401_softc *sc = ctx->dev_softc; 1413 eth_pkt_t *pkt; 1414 int blen; 1415 1416#if XPOLL 1417 bcm4401_isr(sc); 1418#endif 1419 1420 if (sc->state != eth_state_on) return -1; 1421 1422 CS_ENTER(sc); 1423 pkt = (eth_pkt_t *) q_deqnext(&(sc->rxqueue)); 1424 CS_EXIT(sc); 1425 1426 if (pkt == NULL) { 1427 buffer->buf_retlen = 0; 1428 return 0; 1429 } 1430 1431 blen = buffer->buf_length; 1432 if (blen > pkt->length) blen = pkt->length; 1433 1434 hs_memcpy_to_hs(buffer->buf_ptr, pkt->buffer+PKTBUF_RX_OFFSET, blen); 1435 buffer->buf_retlen = blen; 1436 1437 eth_free_pkt(sc, pkt); 1438 bcm4401_fillrxring(sc); 1439 1440#if XPOLL 1441 bcm4401_isr(sc); 1442#endif 1443 1444 return 0; 1445} 1446 1447static int 1448bcm4401_ether_inpstat(cfe_devctx_t *ctx, iocb_inpstat_t *inpstat) 1449{ 1450 bcm4401_softc *sc = ctx->dev_softc; 1451 1452#if XPOLL 1453 bcm4401_isr(sc); 1454#endif 1455 1456 if (sc->state != eth_state_on) return -1; 1457 1458 /* We avoid an interlock here because the result is a hint and an 1459 interrupt cannot turn a non-empty queue into an empty one. */ 1460 inpstat->inp_status = (q_isempty(&(sc->rxqueue))) ? 0 : 1; 1461 1462 return 0; 1463} 1464 1465static int 1466bcm4401_ether_write(cfe_devctx_t *ctx, iocb_buffer_t *buffer) 1467{ 1468 bcm4401_softc *sc = ctx->dev_softc; 1469 eth_pkt_t *pkt; 1470 int blen; 1471 1472#if XPOLL 1473 bcm4401_isr(sc); 1474#endif 1475 1476 if (sc->state != eth_state_on) return -1; 1477 1478 pkt = eth_alloc_pkt(sc); 1479 if (!pkt) return CFE_ERR_NOMEM; 1480 1481 blen = buffer->buf_length; 1482 if (blen > pkt->length) blen = pkt->length; 1483 1484 hs_memcpy_from_hs(pkt->buffer, buffer->buf_ptr, blen); 1485 pkt->length = blen; 1486 1487 if (bcm4401_transmit(sc, pkt) != 0) { 1488 eth_free_pkt(sc,pkt); 1489 return CFE_ERR_IOERR; 1490 } 1491 1492#if XPOLL 1493 bcm4401_isr(sc); 1494#endif 1495 1496 return 0; 1497} 1498 1499static int 1500bcm4401_ether_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer) 1501{ 1502 bcm4401_softc *sc = ctx->dev_softc; 1503 int mode; 1504 int speed; 1505 1506 switch ((int)buffer->buf_ioctlcmd) { 1507 case IOCTL_ETHER_GETHWADDR: 1508 hs_memcpy_to_hs(buffer->buf_ptr, sc->hwaddr, sizeof(sc->hwaddr)); 1509 return 0; 1510 1511 case IOCTL_ETHER_SETHWADDR: 1512 return -1; /* not supported */ 1513 1514 case IOCTL_ETHER_GETSPEED: 1515 speed = sc->linkspeed; 1516 hs_memcpy_to_hs(buffer->buf_ptr,&speed,sizeof(int)); 1517 return 0; 1518 1519 case IOCTL_ETHER_SETSPEED: 1520 hs_memcpy_from_hs(&speed,buffer->buf_ptr,sizeof(int)); 1521 bcm4401_setspeed(sc, speed); 1522 return -1; /* not supported yet */ 1523 1524 case IOCTL_ETHER_GETLINK: 1525 speed = sc->linkspeed; 1526 hs_memcpy_to_hs(buffer->buf_ptr,&speed,sizeof(int)); 1527 return 0; 1528 1529 case IOCTL_ETHER_GETLOOPBACK: 1530 mode = sc->loopback; 1531 hs_memcpy_to_hs(buffer->buf_ptr,&mode,sizeof(int)); 1532 return 0; 1533 1534 case IOCTL_ETHER_SETLOOPBACK: 1535 hs_memcpy_from_hs(&mode,buffer->buf_ptr,sizeof(int)); 1536 sc->loopback = ETHER_LOOPBACK_OFF; /* default */ 1537 if (mode == ETHER_LOOPBACK_INT || mode == ETHER_LOOPBACK_EXT) { 1538 bcm4401_setloopback(sc, mode); 1539 } 1540 return -1; /* not supported yet */ 1541 1542 default: 1543 return -1; 1544 } 1545} 1546 1547static int 1548bcm4401_ether_close(cfe_devctx_t *ctx) 1549{ 1550 bcm4401_softc *sc = ctx->dev_softc; 1551 1552 sc->state = eth_state_off; 1553 bcm4401_stop(sc); 1554 1555 xprintf("%s: %d sent, %d received, %d interrupts\n", 1556 bcm4401_devname(sc), sc->outpkts, sc->inpkts, sc->interrupts); 1557 if (IPOLL) { 1558 xprintf(" %d tx interrupts, %d rx interrupts\n", 1559 sc->tx_interrupts, sc->rx_interrupts); 1560 } 1561 1562 /* resynchronize descriptor rings */ 1563 bcm4401_resetrings(sc); 1564 1565 sc->devctx = NULL; 1566#if 1 /* XXX Redo partitioning among hwinit, start and stop */ 1567 sc->state = eth_state_uninit; 1568#endif 1569 return 0; 1570} 1571 1572static void 1573bcm4401_ether_poll(cfe_devctx_t *ctx, int64_t ticks) 1574{ 1575 bcm4401_softc *sc = (bcm4401_softc *)ctx->dev_softc; 1576 uint16_t phy_isr; 1577 1578 /* The PHY Interrupt register appears to work as claimed with 1579 respect to link status changes, but I've had no luck clearing 1580 the MIIInt bit in the EnetIntStatus register. We therefore use 1581 polling but reduce the frequency since reading MII registers is 1582 expensive. */ 1583 if (sc->slow_poll) { 1584 sc->slow_poll = 0; 1585 phy_isr = mii_interrupt(sc); 1586 if ((phy_isr & (M_PHYINT_LC | M_PHYINT_SP | M_PHYINT_DC)) != 0) { 1587 mii_autonegotiate(sc); 1588 bcm4401_set_linkspeed(sc); 1589 } 1590 } 1591} 1592 1593static void 1594bcm4401_ether_reset(void *softc) 1595{ 1596 bcm4401_softc *sc = (bcm4401_softc *)softc; 1597 1598 /* Turn off the Ethernet interface. */ 1599 if (sc->state == eth_state_on) 1600 bcm4401_stop(sc); 1601 bcm4401_reset(sc); 1602 1603 sc->state = eth_state_uninit; 1604} 1605