if_my.c revision 146734
1/*- 2 * Written by: yen_cw@myson.com.tw 3 * Copyright (c) 2002 Myson Technology Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions, and the following disclaimer, 11 * without modification, immediately at the beginning of the file. 12 * 2. The name of the author may not be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Myson fast ethernet PCI NIC driver, available at: http://www.myson.com.tw/ 28 */ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: head/sys/dev/my/if_my.c 146734 2005-05-29 04:42:30Z nyan $"); 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/sockio.h> 36#include <sys/mbuf.h> 37#include <sys/malloc.h> 38#include <sys/kernel.h> 39#include <sys/socket.h> 40#include <sys/queue.h> 41#include <sys/types.h> 42#include <sys/bus.h> 43#include <sys/module.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46 47#define NBPFILTER 1 48 49#include <net/if.h> 50#include <net/if_arp.h> 51#include <net/ethernet.h> 52#include <net/if_media.h> 53#include <net/if_dl.h> 54#include <net/bpf.h> 55 56#include <vm/vm.h> /* for vtophys */ 57#include <vm/pmap.h> /* for vtophys */ 58#include <machine/clock.h> /* for DELAY */ 59#include <machine/bus.h> 60#include <machine/resource.h> 61#include <sys/bus.h> 62#include <sys/rman.h> 63 64#include <dev/pci/pcireg.h> 65#include <dev/pci/pcivar.h> 66 67#include <dev/mii/mii.h> 68#include <dev/mii/miivar.h> 69 70#include "miibus_if.h" 71 72/* 73 * #define MY_USEIOSPACE 74 */ 75 76static int MY_USEIOSPACE = 1; 77 78#if (MY_USEIOSPACE) 79#define MY_RES SYS_RES_IOPORT 80#define MY_RID MY_PCI_LOIO 81#else 82#define MY_RES SYS_RES_MEMORY 83#define MY_RID MY_PCI_LOMEM 84#endif 85 86 87#include <dev/my/if_myreg.h> 88 89#ifndef lint 90static const char rcsid[] = 91"$Id: if_my.c,v 1.16 2003/04/15 06:37:25 mdodd Exp $"; 92#endif 93 94/* 95 * Various supported device vendors/types and their names. 96 */ 97struct my_type *my_info_tmp; 98static struct my_type my_devs[] = { 99 {MYSONVENDORID, MTD800ID, "Myson MTD80X Based Fast Ethernet Card"}, 100 {MYSONVENDORID, MTD803ID, "Myson MTD80X Based Fast Ethernet Card"}, 101 {MYSONVENDORID, MTD891ID, "Myson MTD89X Based Giga Ethernet Card"}, 102 {0, 0, NULL} 103}; 104 105/* 106 * Various supported PHY vendors/types and their names. Note that this driver 107 * will work with pretty much any MII-compliant PHY, so failure to positively 108 * identify the chip is not a fatal error. 109 */ 110static struct my_type my_phys[] = { 111 {MysonPHYID0, MysonPHYID0, "<MYSON MTD981>"}, 112 {SeeqPHYID0, SeeqPHYID0, "<SEEQ 80225>"}, 113 {AhdocPHYID0, AhdocPHYID0, "<AHDOC 101>"}, 114 {MarvellPHYID0, MarvellPHYID0, "<MARVELL 88E1000>"}, 115 {LevelOnePHYID0, LevelOnePHYID0, "<LevelOne LXT1000>"}, 116 {0, 0, "<MII-compliant physical interface>"} 117}; 118 119static int my_probe(device_t); 120static int my_attach(device_t); 121static int my_detach(device_t); 122static int my_newbuf(struct my_softc *, struct my_chain_onefrag *); 123static int my_encap(struct my_softc *, struct my_chain *, struct mbuf *); 124static void my_rxeof(struct my_softc *); 125static void my_txeof(struct my_softc *); 126static void my_txeoc(struct my_softc *); 127static void my_intr(void *); 128static void my_start(struct ifnet *); 129static int my_ioctl(struct ifnet *, u_long, caddr_t); 130static void my_init(void *); 131static void my_stop(struct my_softc *); 132static void my_watchdog(struct ifnet *); 133static void my_shutdown(device_t); 134static int my_ifmedia_upd(struct ifnet *); 135static void my_ifmedia_sts(struct ifnet *, struct ifmediareq *); 136static u_int16_t my_phy_readreg(struct my_softc *, int); 137static void my_phy_writereg(struct my_softc *, int, int); 138static void my_autoneg_xmit(struct my_softc *); 139static void my_autoneg_mii(struct my_softc *, int, int); 140static void my_setmode_mii(struct my_softc *, int); 141static void my_getmode_mii(struct my_softc *); 142static void my_setcfg(struct my_softc *, int); 143static void my_setmulti(struct my_softc *); 144static void my_reset(struct my_softc *); 145static int my_list_rx_init(struct my_softc *); 146static int my_list_tx_init(struct my_softc *); 147static long my_send_cmd_to_phy(struct my_softc *, int, int); 148 149#define MY_SETBIT(sc, reg, x) CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x)) 150#define MY_CLRBIT(sc, reg, x) CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(x)) 151 152static device_method_t my_methods[] = { 153 /* Device interface */ 154 DEVMETHOD(device_probe, my_probe), 155 DEVMETHOD(device_attach, my_attach), 156 DEVMETHOD(device_detach, my_detach), 157 DEVMETHOD(device_shutdown, my_shutdown), 158 159 {0, 0} 160}; 161 162static driver_t my_driver = { 163 "my", 164 my_methods, 165 sizeof(struct my_softc) 166}; 167 168static devclass_t my_devclass; 169 170DRIVER_MODULE(my, pci, my_driver, my_devclass, 0, 0); 171MODULE_DEPEND(my, pci, 1, 1, 1); 172MODULE_DEPEND(my, ether, 1, 1, 1); 173 174static long 175my_send_cmd_to_phy(struct my_softc * sc, int opcode, int regad) 176{ 177 long miir; 178 int i; 179 int mask, data; 180 181 MY_LOCK(sc); 182 183 /* enable MII output */ 184 miir = CSR_READ_4(sc, MY_MANAGEMENT); 185 miir &= 0xfffffff0; 186 187 miir |= MY_MASK_MIIR_MII_WRITE + MY_MASK_MIIR_MII_MDO; 188 189 /* send 32 1's preamble */ 190 for (i = 0; i < 32; i++) { 191 /* low MDC; MDO is already high (miir) */ 192 miir &= ~MY_MASK_MIIR_MII_MDC; 193 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 194 195 /* high MDC */ 196 miir |= MY_MASK_MIIR_MII_MDC; 197 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 198 } 199 200 /* calculate ST+OP+PHYAD+REGAD+TA */ 201 data = opcode | (sc->my_phy_addr << 7) | (regad << 2); 202 203 /* sent out */ 204 mask = 0x8000; 205 while (mask) { 206 /* low MDC, prepare MDO */ 207 miir &= ~(MY_MASK_MIIR_MII_MDC + MY_MASK_MIIR_MII_MDO); 208 if (mask & data) 209 miir |= MY_MASK_MIIR_MII_MDO; 210 211 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 212 /* high MDC */ 213 miir |= MY_MASK_MIIR_MII_MDC; 214 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 215 DELAY(30); 216 217 /* next */ 218 mask >>= 1; 219 if (mask == 0x2 && opcode == MY_OP_READ) 220 miir &= ~MY_MASK_MIIR_MII_WRITE; 221 } 222 223 MY_UNLOCK(sc); 224 return miir; 225} 226 227 228static u_int16_t 229my_phy_readreg(struct my_softc * sc, int reg) 230{ 231 long miir; 232 int mask, data; 233 234 MY_LOCK(sc); 235 236 if (sc->my_info->my_did == MTD803ID) 237 data = CSR_READ_2(sc, MY_PHYBASE + reg * 2); 238 else { 239 miir = my_send_cmd_to_phy(sc, MY_OP_READ, reg); 240 241 /* read data */ 242 mask = 0x8000; 243 data = 0; 244 while (mask) { 245 /* low MDC */ 246 miir &= ~MY_MASK_MIIR_MII_MDC; 247 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 248 249 /* read MDI */ 250 miir = CSR_READ_4(sc, MY_MANAGEMENT); 251 if (miir & MY_MASK_MIIR_MII_MDI) 252 data |= mask; 253 254 /* high MDC, and wait */ 255 miir |= MY_MASK_MIIR_MII_MDC; 256 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 257 DELAY(30); 258 259 /* next */ 260 mask >>= 1; 261 } 262 263 /* low MDC */ 264 miir &= ~MY_MASK_MIIR_MII_MDC; 265 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 266 } 267 268 MY_UNLOCK(sc); 269 return (u_int16_t) data; 270} 271 272 273static void 274my_phy_writereg(struct my_softc * sc, int reg, int data) 275{ 276 long miir; 277 int mask; 278 279 MY_LOCK(sc); 280 281 if (sc->my_info->my_did == MTD803ID) 282 CSR_WRITE_2(sc, MY_PHYBASE + reg * 2, data); 283 else { 284 miir = my_send_cmd_to_phy(sc, MY_OP_WRITE, reg); 285 286 /* write data */ 287 mask = 0x8000; 288 while (mask) { 289 /* low MDC, prepare MDO */ 290 miir &= ~(MY_MASK_MIIR_MII_MDC + MY_MASK_MIIR_MII_MDO); 291 if (mask & data) 292 miir |= MY_MASK_MIIR_MII_MDO; 293 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 294 DELAY(1); 295 296 /* high MDC */ 297 miir |= MY_MASK_MIIR_MII_MDC; 298 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 299 DELAY(1); 300 301 /* next */ 302 mask >>= 1; 303 } 304 305 /* low MDC */ 306 miir &= ~MY_MASK_MIIR_MII_MDC; 307 CSR_WRITE_4(sc, MY_MANAGEMENT, miir); 308 } 309 MY_UNLOCK(sc); 310 return; 311} 312 313 314/* 315 * Program the 64-bit multicast hash filter. 316 */ 317static void 318my_setmulti(struct my_softc * sc) 319{ 320 struct ifnet *ifp; 321 int h = 0; 322 u_int32_t hashes[2] = {0, 0}; 323 struct ifmultiaddr *ifma; 324 u_int32_t rxfilt; 325 int mcnt = 0; 326 327 MY_LOCK(sc); 328 329 ifp = &sc->arpcom.ac_if; 330 331 rxfilt = CSR_READ_4(sc, MY_TCRRCR); 332 333 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 334 rxfilt |= MY_AM; 335 CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); 336 CSR_WRITE_4(sc, MY_MAR0, 0xFFFFFFFF); 337 CSR_WRITE_4(sc, MY_MAR1, 0xFFFFFFFF); 338 339 MY_UNLOCK(sc); 340 341 return; 342 } 343 /* first, zot all the existing hash bits */ 344 CSR_WRITE_4(sc, MY_MAR0, 0); 345 CSR_WRITE_4(sc, MY_MAR1, 0); 346 347 /* now program new ones */ 348 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 349 if (ifma->ifma_addr->sa_family != AF_LINK) 350 continue; 351 h = ~ether_crc32_be(LLADDR((struct sockaddr_dl *) 352 ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 353 if (h < 32) 354 hashes[0] |= (1 << h); 355 else 356 hashes[1] |= (1 << (h - 32)); 357 mcnt++; 358 } 359 360 if (mcnt) 361 rxfilt |= MY_AM; 362 else 363 rxfilt &= ~MY_AM; 364 CSR_WRITE_4(sc, MY_MAR0, hashes[0]); 365 CSR_WRITE_4(sc, MY_MAR1, hashes[1]); 366 CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); 367 MY_UNLOCK(sc); 368 return; 369} 370 371/* 372 * Initiate an autonegotiation session. 373 */ 374static void 375my_autoneg_xmit(struct my_softc * sc) 376{ 377 u_int16_t phy_sts = 0; 378 379 MY_LOCK(sc); 380 381 my_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET); 382 DELAY(500); 383 while (my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_RESET); 384 385 phy_sts = my_phy_readreg(sc, PHY_BMCR); 386 phy_sts |= PHY_BMCR_AUTONEGENBL | PHY_BMCR_AUTONEGRSTR; 387 my_phy_writereg(sc, PHY_BMCR, phy_sts); 388 389 MY_UNLOCK(sc); 390 return; 391} 392 393 394/* 395 * Invoke autonegotiation on a PHY. 396 */ 397static void 398my_autoneg_mii(struct my_softc * sc, int flag, int verbose) 399{ 400 u_int16_t phy_sts = 0, media, advert, ability; 401 u_int16_t ability2 = 0; 402 struct ifnet *ifp; 403 struct ifmedia *ifm; 404 405 MY_LOCK(sc); 406 407 ifm = &sc->ifmedia; 408 ifp = &sc->arpcom.ac_if; 409 410 ifm->ifm_media = IFM_ETHER | IFM_AUTO; 411 412#ifndef FORCE_AUTONEG_TFOUR 413 /* 414 * First, see if autoneg is supported. If not, there's no point in 415 * continuing. 416 */ 417 phy_sts = my_phy_readreg(sc, PHY_BMSR); 418 if (!(phy_sts & PHY_BMSR_CANAUTONEG)) { 419 if (verbose) 420 printf("my%d: autonegotiation not supported\n", 421 sc->my_unit); 422 ifm->ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX; 423 MY_UNLOCK(sc); 424 return; 425 } 426#endif 427 switch (flag) { 428 case MY_FLAG_FORCEDELAY: 429 /* 430 * XXX Never use this option anywhere but in the probe 431 * routine: making the kernel stop dead in its tracks for 432 * three whole seconds after we've gone multi-user is really 433 * bad manners. 434 */ 435 my_autoneg_xmit(sc); 436 DELAY(5000000); 437 break; 438 case MY_FLAG_SCHEDDELAY: 439 /* 440 * Wait for the transmitter to go idle before starting an 441 * autoneg session, otherwise my_start() may clobber our 442 * timeout, and we don't want to allow transmission during an 443 * autoneg session since that can screw it up. 444 */ 445 if (sc->my_cdata.my_tx_head != NULL) { 446 sc->my_want_auto = 1; 447 MY_UNLOCK(sc); 448 return; 449 } 450 my_autoneg_xmit(sc); 451 ifp->if_timer = 5; 452 sc->my_autoneg = 1; 453 sc->my_want_auto = 0; 454 MY_UNLOCK(sc); 455 return; 456 case MY_FLAG_DELAYTIMEO: 457 ifp->if_timer = 0; 458 sc->my_autoneg = 0; 459 break; 460 default: 461 printf("my%d: invalid autoneg flag: %d\n", sc->my_unit, flag); 462 MY_UNLOCK(sc); 463 return; 464 } 465 466 if (my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP) { 467 if (verbose) 468 printf("my%d: autoneg complete, ", sc->my_unit); 469 phy_sts = my_phy_readreg(sc, PHY_BMSR); 470 } else { 471 if (verbose) 472 printf("my%d: autoneg not complete, ", sc->my_unit); 473 } 474 475 media = my_phy_readreg(sc, PHY_BMCR); 476 477 /* Link is good. Report modes and set duplex mode. */ 478 if (my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT) { 479 if (verbose) 480 printf("my%d: link status good. ", sc->my_unit); 481 advert = my_phy_readreg(sc, PHY_ANAR); 482 ability = my_phy_readreg(sc, PHY_LPAR); 483 if ((sc->my_pinfo->my_vid == MarvellPHYID0) || 484 (sc->my_pinfo->my_vid == LevelOnePHYID0)) { 485 ability2 = my_phy_readreg(sc, PHY_1000SR); 486 if (ability2 & PHY_1000SR_1000BTXFULL) { 487 advert = 0; 488 ability = 0; 489 /* 490 * this version did not support 1000M, 491 * ifm->ifm_media = 492 * IFM_ETHER|IFM_1000_T|IFM_FDX; 493 */ 494 ifm->ifm_media = 495 IFM_ETHER | IFM_100_TX | IFM_FDX; 496 media &= ~PHY_BMCR_SPEEDSEL; 497 media |= PHY_BMCR_1000; 498 media |= PHY_BMCR_DUPLEX; 499 printf("(full-duplex, 1000Mbps)\n"); 500 } else if (ability2 & PHY_1000SR_1000BTXHALF) { 501 advert = 0; 502 ability = 0; 503 /* 504 * this version did not support 1000M, 505 * ifm->ifm_media = IFM_ETHER|IFM_1000_T; 506 */ 507 ifm->ifm_media = IFM_ETHER | IFM_100_TX; 508 media &= ~PHY_BMCR_SPEEDSEL; 509 media &= ~PHY_BMCR_DUPLEX; 510 media |= PHY_BMCR_1000; 511 printf("(half-duplex, 1000Mbps)\n"); 512 } 513 } 514 if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) { 515 ifm->ifm_media = IFM_ETHER | IFM_100_T4; 516 media |= PHY_BMCR_SPEEDSEL; 517 media &= ~PHY_BMCR_DUPLEX; 518 printf("(100baseT4)\n"); 519 } else if (advert & PHY_ANAR_100BTXFULL && 520 ability & PHY_ANAR_100BTXFULL) { 521 ifm->ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX; 522 media |= PHY_BMCR_SPEEDSEL; 523 media |= PHY_BMCR_DUPLEX; 524 printf("(full-duplex, 100Mbps)\n"); 525 } else if (advert & PHY_ANAR_100BTXHALF && 526 ability & PHY_ANAR_100BTXHALF) { 527 ifm->ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX; 528 media |= PHY_BMCR_SPEEDSEL; 529 media &= ~PHY_BMCR_DUPLEX; 530 printf("(half-duplex, 100Mbps)\n"); 531 } else if (advert & PHY_ANAR_10BTFULL && 532 ability & PHY_ANAR_10BTFULL) { 533 ifm->ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX; 534 media &= ~PHY_BMCR_SPEEDSEL; 535 media |= PHY_BMCR_DUPLEX; 536 printf("(full-duplex, 10Mbps)\n"); 537 } else if (advert) { 538 ifm->ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX; 539 media &= ~PHY_BMCR_SPEEDSEL; 540 media &= ~PHY_BMCR_DUPLEX; 541 printf("(half-duplex, 10Mbps)\n"); 542 } 543 media &= ~PHY_BMCR_AUTONEGENBL; 544 545 /* Set ASIC's duplex mode to match the PHY. */ 546 my_phy_writereg(sc, PHY_BMCR, media); 547 my_setcfg(sc, media); 548 } else { 549 if (verbose) 550 printf("my%d: no carrier\n", sc->my_unit); 551 } 552 553 my_init(sc); 554 if (sc->my_tx_pend) { 555 sc->my_autoneg = 0; 556 sc->my_tx_pend = 0; 557 my_start(ifp); 558 } 559 MY_UNLOCK(sc); 560 return; 561} 562 563/* 564 * To get PHY ability. 565 */ 566static void 567my_getmode_mii(struct my_softc * sc) 568{ 569 u_int16_t bmsr; 570 struct ifnet *ifp; 571 572 MY_LOCK(sc); 573 ifp = &sc->arpcom.ac_if; 574 bmsr = my_phy_readreg(sc, PHY_BMSR); 575 if (bootverbose) 576 printf("my%d: PHY status word: %x\n", sc->my_unit, bmsr); 577 578 /* fallback */ 579 sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX; 580 581 if (bmsr & PHY_BMSR_10BTHALF) { 582 if (bootverbose) 583 printf("my%d: 10Mbps half-duplex mode supported\n", 584 sc->my_unit); 585 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX, 586 0, NULL); 587 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL); 588 } 589 if (bmsr & PHY_BMSR_10BTFULL) { 590 if (bootverbose) 591 printf("my%d: 10Mbps full-duplex mode supported\n", 592 sc->my_unit); 593 594 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 595 0, NULL); 596 sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX; 597 } 598 if (bmsr & PHY_BMSR_100BTXHALF) { 599 if (bootverbose) 600 printf("my%d: 100Mbps half-duplex mode supported\n", 601 sc->my_unit); 602 ifp->if_baudrate = 100000000; 603 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL); 604 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX, 605 0, NULL); 606 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX; 607 } 608 if (bmsr & PHY_BMSR_100BTXFULL) { 609 if (bootverbose) 610 printf("my%d: 100Mbps full-duplex mode supported\n", 611 sc->my_unit); 612 ifp->if_baudrate = 100000000; 613 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 614 0, NULL); 615 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX; 616 } 617 /* Some also support 100BaseT4. */ 618 if (bmsr & PHY_BMSR_100BT4) { 619 if (bootverbose) 620 printf("my%d: 100baseT4 mode supported\n", sc->my_unit); 621 ifp->if_baudrate = 100000000; 622 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_T4, 0, NULL); 623 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_T4; 624#ifdef FORCE_AUTONEG_TFOUR 625 if (bootverbose) 626 printf("my%d: forcing on autoneg support for BT4\n", 627 sc->my_unit); 628 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0 NULL): 629 sc->ifmedia.ifm_media = IFM_ETHER | IFM_AUTO; 630#endif 631 } 632#if 0 /* this version did not support 1000M, */ 633 if (sc->my_pinfo->my_vid == MarvellPHYID0) { 634 if (bootverbose) 635 printf("my%d: 1000Mbps half-duplex mode supported\n", 636 sc->my_unit); 637 638 ifp->if_baudrate = 1000000000; 639 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_1000_T, 0, NULL); 640 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_1000_T | IFM_HDX, 641 0, NULL); 642 if (bootverbose) 643 printf("my%d: 1000Mbps full-duplex mode supported\n", 644 sc->my_unit); 645 ifp->if_baudrate = 1000000000; 646 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_1000_T | IFM_FDX, 647 0, NULL); 648 sc->ifmedia.ifm_media = IFM_ETHER | IFM_1000_T | IFM_FDX; 649 } 650#endif 651 if (bmsr & PHY_BMSR_CANAUTONEG) { 652 if (bootverbose) 653 printf("my%d: autoneg supported\n", sc->my_unit); 654 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); 655 sc->ifmedia.ifm_media = IFM_ETHER | IFM_AUTO; 656 } 657 MY_UNLOCK(sc); 658 return; 659} 660 661/* 662 * Set speed and duplex mode. 663 */ 664static void 665my_setmode_mii(struct my_softc * sc, int media) 666{ 667 u_int16_t bmcr; 668 struct ifnet *ifp; 669 670 MY_LOCK(sc); 671 ifp = &sc->arpcom.ac_if; 672 /* 673 * If an autoneg session is in progress, stop it. 674 */ 675 if (sc->my_autoneg) { 676 printf("my%d: canceling autoneg session\n", sc->my_unit); 677 ifp->if_timer = sc->my_autoneg = sc->my_want_auto = 0; 678 bmcr = my_phy_readreg(sc, PHY_BMCR); 679 bmcr &= ~PHY_BMCR_AUTONEGENBL; 680 my_phy_writereg(sc, PHY_BMCR, bmcr); 681 } 682 printf("my%d: selecting MII, ", sc->my_unit); 683 bmcr = my_phy_readreg(sc, PHY_BMCR); 684 bmcr &= ~(PHY_BMCR_AUTONEGENBL | PHY_BMCR_SPEEDSEL | PHY_BMCR_1000 | 685 PHY_BMCR_DUPLEX | PHY_BMCR_LOOPBK); 686 687#if 0 /* this version did not support 1000M, */ 688 if (IFM_SUBTYPE(media) == IFM_1000_T) { 689 printf("1000Mbps/T4, half-duplex\n"); 690 bmcr &= ~PHY_BMCR_SPEEDSEL; 691 bmcr &= ~PHY_BMCR_DUPLEX; 692 bmcr |= PHY_BMCR_1000; 693 } 694#endif 695 if (IFM_SUBTYPE(media) == IFM_100_T4) { 696 printf("100Mbps/T4, half-duplex\n"); 697 bmcr |= PHY_BMCR_SPEEDSEL; 698 bmcr &= ~PHY_BMCR_DUPLEX; 699 } 700 if (IFM_SUBTYPE(media) == IFM_100_TX) { 701 printf("100Mbps, "); 702 bmcr |= PHY_BMCR_SPEEDSEL; 703 } 704 if (IFM_SUBTYPE(media) == IFM_10_T) { 705 printf("10Mbps, "); 706 bmcr &= ~PHY_BMCR_SPEEDSEL; 707 } 708 if ((media & IFM_GMASK) == IFM_FDX) { 709 printf("full duplex\n"); 710 bmcr |= PHY_BMCR_DUPLEX; 711 } else { 712 printf("half duplex\n"); 713 bmcr &= ~PHY_BMCR_DUPLEX; 714 } 715 my_phy_writereg(sc, PHY_BMCR, bmcr); 716 my_setcfg(sc, bmcr); 717 MY_UNLOCK(sc); 718 return; 719} 720 721/* 722 * The Myson manual states that in order to fiddle with the 'full-duplex' and 723 * '100Mbps' bits in the netconfig register, we first have to put the 724 * transmit and/or receive logic in the idle state. 725 */ 726static void 727my_setcfg(struct my_softc * sc, int bmcr) 728{ 729 int i, restart = 0; 730 731 MY_LOCK(sc); 732 if (CSR_READ_4(sc, MY_TCRRCR) & (MY_TE | MY_RE)) { 733 restart = 1; 734 MY_CLRBIT(sc, MY_TCRRCR, (MY_TE | MY_RE)); 735 for (i = 0; i < MY_TIMEOUT; i++) { 736 DELAY(10); 737 if (!(CSR_READ_4(sc, MY_TCRRCR) & 738 (MY_TXRUN | MY_RXRUN))) 739 break; 740 } 741 if (i == MY_TIMEOUT) 742 printf("my%d: failed to force tx and rx to idle \n", 743 sc->my_unit); 744 } 745 MY_CLRBIT(sc, MY_TCRRCR, MY_PS1000); 746 MY_CLRBIT(sc, MY_TCRRCR, MY_PS10); 747 if (bmcr & PHY_BMCR_1000) 748 MY_SETBIT(sc, MY_TCRRCR, MY_PS1000); 749 else if (!(bmcr & PHY_BMCR_SPEEDSEL)) 750 MY_SETBIT(sc, MY_TCRRCR, MY_PS10); 751 if (bmcr & PHY_BMCR_DUPLEX) 752 MY_SETBIT(sc, MY_TCRRCR, MY_FD); 753 else 754 MY_CLRBIT(sc, MY_TCRRCR, MY_FD); 755 if (restart) 756 MY_SETBIT(sc, MY_TCRRCR, MY_TE | MY_RE); 757 MY_UNLOCK(sc); 758 return; 759} 760 761static void 762my_reset(struct my_softc * sc) 763{ 764 register int i; 765 766 MY_LOCK(sc); 767 MY_SETBIT(sc, MY_BCR, MY_SWR); 768 for (i = 0; i < MY_TIMEOUT; i++) { 769 DELAY(10); 770 if (!(CSR_READ_4(sc, MY_BCR) & MY_SWR)) 771 break; 772 } 773 if (i == MY_TIMEOUT) 774 printf("m0x%d: reset never completed!\n", sc->my_unit); 775 776 /* Wait a little while for the chip to get its brains in order. */ 777 DELAY(1000); 778 MY_UNLOCK(sc); 779 return; 780} 781 782/* 783 * Probe for a Myson chip. Check the PCI vendor and device IDs against our 784 * list and return a device name if we find a match. 785 */ 786static int 787my_probe(device_t dev) 788{ 789 struct my_type *t; 790 791 t = my_devs; 792 while (t->my_name != NULL) { 793 if ((pci_get_vendor(dev) == t->my_vid) && 794 (pci_get_device(dev) == t->my_did)) { 795 device_set_desc(dev, t->my_name); 796 my_info_tmp = t; 797 return (BUS_PROBE_DEFAULT); 798 } 799 t++; 800 } 801 return (ENXIO); 802} 803 804/* 805 * Attach the interface. Allocate softc structures, do ifmedia setup and 806 * ethernet/BPF attach. 807 */ 808static int 809my_attach(device_t dev) 810{ 811 int s, i; 812 u_char eaddr[ETHER_ADDR_LEN]; 813 u_int32_t command, iobase; 814 struct my_softc *sc; 815 struct ifnet *ifp; 816 int media = IFM_ETHER | IFM_100_TX | IFM_FDX; 817 unsigned int round; 818 caddr_t roundptr; 819 struct my_type *p; 820 u_int16_t phy_vid, phy_did, phy_sts = 0; 821 int rid, unit, error = 0; 822 823 s = splimp(); 824 sc = device_get_softc(dev); 825 unit = device_get_unit(dev); 826 if (sc == NULL) { 827 printf("my%d: no memory for softc struct!\n", unit); 828 error = ENXIO; 829 goto fail; 830 831 } 832 bzero(sc, sizeof(struct my_softc)); 833 mtx_init(&sc->my_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 834 MTX_DEF | MTX_RECURSE); 835 MY_LOCK(sc); 836 837 /* 838 * Map control/status registers. 839 */ 840#if 0 841 command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); 842 command |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 843 pci_write_config(dev, PCI_COMMAND_STATUS_REG, command & 0x000000ff, 4); 844 command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); 845#endif 846 command = pci_read_config(dev, PCIR_COMMAND, 4); 847 command |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 848 pci_write_config(dev, PCIR_COMMAND, command & 0x000000ff, 4); 849 command = pci_read_config(dev, PCIR_COMMAND, 4); 850 851 if (my_info_tmp->my_did == MTD800ID) { 852 iobase = pci_read_config(dev, MY_PCI_LOIO, 4); 853 if (iobase & 0x300) 854 MY_USEIOSPACE = 0; 855 } 856 if (MY_USEIOSPACE) { 857 if (!(command & PCIM_CMD_PORTEN)) { 858 printf("my%d: failed to enable I/O ports!\n", unit); 859 free(sc, M_DEVBUF); 860 error = ENXIO; 861 goto fail; 862 } 863#if 0 864 if (!pci_map_port(config_id, MY_PCI_LOIO, (u_int16_t *) & (sc->my_bhandle))) { 865 printf("my%d: couldn't map ports\n", unit); 866 error = ENXIO; 867 goto fail; 868 } 869 870 sc->my_btag = I386_BUS_SPACE_IO; 871#endif 872 } else { 873 if (!(command & PCIM_CMD_MEMEN)) { 874 printf("my%d: failed to enable memory mapping!\n", 875 unit); 876 error = ENXIO; 877 goto fail; 878 } 879#if 0 880 if (!pci_map_mem(config_id, MY_PCI_LOMEM, &vbase, &pbase)) { 881 printf ("my%d: couldn't map memory\n", unit); 882 error = ENXIO; 883 goto fail; 884 } 885 sc->my_btag = I386_BUS_SPACE_MEM; 886 sc->my_bhandle = vbase; 887#endif 888 } 889 890 rid = MY_RID; 891 sc->my_res = bus_alloc_resource_any(dev, MY_RES, &rid, RF_ACTIVE); 892 893 if (sc->my_res == NULL) { 894 printf("my%d: couldn't map ports/memory\n", unit); 895 error = ENXIO; 896 goto fail; 897 } 898 sc->my_btag = rman_get_bustag(sc->my_res); 899 sc->my_bhandle = rman_get_bushandle(sc->my_res); 900 901 rid = 0; 902 sc->my_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 903 RF_SHAREABLE | RF_ACTIVE); 904 905 if (sc->my_irq == NULL) { 906 printf("my%d: couldn't map interrupt\n", unit); 907 bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); 908 error = ENXIO; 909 goto fail; 910 } 911 error = bus_setup_intr(dev, sc->my_irq, INTR_TYPE_NET, 912 my_intr, sc, &sc->my_intrhand); 913 914 if (error) { 915 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->my_irq); 916 bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); 917 printf("my%d: couldn't set up irq\n", unit); 918 goto fail; 919 } 920 callout_handle_init(&sc->my_stat_ch); 921 922 sc->my_info = my_info_tmp; 923 924 /* Reset the adapter. */ 925 my_reset(sc); 926 927 /* 928 * Get station address 929 */ 930 for (i = 0; i < ETHER_ADDR_LEN; ++i) 931 eaddr[i] = CSR_READ_1(sc, MY_PAR0 + i); 932 933 sc->my_unit = unit; 934 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 935 936 sc->my_ldata_ptr = malloc(sizeof(struct my_list_data) + 8, 937 M_DEVBUF, M_NOWAIT); 938 if (sc->my_ldata_ptr == NULL) { 939 free(sc, M_DEVBUF); 940 printf("my%d: no memory for list buffers!\n", unit); 941 error = ENXIO; 942 goto fail; 943 } 944 sc->my_ldata = (struct my_list_data *) sc->my_ldata_ptr; 945 round = (uintptr_t)sc->my_ldata_ptr & 0xF; 946 roundptr = sc->my_ldata_ptr; 947 for (i = 0; i < 8; i++) { 948 if (round % 8) { 949 round++; 950 roundptr++; 951 } else 952 break; 953 } 954 sc->my_ldata = (struct my_list_data *) roundptr; 955 bzero(sc->my_ldata, sizeof(struct my_list_data)); 956 957 ifp = &sc->arpcom.ac_if; 958 ifp->if_softc = sc; 959 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 960 ifp->if_mtu = ETHERMTU; 961 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 962 ifp->if_ioctl = my_ioctl; 963 ifp->if_start = my_start; 964 ifp->if_watchdog = my_watchdog; 965 ifp->if_init = my_init; 966 ifp->if_baudrate = 10000000; 967 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 968 969 if (sc->my_info->my_did == MTD803ID) 970 sc->my_pinfo = my_phys; 971 else { 972 if (bootverbose) 973 printf("my%d: probing for a PHY\n", sc->my_unit); 974 for (i = MY_PHYADDR_MIN; i < MY_PHYADDR_MAX + 1; i++) { 975 if (bootverbose) 976 printf("my%d: checking address: %d\n", 977 sc->my_unit, i); 978 sc->my_phy_addr = i; 979 phy_sts = my_phy_readreg(sc, PHY_BMSR); 980 if ((phy_sts != 0) && (phy_sts != 0xffff)) 981 break; 982 else 983 phy_sts = 0; 984 } 985 if (phy_sts) { 986 phy_vid = my_phy_readreg(sc, PHY_VENID); 987 phy_did = my_phy_readreg(sc, PHY_DEVID); 988 if (bootverbose) { 989 printf("my%d: found PHY at address %d, ", 990 sc->my_unit, sc->my_phy_addr); 991 printf("vendor id: %x device id: %x\n", 992 phy_vid, phy_did); 993 } 994 p = my_phys; 995 while (p->my_vid) { 996 if (phy_vid == p->my_vid) { 997 sc->my_pinfo = p; 998 break; 999 } 1000 p++; 1001 } 1002 if (sc->my_pinfo == NULL) 1003 sc->my_pinfo = &my_phys[PHY_UNKNOWN]; 1004 if (bootverbose) 1005 printf("my%d: PHY type: %s\n", 1006 sc->my_unit, sc->my_pinfo->my_name); 1007 } else { 1008 printf("my%d: MII without any phy!\n", sc->my_unit); 1009 error = ENXIO; 1010 goto fail; 1011 } 1012 } 1013 1014 /* Do ifmedia setup. */ 1015 ifmedia_init(&sc->ifmedia, 0, my_ifmedia_upd, my_ifmedia_sts); 1016 my_getmode_mii(sc); 1017 my_autoneg_mii(sc, MY_FLAG_FORCEDELAY, 1); 1018 media = sc->ifmedia.ifm_media; 1019 my_stop(sc); 1020 ifmedia_set(&sc->ifmedia, media); 1021 1022 ether_ifattach(ifp, eaddr); 1023 1024#if 0 1025 at_shutdown(my_shutdown, sc, SHUTDOWN_POST_SYNC); 1026 shutdownhook_establish(my_shutdown, sc); 1027#endif 1028 1029 MY_UNLOCK(sc); 1030 return (0); 1031 1032fail: 1033 MY_UNLOCK(sc); 1034 mtx_destroy(&sc->my_mtx); 1035 splx(s); 1036 return (error); 1037} 1038 1039static int 1040my_detach(device_t dev) 1041{ 1042 struct my_softc *sc; 1043 struct ifnet *ifp; 1044 int s; 1045 1046 s = splimp(); 1047 sc = device_get_softc(dev); 1048 MY_LOCK(sc); 1049 ifp = &sc->arpcom.ac_if; 1050 ether_ifdetach(ifp); 1051 my_stop(sc); 1052 1053#if 0 1054 bus_generic_detach(dev); 1055 device_delete_child(dev, sc->rl_miibus); 1056#endif 1057 1058 bus_teardown_intr(dev, sc->my_irq, sc->my_intrhand); 1059 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->my_irq); 1060 bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); 1061#if 0 1062 contigfree(sc->my_cdata.my_rx_buf, MY_RXBUFLEN + 32, M_DEVBUF); 1063#endif 1064 free(sc, M_DEVBUF); 1065 MY_UNLOCK(sc); 1066 splx(s); 1067 mtx_destroy(&sc->my_mtx); 1068 return (0); 1069} 1070 1071 1072/* 1073 * Initialize the transmit descriptors. 1074 */ 1075static int 1076my_list_tx_init(struct my_softc * sc) 1077{ 1078 struct my_chain_data *cd; 1079 struct my_list_data *ld; 1080 int i; 1081 1082 MY_LOCK(sc); 1083 cd = &sc->my_cdata; 1084 ld = sc->my_ldata; 1085 for (i = 0; i < MY_TX_LIST_CNT; i++) { 1086 cd->my_tx_chain[i].my_ptr = &ld->my_tx_list[i]; 1087 if (i == (MY_TX_LIST_CNT - 1)) 1088 cd->my_tx_chain[i].my_nextdesc = &cd->my_tx_chain[0]; 1089 else 1090 cd->my_tx_chain[i].my_nextdesc = 1091 &cd->my_tx_chain[i + 1]; 1092 } 1093 cd->my_tx_free = &cd->my_tx_chain[0]; 1094 cd->my_tx_tail = cd->my_tx_head = NULL; 1095 MY_UNLOCK(sc); 1096 return (0); 1097} 1098 1099/* 1100 * Initialize the RX descriptors and allocate mbufs for them. Note that we 1101 * arrange the descriptors in a closed ring, so that the last descriptor 1102 * points back to the first. 1103 */ 1104static int 1105my_list_rx_init(struct my_softc * sc) 1106{ 1107 struct my_chain_data *cd; 1108 struct my_list_data *ld; 1109 int i; 1110 1111 MY_LOCK(sc); 1112 cd = &sc->my_cdata; 1113 ld = sc->my_ldata; 1114 for (i = 0; i < MY_RX_LIST_CNT; i++) { 1115 cd->my_rx_chain[i].my_ptr = 1116 (struct my_desc *) & ld->my_rx_list[i]; 1117 if (my_newbuf(sc, &cd->my_rx_chain[i]) == ENOBUFS) { 1118 MY_UNLOCK(sc); 1119 return (ENOBUFS); 1120 } 1121 if (i == (MY_RX_LIST_CNT - 1)) { 1122 cd->my_rx_chain[i].my_nextdesc = &cd->my_rx_chain[0]; 1123 ld->my_rx_list[i].my_next = vtophys(&ld->my_rx_list[0]); 1124 } else { 1125 cd->my_rx_chain[i].my_nextdesc = 1126 &cd->my_rx_chain[i + 1]; 1127 ld->my_rx_list[i].my_next = 1128 vtophys(&ld->my_rx_list[i + 1]); 1129 } 1130 } 1131 cd->my_rx_head = &cd->my_rx_chain[0]; 1132 MY_UNLOCK(sc); 1133 return (0); 1134} 1135 1136/* 1137 * Initialize an RX descriptor and attach an MBUF cluster. 1138 */ 1139static int 1140my_newbuf(struct my_softc * sc, struct my_chain_onefrag * c) 1141{ 1142 struct mbuf *m_new = NULL; 1143 1144 MY_LOCK(sc); 1145 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1146 if (m_new == NULL) { 1147 printf("my%d: no memory for rx list -- packet dropped!\n", 1148 sc->my_unit); 1149 MY_UNLOCK(sc); 1150 return (ENOBUFS); 1151 } 1152 MCLGET(m_new, M_DONTWAIT); 1153 if (!(m_new->m_flags & M_EXT)) { 1154 printf("my%d: no memory for rx list -- packet dropped!\n", 1155 sc->my_unit); 1156 m_freem(m_new); 1157 MY_UNLOCK(sc); 1158 return (ENOBUFS); 1159 } 1160 c->my_mbuf = m_new; 1161 c->my_ptr->my_data = vtophys(mtod(m_new, caddr_t)); 1162 c->my_ptr->my_ctl = (MCLBYTES - 1) << MY_RBSShift; 1163 c->my_ptr->my_status = MY_OWNByNIC; 1164 MY_UNLOCK(sc); 1165 return (0); 1166} 1167 1168/* 1169 * A frame has been uploaded: pass the resulting mbuf chain up to the higher 1170 * level protocols. 1171 */ 1172static void 1173my_rxeof(struct my_softc * sc) 1174{ 1175 struct ether_header *eh; 1176 struct mbuf *m; 1177 struct ifnet *ifp; 1178 struct my_chain_onefrag *cur_rx; 1179 int total_len = 0; 1180 u_int32_t rxstat; 1181 1182 MY_LOCK(sc); 1183 ifp = &sc->arpcom.ac_if; 1184 while (!((rxstat = sc->my_cdata.my_rx_head->my_ptr->my_status) 1185 & MY_OWNByNIC)) { 1186 cur_rx = sc->my_cdata.my_rx_head; 1187 sc->my_cdata.my_rx_head = cur_rx->my_nextdesc; 1188 1189 if (rxstat & MY_ES) { /* error summary: give up this rx pkt */ 1190 ifp->if_ierrors++; 1191 cur_rx->my_ptr->my_status = MY_OWNByNIC; 1192 continue; 1193 } 1194 /* No errors; receive the packet. */ 1195 total_len = (rxstat & MY_FLNGMASK) >> MY_FLNGShift; 1196 total_len -= ETHER_CRC_LEN; 1197 1198 if (total_len < MINCLSIZE) { 1199 m = m_devget(mtod(cur_rx->my_mbuf, char *), 1200 total_len, 0, ifp, NULL); 1201 cur_rx->my_ptr->my_status = MY_OWNByNIC; 1202 if (m == NULL) { 1203 ifp->if_ierrors++; 1204 continue; 1205 } 1206 } else { 1207 m = cur_rx->my_mbuf; 1208 /* 1209 * Try to conjure up a new mbuf cluster. If that 1210 * fails, it means we have an out of memory condition 1211 * and should leave the buffer in place and continue. 1212 * This will result in a lost packet, but there's 1213 * little else we can do in this situation. 1214 */ 1215 if (my_newbuf(sc, cur_rx) == ENOBUFS) { 1216 ifp->if_ierrors++; 1217 cur_rx->my_ptr->my_status = MY_OWNByNIC; 1218 continue; 1219 } 1220 m->m_pkthdr.rcvif = ifp; 1221 m->m_pkthdr.len = m->m_len = total_len; 1222 } 1223 ifp->if_ipackets++; 1224 eh = mtod(m, struct ether_header *); 1225#if NBPFILTER > 0 1226 /* 1227 * Handle BPF listeners. Let the BPF user see the packet, but 1228 * don't pass it up to the ether_input() layer unless it's a 1229 * broadcast packet, multicast packet, matches our ethernet 1230 * address or the interface is in promiscuous mode. 1231 */ 1232 if (ifp->if_bpf) { 1233 BPF_MTAP(ifp, m); 1234 if (ifp->if_flags & IFF_PROMISC && 1235 (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, 1236 ETHER_ADDR_LEN) && 1237 (eh->ether_dhost[0] & 1) == 0)) { 1238 m_freem(m); 1239 continue; 1240 } 1241 } 1242#endif 1243 MY_UNLOCK(sc); 1244 (*ifp->if_input)(ifp, m); 1245 MY_LOCK(sc); 1246 } 1247 MY_UNLOCK(sc); 1248 return; 1249} 1250 1251 1252/* 1253 * A frame was downloaded to the chip. It's safe for us to clean up the list 1254 * buffers. 1255 */ 1256static void 1257my_txeof(struct my_softc * sc) 1258{ 1259 struct my_chain *cur_tx; 1260 struct ifnet *ifp; 1261 1262 MY_LOCK(sc); 1263 ifp = &sc->arpcom.ac_if; 1264 /* Clear the timeout timer. */ 1265 ifp->if_timer = 0; 1266 if (sc->my_cdata.my_tx_head == NULL) { 1267 MY_UNLOCK(sc); 1268 return; 1269 } 1270 /* 1271 * Go through our tx list and free mbufs for those frames that have 1272 * been transmitted. 1273 */ 1274 while (sc->my_cdata.my_tx_head->my_mbuf != NULL) { 1275 u_int32_t txstat; 1276 1277 cur_tx = sc->my_cdata.my_tx_head; 1278 txstat = MY_TXSTATUS(cur_tx); 1279 if ((txstat & MY_OWNByNIC) || txstat == MY_UNSENT) 1280 break; 1281 if (!(CSR_READ_4(sc, MY_TCRRCR) & MY_Enhanced)) { 1282 if (txstat & MY_TXERR) { 1283 ifp->if_oerrors++; 1284 if (txstat & MY_EC) /* excessive collision */ 1285 ifp->if_collisions++; 1286 if (txstat & MY_LC) /* late collision */ 1287 ifp->if_collisions++; 1288 } 1289 ifp->if_collisions += (txstat & MY_NCRMASK) >> 1290 MY_NCRShift; 1291 } 1292 ifp->if_opackets++; 1293 m_freem(cur_tx->my_mbuf); 1294 cur_tx->my_mbuf = NULL; 1295 if (sc->my_cdata.my_tx_head == sc->my_cdata.my_tx_tail) { 1296 sc->my_cdata.my_tx_head = NULL; 1297 sc->my_cdata.my_tx_tail = NULL; 1298 break; 1299 } 1300 sc->my_cdata.my_tx_head = cur_tx->my_nextdesc; 1301 } 1302 if (CSR_READ_4(sc, MY_TCRRCR) & MY_Enhanced) { 1303 ifp->if_collisions += (CSR_READ_4(sc, MY_TSR) & MY_NCRMask); 1304 } 1305 MY_UNLOCK(sc); 1306 return; 1307} 1308 1309/* 1310 * TX 'end of channel' interrupt handler. 1311 */ 1312static void 1313my_txeoc(struct my_softc * sc) 1314{ 1315 struct ifnet *ifp; 1316 1317 MY_LOCK(sc); 1318 ifp = &sc->arpcom.ac_if; 1319 ifp->if_timer = 0; 1320 if (sc->my_cdata.my_tx_head == NULL) { 1321 ifp->if_flags &= ~IFF_OACTIVE; 1322 sc->my_cdata.my_tx_tail = NULL; 1323 if (sc->my_want_auto) 1324 my_autoneg_mii(sc, MY_FLAG_SCHEDDELAY, 1); 1325 } else { 1326 if (MY_TXOWN(sc->my_cdata.my_tx_head) == MY_UNSENT) { 1327 MY_TXOWN(sc->my_cdata.my_tx_head) = MY_OWNByNIC; 1328 ifp->if_timer = 5; 1329 CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF); 1330 } 1331 } 1332 MY_UNLOCK(sc); 1333 return; 1334} 1335 1336static void 1337my_intr(void *arg) 1338{ 1339 struct my_softc *sc; 1340 struct ifnet *ifp; 1341 u_int32_t status; 1342 1343 sc = arg; 1344 MY_LOCK(sc); 1345 ifp = &sc->arpcom.ac_if; 1346 if (!(ifp->if_flags & IFF_UP)) { 1347 MY_UNLOCK(sc); 1348 return; 1349 } 1350 /* Disable interrupts. */ 1351 CSR_WRITE_4(sc, MY_IMR, 0x00000000); 1352 1353 for (;;) { 1354 status = CSR_READ_4(sc, MY_ISR); 1355 status &= MY_INTRS; 1356 if (status) 1357 CSR_WRITE_4(sc, MY_ISR, status); 1358 else 1359 break; 1360 1361 if (status & MY_RI) /* receive interrupt */ 1362 my_rxeof(sc); 1363 1364 if ((status & MY_RBU) || (status & MY_RxErr)) { 1365 /* rx buffer unavailable or rx error */ 1366 ifp->if_ierrors++; 1367#ifdef foo 1368 my_stop(sc); 1369 my_reset(sc); 1370 my_init(sc); 1371#endif 1372 } 1373 if (status & MY_TI) /* tx interrupt */ 1374 my_txeof(sc); 1375 if (status & MY_ETI) /* tx early interrupt */ 1376 my_txeof(sc); 1377 if (status & MY_TBU) /* tx buffer unavailable */ 1378 my_txeoc(sc); 1379 1380#if 0 /* 90/1/18 delete */ 1381 if (status & MY_FBE) { 1382 my_reset(sc); 1383 my_init(sc); 1384 } 1385#endif 1386 1387 } 1388 1389 /* Re-enable interrupts. */ 1390 CSR_WRITE_4(sc, MY_IMR, MY_INTRS); 1391 if (ifp->if_snd.ifq_head != NULL) 1392 my_start(ifp); 1393 MY_UNLOCK(sc); 1394 return; 1395} 1396 1397/* 1398 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 1399 * pointers to the fragment pointers. 1400 */ 1401static int 1402my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head) 1403{ 1404 struct my_desc *f = NULL; 1405 int total_len; 1406 struct mbuf *m, *m_new = NULL; 1407 1408 MY_LOCK(sc); 1409 /* calculate the total tx pkt length */ 1410 total_len = 0; 1411 for (m = m_head; m != NULL; m = m->m_next) 1412 total_len += m->m_len; 1413 /* 1414 * Start packing the mbufs in this chain into the fragment pointers. 1415 * Stop when we run out of fragments or hit the end of the mbuf 1416 * chain. 1417 */ 1418 m = m_head; 1419 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1420 if (m_new == NULL) { 1421 printf("my%d: no memory for tx list", sc->my_unit); 1422 MY_UNLOCK(sc); 1423 return (1); 1424 } 1425 if (m_head->m_pkthdr.len > MHLEN) { 1426 MCLGET(m_new, M_DONTWAIT); 1427 if (!(m_new->m_flags & M_EXT)) { 1428 m_freem(m_new); 1429 printf("my%d: no memory for tx list", sc->my_unit); 1430 MY_UNLOCK(sc); 1431 return (1); 1432 } 1433 } 1434 m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t)); 1435 m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len; 1436 m_freem(m_head); 1437 m_head = m_new; 1438 f = &c->my_ptr->my_frag[0]; 1439 f->my_status = 0; 1440 f->my_data = vtophys(mtod(m_new, caddr_t)); 1441 total_len = m_new->m_len; 1442 f->my_ctl = MY_TXFD | MY_TXLD | MY_CRCEnable | MY_PADEnable; 1443 f->my_ctl |= total_len << MY_PKTShift; /* pkt size */ 1444 f->my_ctl |= total_len; /* buffer size */ 1445 /* 89/12/29 add, for mtd891 *//* [ 89? ] */ 1446 if (sc->my_info->my_did == MTD891ID) 1447 f->my_ctl |= MY_ETIControl | MY_RetryTxLC; 1448 c->my_mbuf = m_head; 1449 c->my_lastdesc = 0; 1450 MY_TXNEXT(c) = vtophys(&c->my_nextdesc->my_ptr->my_frag[0]); 1451 MY_UNLOCK(sc); 1452 return (0); 1453} 1454 1455/* 1456 * Main transmit routine. To avoid having to do mbuf copies, we put pointers 1457 * to the mbuf data regions directly in the transmit lists. We also save a 1458 * copy of the pointers since the transmit list fragment pointers are 1459 * physical addresses. 1460 */ 1461static void 1462my_start(struct ifnet * ifp) 1463{ 1464 struct my_softc *sc; 1465 struct mbuf *m_head = NULL; 1466 struct my_chain *cur_tx = NULL, *start_tx; 1467 1468 sc = ifp->if_softc; 1469 MY_LOCK(sc); 1470 if (sc->my_autoneg) { 1471 sc->my_tx_pend = 1; 1472 MY_UNLOCK(sc); 1473 return; 1474 } 1475 /* 1476 * Check for an available queue slot. If there are none, punt. 1477 */ 1478 if (sc->my_cdata.my_tx_free->my_mbuf != NULL) { 1479 ifp->if_flags |= IFF_OACTIVE; 1480 MY_UNLOCK(sc); 1481 return; 1482 } 1483 start_tx = sc->my_cdata.my_tx_free; 1484 while (sc->my_cdata.my_tx_free->my_mbuf == NULL) { 1485 IF_DEQUEUE(&ifp->if_snd, m_head); 1486 if (m_head == NULL) 1487 break; 1488 1489 /* Pick a descriptor off the free list. */ 1490 cur_tx = sc->my_cdata.my_tx_free; 1491 sc->my_cdata.my_tx_free = cur_tx->my_nextdesc; 1492 1493 /* Pack the data into the descriptor. */ 1494 my_encap(sc, cur_tx, m_head); 1495 1496 if (cur_tx != start_tx) 1497 MY_TXOWN(cur_tx) = MY_OWNByNIC; 1498#if NBPFILTER > 0 1499 /* 1500 * If there's a BPF listener, bounce a copy of this frame to 1501 * him. 1502 */ 1503 BPF_MTAP(ifp, cur_tx->my_mbuf); 1504#endif 1505 } 1506 /* 1507 * If there are no packets queued, bail. 1508 */ 1509 if (cur_tx == NULL) { 1510 MY_UNLOCK(sc); 1511 return; 1512 } 1513 /* 1514 * Place the request for the upload interrupt in the last descriptor 1515 * in the chain. This way, if we're chaining several packets at once, 1516 * we'll only get an interupt once for the whole chain rather than 1517 * once for each packet. 1518 */ 1519 MY_TXCTL(cur_tx) |= MY_TXIC; 1520 cur_tx->my_ptr->my_frag[0].my_ctl |= MY_TXIC; 1521 sc->my_cdata.my_tx_tail = cur_tx; 1522 if (sc->my_cdata.my_tx_head == NULL) 1523 sc->my_cdata.my_tx_head = start_tx; 1524 MY_TXOWN(start_tx) = MY_OWNByNIC; 1525 CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF); /* tx polling demand */ 1526 1527 /* 1528 * Set a timeout in case the chip goes out to lunch. 1529 */ 1530 ifp->if_timer = 5; 1531 MY_UNLOCK(sc); 1532 return; 1533} 1534 1535static void 1536my_init(void *xsc) 1537{ 1538 struct my_softc *sc = xsc; 1539 struct ifnet *ifp = &sc->arpcom.ac_if; 1540 int s; 1541 u_int16_t phy_bmcr = 0; 1542 1543 MY_LOCK(sc); 1544 if (sc->my_autoneg) { 1545 MY_UNLOCK(sc); 1546 return; 1547 } 1548 s = splimp(); 1549 if (sc->my_pinfo != NULL) 1550 phy_bmcr = my_phy_readreg(sc, PHY_BMCR); 1551 /* 1552 * Cancel pending I/O and free all RX/TX buffers. 1553 */ 1554 my_stop(sc); 1555 my_reset(sc); 1556 1557 /* 1558 * Set cache alignment and burst length. 1559 */ 1560#if 0 /* 89/9/1 modify, */ 1561 CSR_WRITE_4(sc, MY_BCR, MY_RPBLE512); 1562 CSR_WRITE_4(sc, MY_TCRRCR, MY_TFTSF); 1563#endif 1564 CSR_WRITE_4(sc, MY_BCR, MY_PBL8); 1565 CSR_WRITE_4(sc, MY_TCRRCR, MY_TFTSF | MY_RBLEN | MY_RPBLE512); 1566 /* 1567 * 89/12/29 add, for mtd891, 1568 */ 1569 if (sc->my_info->my_did == MTD891ID) { 1570 MY_SETBIT(sc, MY_BCR, MY_PROG); 1571 MY_SETBIT(sc, MY_TCRRCR, MY_Enhanced); 1572 } 1573 my_setcfg(sc, phy_bmcr); 1574 /* Init circular RX list. */ 1575 if (my_list_rx_init(sc) == ENOBUFS) { 1576 printf("my%d: init failed: no memory for rx buffers\n", 1577 sc->my_unit); 1578 my_stop(sc); 1579 (void)splx(s); 1580 MY_UNLOCK(sc); 1581 return; 1582 } 1583 /* Init TX descriptors. */ 1584 my_list_tx_init(sc); 1585 1586 /* If we want promiscuous mode, set the allframes bit. */ 1587 if (ifp->if_flags & IFF_PROMISC) 1588 MY_SETBIT(sc, MY_TCRRCR, MY_PROM); 1589 else 1590 MY_CLRBIT(sc, MY_TCRRCR, MY_PROM); 1591 1592 /* 1593 * Set capture broadcast bit to capture broadcast frames. 1594 */ 1595 if (ifp->if_flags & IFF_BROADCAST) 1596 MY_SETBIT(sc, MY_TCRRCR, MY_AB); 1597 else 1598 MY_CLRBIT(sc, MY_TCRRCR, MY_AB); 1599 1600 /* 1601 * Program the multicast filter, if necessary. 1602 */ 1603 my_setmulti(sc); 1604 1605 /* 1606 * Load the address of the RX list. 1607 */ 1608 MY_CLRBIT(sc, MY_TCRRCR, MY_RE); 1609 CSR_WRITE_4(sc, MY_RXLBA, vtophys(&sc->my_ldata->my_rx_list[0])); 1610 1611 /* 1612 * Enable interrupts. 1613 */ 1614 CSR_WRITE_4(sc, MY_IMR, MY_INTRS); 1615 CSR_WRITE_4(sc, MY_ISR, 0xFFFFFFFF); 1616 1617 /* Enable receiver and transmitter. */ 1618 MY_SETBIT(sc, MY_TCRRCR, MY_RE); 1619 MY_CLRBIT(sc, MY_TCRRCR, MY_TE); 1620 CSR_WRITE_4(sc, MY_TXLBA, vtophys(&sc->my_ldata->my_tx_list[0])); 1621 MY_SETBIT(sc, MY_TCRRCR, MY_TE); 1622 1623 /* Restore state of BMCR */ 1624 if (sc->my_pinfo != NULL) 1625 my_phy_writereg(sc, PHY_BMCR, phy_bmcr); 1626 ifp->if_flags |= IFF_RUNNING; 1627 ifp->if_flags &= ~IFF_OACTIVE; 1628 (void)splx(s); 1629 MY_UNLOCK(sc); 1630 return; 1631} 1632 1633/* 1634 * Set media options. 1635 */ 1636 1637static int 1638my_ifmedia_upd(struct ifnet * ifp) 1639{ 1640 struct my_softc *sc; 1641 struct ifmedia *ifm; 1642 1643 sc = ifp->if_softc; 1644 MY_LOCK(sc); 1645 ifm = &sc->ifmedia; 1646 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) { 1647 MY_UNLOCK(sc); 1648 return (EINVAL); 1649 } 1650 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) 1651 my_autoneg_mii(sc, MY_FLAG_SCHEDDELAY, 1); 1652 else 1653 my_setmode_mii(sc, ifm->ifm_media); 1654 MY_UNLOCK(sc); 1655 return (0); 1656} 1657 1658/* 1659 * Report current media status. 1660 */ 1661 1662static void 1663my_ifmedia_sts(struct ifnet * ifp, struct ifmediareq * ifmr) 1664{ 1665 struct my_softc *sc; 1666 u_int16_t advert = 0, ability = 0; 1667 1668 sc = ifp->if_softc; 1669 MY_LOCK(sc); 1670 ifmr->ifm_active = IFM_ETHER; 1671 if (!(my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_AUTONEGENBL)) { 1672#if 0 /* this version did not support 1000M, */ 1673 if (my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_1000) 1674 ifmr->ifm_active = IFM_ETHER | IFM_1000TX; 1675#endif 1676 if (my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL) 1677 ifmr->ifm_active = IFM_ETHER | IFM_100_TX; 1678 else 1679 ifmr->ifm_active = IFM_ETHER | IFM_10_T; 1680 if (my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_DUPLEX) 1681 ifmr->ifm_active |= IFM_FDX; 1682 else 1683 ifmr->ifm_active |= IFM_HDX; 1684 1685 MY_UNLOCK(sc); 1686 return; 1687 } 1688 ability = my_phy_readreg(sc, PHY_LPAR); 1689 advert = my_phy_readreg(sc, PHY_ANAR); 1690 1691#if 0 /* this version did not support 1000M, */ 1692 if (sc->my_pinfo->my_vid = MarvellPHYID0) { 1693 ability2 = my_phy_readreg(sc, PHY_1000SR); 1694 if (ability2 & PHY_1000SR_1000BTXFULL) { 1695 advert = 0; 1696 ability = 0; 1697 ifmr->ifm_active = IFM_ETHER|IFM_1000_T|IFM_FDX; 1698 } else if (ability & PHY_1000SR_1000BTXHALF) { 1699 advert = 0; 1700 ability = 0; 1701 ifmr->ifm_active = IFM_ETHER|IFM_1000_T|IFM_HDX; 1702 } 1703 } 1704#endif 1705 if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) 1706 ifmr->ifm_active = IFM_ETHER | IFM_100_T4; 1707 else if (advert & PHY_ANAR_100BTXFULL && ability & PHY_ANAR_100BTXFULL) 1708 ifmr->ifm_active = IFM_ETHER | IFM_100_TX | IFM_FDX; 1709 else if (advert & PHY_ANAR_100BTXHALF && ability & PHY_ANAR_100BTXHALF) 1710 ifmr->ifm_active = IFM_ETHER | IFM_100_TX | IFM_HDX; 1711 else if (advert & PHY_ANAR_10BTFULL && ability & PHY_ANAR_10BTFULL) 1712 ifmr->ifm_active = IFM_ETHER | IFM_10_T | IFM_FDX; 1713 else if (advert & PHY_ANAR_10BTHALF && ability & PHY_ANAR_10BTHALF) 1714 ifmr->ifm_active = IFM_ETHER | IFM_10_T | IFM_HDX; 1715 MY_UNLOCK(sc); 1716 return; 1717} 1718 1719static int 1720my_ioctl(struct ifnet * ifp, u_long command, caddr_t data) 1721{ 1722 struct my_softc *sc = ifp->if_softc; 1723 struct ifreq *ifr = (struct ifreq *) data; 1724 int s, error = 0; 1725 1726 s = splimp(); 1727 MY_LOCK(sc); 1728 switch (command) { 1729 case SIOCSIFFLAGS: 1730 if (ifp->if_flags & IFF_UP) 1731 my_init(sc); 1732 else if (ifp->if_flags & IFF_RUNNING) 1733 my_stop(sc); 1734 error = 0; 1735 break; 1736 case SIOCADDMULTI: 1737 case SIOCDELMULTI: 1738 my_setmulti(sc); 1739 error = 0; 1740 break; 1741 case SIOCGIFMEDIA: 1742 case SIOCSIFMEDIA: 1743 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); 1744 break; 1745 default: 1746 error = ether_ioctl(ifp, command, data); 1747 break; 1748 } 1749 MY_UNLOCK(sc); 1750 (void)splx(s); 1751 return (error); 1752} 1753 1754static void 1755my_watchdog(struct ifnet * ifp) 1756{ 1757 struct my_softc *sc; 1758 1759 sc = ifp->if_softc; 1760 MY_LOCK(sc); 1761 if (sc->my_autoneg) { 1762 my_autoneg_mii(sc, MY_FLAG_DELAYTIMEO, 1); 1763 MY_UNLOCK(sc); 1764 return; 1765 } 1766 ifp->if_oerrors++; 1767 printf("my%d: watchdog timeout\n", sc->my_unit); 1768 if (!(my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) 1769 printf("my%d: no carrier - transceiver cable problem?\n", 1770 sc->my_unit); 1771 my_stop(sc); 1772 my_reset(sc); 1773 my_init(sc); 1774 if (ifp->if_snd.ifq_head != NULL) 1775 my_start(ifp); 1776 MY_LOCK(sc); 1777 return; 1778} 1779 1780 1781/* 1782 * Stop the adapter and free any mbufs allocated to the RX and TX lists. 1783 */ 1784static void 1785my_stop(struct my_softc * sc) 1786{ 1787 register int i; 1788 struct ifnet *ifp; 1789 1790 MY_LOCK(sc); 1791 ifp = &sc->arpcom.ac_if; 1792 ifp->if_timer = 0; 1793 1794 MY_CLRBIT(sc, MY_TCRRCR, (MY_RE | MY_TE)); 1795 CSR_WRITE_4(sc, MY_IMR, 0x00000000); 1796 CSR_WRITE_4(sc, MY_TXLBA, 0x00000000); 1797 CSR_WRITE_4(sc, MY_RXLBA, 0x00000000); 1798 1799 /* 1800 * Free data in the RX lists. 1801 */ 1802 for (i = 0; i < MY_RX_LIST_CNT; i++) { 1803 if (sc->my_cdata.my_rx_chain[i].my_mbuf != NULL) { 1804 m_freem(sc->my_cdata.my_rx_chain[i].my_mbuf); 1805 sc->my_cdata.my_rx_chain[i].my_mbuf = NULL; 1806 } 1807 } 1808 bzero((char *)&sc->my_ldata->my_rx_list, 1809 sizeof(sc->my_ldata->my_rx_list)); 1810 /* 1811 * Free the TX list buffers. 1812 */ 1813 for (i = 0; i < MY_TX_LIST_CNT; i++) { 1814 if (sc->my_cdata.my_tx_chain[i].my_mbuf != NULL) { 1815 m_freem(sc->my_cdata.my_tx_chain[i].my_mbuf); 1816 sc->my_cdata.my_tx_chain[i].my_mbuf = NULL; 1817 } 1818 } 1819 bzero((char *)&sc->my_ldata->my_tx_list, 1820 sizeof(sc->my_ldata->my_tx_list)); 1821 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1822 MY_UNLOCK(sc); 1823 return; 1824} 1825 1826/* 1827 * Stop all chip I/O so that the kernel's probe routines don't get confused 1828 * by errant DMAs when rebooting. 1829 */ 1830static void 1831my_shutdown(device_t dev) 1832{ 1833 struct my_softc *sc; 1834 1835 sc = device_get_softc(dev); 1836 my_stop(sc); 1837 return; 1838} 1839