|
|
1.1 ! root 1: /* ! 2: * JMicron JMC2x0 series PCIe Ethernet gPXE Device Driver ! 3: * ! 4: * Copyright 2010 Guo-Fu Tseng <[email protected]> ! 5: * ! 6: * This program is free software; you can redistribute it and/or modify ! 7: * it under the terms of the GNU General Public License as published by ! 8: * the Free Software Foundation; either version 2 of the License. ! 9: * ! 10: * This program is distributed in the hope that it will be useful, ! 11: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 13: * GNU General Public License for more details. ! 14: * ! 15: * You should have received a copy of the GNU General Public License ! 16: * along with this program; if not, write to the Free Software ! 17: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: * ! 19: */ ! 20: FILE_LICENCE ( GPL2_OR_LATER ); ! 21: ! 22: #include <stdint.h> ! 23: #include <stdlib.h> ! 24: #include <stdio.h> ! 25: #include <string.h> ! 26: #include <ipxe/io.h> ! 27: #include <errno.h> ! 28: #include <unistd.h> ! 29: #include <byteswap.h> ! 30: #include <ipxe/pci.h> ! 31: #include <ipxe/if_ether.h> ! 32: #include <ipxe/ethernet.h> ! 33: #include <ipxe/iobuf.h> ! 34: #include <ipxe/netdevice.h> ! 35: #include <ipxe/malloc.h> ! 36: #include <mii.h> ! 37: #include "jme.h" ! 38: ! 39: static int ! 40: jme_mdio_read(struct net_device *netdev, int phy, int reg) ! 41: { ! 42: struct jme_adapter *jme = netdev->priv; ! 43: int i, val, again = (reg == MII_BMSR) ? 1 : 0; ! 44: ! 45: read_again: ! 46: jwrite32(jme, JME_SMI, SMI_OP_REQ | ! 47: smi_phy_addr(phy) | ! 48: smi_reg_addr(reg)); ! 49: ! 50: for (i = JME_PHY_TIMEOUT * 50 ; i > 0 ; --i) { ! 51: udelay(20); ! 52: val = jread32(jme, JME_SMI); ! 53: if ((val & SMI_OP_REQ) == 0) ! 54: break; ! 55: } ! 56: ! 57: if (i == 0) { ! 58: DBG("phy(%d) read timeout : %d\n", phy, reg); ! 59: return 0; ! 60: } ! 61: ! 62: if (again--) ! 63: goto read_again; ! 64: ! 65: return (val & SMI_DATA_MASK) >> SMI_DATA_SHIFT; ! 66: } ! 67: ! 68: static void ! 69: jme_mdio_write(struct net_device *netdev, ! 70: int phy, int reg, int val) ! 71: { ! 72: struct jme_adapter *jme = netdev->priv; ! 73: int i; ! 74: ! 75: jwrite32(jme, JME_SMI, SMI_OP_WRITE | SMI_OP_REQ | ! 76: ((val << SMI_DATA_SHIFT) & SMI_DATA_MASK) | ! 77: smi_phy_addr(phy) | smi_reg_addr(reg)); ! 78: ! 79: wmb(); ! 80: for (i = JME_PHY_TIMEOUT * 50 ; i > 0 ; --i) { ! 81: udelay(20); ! 82: if ((jread32(jme, JME_SMI) & SMI_OP_REQ) == 0) ! 83: break; ! 84: } ! 85: ! 86: if (i == 0) ! 87: DBG("phy(%d) write timeout : %d\n", phy, reg); ! 88: ! 89: return; ! 90: } ! 91: ! 92: static void ! 93: jme_reset_phy_processor(struct jme_adapter *jme) ! 94: { ! 95: u32 val; ! 96: ! 97: jme_mdio_write(jme->mii_if.dev, ! 98: jme->mii_if.phy_id, ! 99: MII_ADVERTISE, ADVERTISE_ALL | ! 100: ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); ! 101: ! 102: if (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250) ! 103: jme_mdio_write(jme->mii_if.dev, ! 104: jme->mii_if.phy_id, ! 105: MII_CTRL1000, ! 106: ADVERTISE_1000FULL | ADVERTISE_1000HALF); ! 107: ! 108: val = jme_mdio_read(jme->mii_if.dev, ! 109: jme->mii_if.phy_id, ! 110: MII_BMCR); ! 111: ! 112: jme_mdio_write(jme->mii_if.dev, ! 113: jme->mii_if.phy_id, ! 114: MII_BMCR, val | BMCR_RESET); ! 115: ! 116: return; ! 117: } ! 118: ! 119: static void ! 120: jme_phy_init(struct jme_adapter *jme) ! 121: { ! 122: u16 reg26; ! 123: ! 124: reg26 = jme_mdio_read(jme->mii_if.dev, jme->mii_if.phy_id, 26); ! 125: jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, 26, reg26 | 0x1000); ! 126: } ! 127: ! 128: static void ! 129: jme_set_phyfifoa(struct jme_adapter *jme) ! 130: { ! 131: jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, 27, 0x0004); ! 132: } ! 133: ! 134: static void ! 135: jme_set_phyfifob(struct jme_adapter *jme) ! 136: { ! 137: jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, 27, 0x0000); ! 138: } ! 139: ! 140: static void ! 141: jme_phy_off(struct jme_adapter *jme) ! 142: { ! 143: jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN); ! 144: } ! 145: ! 146: static void ! 147: jme_restart_an(struct jme_adapter *jme) ! 148: { ! 149: uint32_t bmcr; ! 150: ! 151: bmcr = jme_mdio_read(jme->mii_if.dev, jme->mii_if.phy_id, MII_BMCR); ! 152: bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); ! 153: jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, MII_BMCR, bmcr); ! 154: } ! 155: ! 156: static void ! 157: jme_reset_ghc_speed(struct jme_adapter *jme) ! 158: { ! 159: jme->reg_ghc &= ~(GHC_SPEED_1000M | GHC_DPX); ! 160: jwrite32(jme, JME_GHC, jme->reg_ghc); ! 161: } ! 162: ! 163: static void ! 164: jme_start_irq(struct jme_adapter *jme) ! 165: { ! 166: /* ! 167: * Enable Interrupts ! 168: */ ! 169: jwrite32(jme, JME_IENS, INTR_ENABLE); ! 170: } ! 171: ! 172: static void ! 173: jme_stop_irq(struct jme_adapter *jme) ! 174: { ! 175: /* ! 176: * Disable Interrupts ! 177: */ ! 178: jwrite32f(jme, JME_IENC, INTR_ENABLE); ! 179: } ! 180: ! 181: static void ! 182: jme_setup_wakeup_frame(struct jme_adapter *jme, ! 183: u32 *mask, u32 crc, int fnr) ! 184: { ! 185: int i; ! 186: ! 187: /* ! 188: * Setup CRC pattern ! 189: */ ! 190: jwrite32(jme, JME_WFOI, WFOI_CRC_SEL | (fnr & WFOI_FRAME_SEL)); ! 191: wmb(); ! 192: jwrite32(jme, JME_WFODP, crc); ! 193: wmb(); ! 194: ! 195: /* ! 196: * Setup Mask ! 197: */ ! 198: for (i = 0 ; i < WAKEUP_FRAME_MASK_DWNR ; ++i) { ! 199: jwrite32(jme, JME_WFOI, ! 200: ((i << WFOI_MASK_SHIFT) & WFOI_MASK_SEL) | ! 201: (fnr & WFOI_FRAME_SEL)); ! 202: wmb(); ! 203: jwrite32(jme, JME_WFODP, mask[i]); ! 204: wmb(); ! 205: } ! 206: } ! 207: ! 208: static void ! 209: jme_reset_mac_processor(struct jme_adapter *jme) ! 210: { ! 211: u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0}; ! 212: u32 crc = 0xCDCDCDCD; ! 213: int i; ! 214: ! 215: jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST); ! 216: udelay(2); ! 217: jwrite32(jme, JME_GHC, jme->reg_ghc); ! 218: ! 219: jwrite32(jme, JME_RXDBA_LO, 0x00000000); ! 220: jwrite32(jme, JME_RXDBA_HI, 0x00000000); ! 221: jwrite32(jme, JME_RXQDC, 0x00000000); ! 222: jwrite32(jme, JME_RXNDA, 0x00000000); ! 223: jwrite32(jme, JME_TXDBA_LO, 0x00000000); ! 224: jwrite32(jme, JME_TXDBA_HI, 0x00000000); ! 225: jwrite32(jme, JME_TXQDC, 0x00000000); ! 226: jwrite32(jme, JME_TXNDA, 0x00000000); ! 227: ! 228: jwrite32(jme, JME_RXMCHT_LO, 0x00000000); ! 229: jwrite32(jme, JME_RXMCHT_HI, 0x00000000); ! 230: for (i = 0 ; i < WAKEUP_FRAME_NR ; ++i) ! 231: jme_setup_wakeup_frame(jme, mask, crc, i); ! 232: jwrite32(jme, JME_GPREG0, GPREG0_DEFAULT); ! 233: jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT); ! 234: } ! 235: ! 236: static void ! 237: jme_free_tx_buffers(struct jme_adapter *jme) ! 238: { ! 239: struct jme_ring *txring = &jme->txring; ! 240: struct io_buffer *txbi; ! 241: unsigned int i; ! 242: ! 243: for (i = 0; i < jme->tx_ring_size; ++i) { ! 244: txbi = txring->bufinf[i]; ! 245: if (txbi) { ! 246: netdev_tx_complete_err(jme->mii_if.dev, ! 247: txbi, -ENOLINK); ! 248: txring->bufinf[i] = NULL; ! 249: } ! 250: } ! 251: } ! 252: ! 253: static void ! 254: jme_free_tx_resources(struct jme_adapter *jme) ! 255: { ! 256: struct jme_ring *txring = &jme->txring; ! 257: ! 258: if (txring->desc) { ! 259: if (txring->bufinf) { ! 260: memset(txring->bufinf, 0, ! 261: sizeof(struct io_buffer *) * jme->tx_ring_size); ! 262: free(txring->bufinf); ! 263: } ! 264: free_dma(txring->desc, jme->tx_ring_size * TX_DESC_SIZE); ! 265: txring->desc = NULL; ! 266: txring->dma = 0; ! 267: txring->bufinf = NULL; ! 268: } ! 269: txring->next_to_use = 0; ! 270: txring->next_to_clean = 0; ! 271: txring->nr_free = 0; ! 272: } ! 273: ! 274: static int ! 275: jme_alloc_tx_resources(struct jme_adapter *jme) ! 276: { ! 277: struct jme_ring *txring = &jme->txring; ! 278: ! 279: txring->desc = malloc_dma(jme->tx_ring_size * TX_DESC_SIZE, ! 280: RING_DESC_ALIGN); ! 281: if (!txring->desc) { ! 282: DBG("Can not allocate transmit ring descriptors.\n"); ! 283: goto err_out; ! 284: } ! 285: ! 286: /* ! 287: * 16 Bytes align ! 288: */ ! 289: txring->dma = virt_to_bus(txring->desc); ! 290: txring->bufinf = malloc(sizeof(struct io_buffer *) * ! 291: jme->tx_ring_size); ! 292: if (!(txring->bufinf)) { ! 293: DBG("Can not allocate transmit buffer info.\n"); ! 294: goto err_out; ! 295: } ! 296: ! 297: /* ! 298: * Initialize Transmit Buffer Pointers ! 299: */ ! 300: memset(txring->bufinf, 0, ! 301: sizeof(struct io_buffer *) * jme->tx_ring_size); ! 302: ! 303: return 0; ! 304: ! 305: err_out: ! 306: jme_free_tx_resources(jme); ! 307: return -ENOMEM; ! 308: } ! 309: ! 310: static void ! 311: jme_init_tx_ring(struct jme_adapter *jme) ! 312: { ! 313: struct jme_ring *txring = &jme->txring; ! 314: ! 315: txring->next_to_clean = 0; ! 316: txring->next_to_use = 0; ! 317: txring->nr_free = jme->tx_ring_size; ! 318: ! 319: /* ! 320: * Initialize Transmit Descriptors ! 321: */ ! 322: memset(txring->desc, 0, jme->tx_ring_size * TX_DESC_SIZE); ! 323: jme_free_tx_buffers(jme); ! 324: } ! 325: ! 326: static void ! 327: jme_enable_tx_engine(struct jme_adapter *jme) ! 328: { ! 329: /* ! 330: * Select Queue 0 ! 331: */ ! 332: jwrite32(jme, JME_TXCS, TXCS_DEFAULT | TXCS_SELECT_QUEUE0); ! 333: wmb(); ! 334: ! 335: /* ! 336: * Setup TX Queue 0 DMA Bass Address ! 337: */ ! 338: jwrite32(jme, JME_TXDBA_LO, (uint64_t)jme->txring.dma & 0xFFFFFFFFUL); ! 339: jwrite32(jme, JME_TXDBA_HI, (uint64_t)(jme->txring.dma) >> 32); ! 340: jwrite32(jme, JME_TXNDA, (uint64_t)jme->txring.dma & 0xFFFFFFFFUL); ! 341: ! 342: /* ! 343: * Setup TX Descptor Count ! 344: */ ! 345: jwrite32(jme, JME_TXQDC, jme->tx_ring_size); ! 346: ! 347: /* ! 348: * Enable TX Engine ! 349: */ ! 350: wmb(); ! 351: jwrite32(jme, JME_TXCS, jme->reg_txcs | ! 352: TXCS_SELECT_QUEUE0 | ! 353: TXCS_ENABLE); ! 354: ! 355: } ! 356: ! 357: static void ! 358: jme_disable_tx_engine(struct jme_adapter *jme) ! 359: { ! 360: int i; ! 361: u32 val; ! 362: ! 363: /* ! 364: * Disable TX Engine ! 365: */ ! 366: jwrite32(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0); ! 367: wmb(); ! 368: ! 369: val = jread32(jme, JME_TXCS); ! 370: for (i = JME_TX_DISABLE_TIMEOUT ; (val & TXCS_ENABLE) && i > 0 ; --i) { ! 371: mdelay(1); ! 372: val = jread32(jme, JME_TXCS); ! 373: rmb(); ! 374: } ! 375: ! 376: if (!i) ! 377: DBG("Disable TX engine timeout.\n"); ! 378: } ! 379: ! 380: ! 381: static void ! 382: jme_set_clean_rxdesc(struct jme_adapter *jme, int i) ! 383: { ! 384: struct jme_ring *rxring = &jme->rxring; ! 385: register struct rxdesc *rxdesc = rxring->desc; ! 386: struct io_buffer *rxbi = rxring->bufinf[i]; ! 387: uint64_t mapping; ! 388: ! 389: rxdesc += i; ! 390: mapping = virt_to_bus(rxbi->data); ! 391: ! 392: rxdesc->dw[0] = 0; ! 393: rxdesc->dw[1] = 0; ! 394: rxdesc->desc1.bufaddrh = cpu_to_le32(mapping >> 32); ! 395: rxdesc->desc1.bufaddrl = cpu_to_le32(mapping & 0xFFFFFFFFUL); ! 396: rxdesc->desc1.datalen = cpu_to_le16(RX_ALLOC_LEN); ! 397: wmb(); ! 398: rxdesc->desc1.flags |= RXFLAG_OWN | RXFLAG_INT; ! 399: } ! 400: ! 401: static int ! 402: jme_make_new_rx_buf(struct io_buffer **rxbip) ! 403: { ! 404: struct io_buffer *inbuf; ! 405: ! 406: /* ! 407: * IOB_ALIGN == 2048 ! 408: */ ! 409: inbuf = alloc_iob(RX_ALLOC_LEN); ! 410: if (!inbuf) { ! 411: DBG("Allocate receive iob error.\n"); ! 412: return -ENOMEM; ! 413: } ! 414: *rxbip = inbuf; ! 415: ! 416: return 0; ! 417: } ! 418: ! 419: static void ! 420: jme_free_rx_buf(struct jme_adapter *jme, int i) ! 421: { ! 422: struct jme_ring *rxring = &jme->rxring; ! 423: struct io_buffer *rxbi = rxring->bufinf[i]; ! 424: ! 425: if (rxbi) { ! 426: free_iob(rxbi); ! 427: rxring->bufinf[i] = NULL; ! 428: } ! 429: } ! 430: ! 431: static void ! 432: jme_free_rx_resources(struct jme_adapter *jme) ! 433: { ! 434: unsigned int i; ! 435: struct jme_ring *rxring = &jme->rxring; ! 436: ! 437: if (rxring->desc) { ! 438: if (rxring->bufinf) { ! 439: for (i = 0 ; i < jme->rx_ring_size ; ++i) ! 440: jme_free_rx_buf(jme, i); ! 441: free(rxring->bufinf); ! 442: } ! 443: ! 444: free_dma(rxring->desc, jme->rx_ring_size * RX_DESC_SIZE); ! 445: rxring->desc = NULL; ! 446: rxring->dma = 0; ! 447: rxring->bufinf = NULL; ! 448: } ! 449: rxring->next_to_fill = 0; ! 450: rxring->next_to_clean = 0; ! 451: } ! 452: ! 453: static int ! 454: jme_alloc_rx_resources(struct jme_adapter *jme) ! 455: { ! 456: unsigned int i; ! 457: struct jme_ring *rxring = &jme->rxring; ! 458: struct io_buffer **bufinf; ! 459: ! 460: rxring->desc = malloc_dma(jme->rx_ring_size * RX_DESC_SIZE, ! 461: RING_DESC_ALIGN); ! 462: if (!rxring->desc) { ! 463: DBG("Can not allocate receive ring descriptors.\n"); ! 464: goto err_out; ! 465: } ! 466: ! 467: /* ! 468: * 16 Bytes align ! 469: */ ! 470: rxring->dma = virt_to_bus(rxring->desc); ! 471: rxring->bufinf = malloc(sizeof(struct io_buffer *) * ! 472: jme->rx_ring_size); ! 473: if (!(rxring->bufinf)) { ! 474: DBG("Can not allocate receive buffer info.\n"); ! 475: goto err_out; ! 476: } ! 477: ! 478: /* ! 479: * Initiallize Receive Buffer Pointers ! 480: */ ! 481: bufinf = rxring->bufinf; ! 482: memset(bufinf, 0, sizeof(struct io_buffer *) * jme->rx_ring_size); ! 483: for (i = 0 ; i < jme->rx_ring_size ; ++i) { ! 484: if (jme_make_new_rx_buf(bufinf)) ! 485: goto err_out; ! 486: ++bufinf; ! 487: } ! 488: ! 489: return 0; ! 490: ! 491: err_out: ! 492: jme_free_rx_resources(jme); ! 493: return -ENOMEM; ! 494: } ! 495: ! 496: static void ! 497: jme_init_rx_ring(struct jme_adapter *jme) ! 498: { ! 499: unsigned int i; ! 500: struct jme_ring *rxring = &jme->rxring; ! 501: ! 502: for (i = 0 ; i < jme->rx_ring_size ; ++i) ! 503: jme_set_clean_rxdesc(jme, i); ! 504: ! 505: rxring->next_to_fill = 0; ! 506: rxring->next_to_clean = 0; ! 507: } ! 508: ! 509: static void ! 510: jme_set_multi(struct jme_adapter *jme) ! 511: { ! 512: /* ! 513: * Just receive all kind of packet for new. ! 514: */ ! 515: jme->reg_rxmcs |= RXMCS_ALLFRAME | RXMCS_BRDFRAME | RXMCS_UNIFRAME; ! 516: jwrite32(jme, JME_RXMCS, jme->reg_rxmcs); ! 517: } ! 518: ! 519: static void ! 520: jme_enable_rx_engine(struct jme_adapter *jme) ! 521: { ! 522: /* ! 523: * Select Queue 0 ! 524: */ ! 525: jwrite32(jme, JME_RXCS, jme->reg_rxcs | ! 526: RXCS_QUEUESEL_Q0); ! 527: wmb(); ! 528: ! 529: /* ! 530: * Setup RX DMA Bass Address ! 531: */ ! 532: jwrite32(jme, JME_RXDBA_LO, (uint64_t)(jme->rxring.dma) & 0xFFFFFFFFUL); ! 533: jwrite32(jme, JME_RXDBA_HI, (uint64_t)(jme->rxring.dma) >> 32); ! 534: jwrite32(jme, JME_RXNDA, (uint64_t)(jme->rxring.dma) & 0xFFFFFFFFUL); ! 535: ! 536: /* ! 537: * Setup RX Descriptor Count ! 538: */ ! 539: jwrite32(jme, JME_RXQDC, jme->rx_ring_size); ! 540: ! 541: /* ! 542: * Setup Unicast Filter ! 543: */ ! 544: jme_set_multi(jme); ! 545: ! 546: /* ! 547: * Enable RX Engine ! 548: */ ! 549: wmb(); ! 550: jwrite32(jme, JME_RXCS, jme->reg_rxcs | ! 551: RXCS_QUEUESEL_Q0 | ! 552: RXCS_ENABLE | ! 553: RXCS_QST); ! 554: } ! 555: ! 556: static void ! 557: jme_restart_rx_engine(struct jme_adapter *jme) ! 558: { ! 559: /* ! 560: * Start RX Engine ! 561: */ ! 562: jwrite32(jme, JME_RXCS, jme->reg_rxcs | ! 563: RXCS_QUEUESEL_Q0 | ! 564: RXCS_ENABLE | ! 565: RXCS_QST); ! 566: } ! 567: ! 568: static void ! 569: jme_disable_rx_engine(struct jme_adapter *jme) ! 570: { ! 571: int i; ! 572: u32 val; ! 573: ! 574: /* ! 575: * Disable RX Engine ! 576: */ ! 577: jwrite32(jme, JME_RXCS, jme->reg_rxcs); ! 578: wmb(); ! 579: ! 580: val = jread32(jme, JME_RXCS); ! 581: for (i = JME_RX_DISABLE_TIMEOUT ; (val & RXCS_ENABLE) && i > 0 ; --i) { ! 582: mdelay(1); ! 583: val = jread32(jme, JME_RXCS); ! 584: rmb(); ! 585: } ! 586: ! 587: if (!i) ! 588: DBG("Disable RX engine timeout.\n"); ! 589: ! 590: } ! 591: ! 592: static void ! 593: jme_refill_rx_ring(struct jme_adapter *jme, int curhole) ! 594: { ! 595: struct jme_ring *rxring = &jme->rxring; ! 596: int i = rxring->next_to_fill; ! 597: struct io_buffer **bufinf = rxring->bufinf; ! 598: int mask = jme->rx_ring_mask; ! 599: int limit = jme->rx_ring_size; ! 600: ! 601: while (limit--) { ! 602: if (!bufinf[i]) { ! 603: if (jme_make_new_rx_buf(bufinf + i)) ! 604: break; ! 605: jme_set_clean_rxdesc(jme, i); ! 606: } ! 607: if (i == curhole) ! 608: limit = 0; ! 609: i = (i + 1) & mask; ! 610: } ! 611: rxring->next_to_fill = i; ! 612: } ! 613: ! 614: static void ! 615: jme_alloc_and_feed_iob(struct jme_adapter *jme, int idx) ! 616: { ! 617: struct jme_ring *rxring = &jme->rxring; ! 618: struct rxdesc *rxdesc = rxring->desc; ! 619: struct io_buffer *rxbi = rxring->bufinf[idx]; ! 620: struct net_device *netdev = jme->mii_if.dev; ! 621: int framesize; ! 622: ! 623: rxdesc += idx; ! 624: ! 625: framesize = le16_to_cpu(rxdesc->descwb.framesize); ! 626: iob_put(rxbi, framesize); ! 627: netdev_rx(netdev, rxbi); ! 628: ! 629: rxring->bufinf[idx] = NULL; ! 630: jme_refill_rx_ring(jme, idx); ! 631: } ! 632: ! 633: static void ! 634: jme_process_receive(struct jme_adapter *jme) ! 635: { ! 636: struct jme_ring *rxring = &jme->rxring; ! 637: struct rxdesc *rxdesc = rxring->desc; ! 638: struct net_device *netdev = jme->mii_if.dev; ! 639: int i, j, ccnt, desccnt, mask = jme->rx_ring_mask; ! 640: unsigned int limit = jme->rx_ring_size; ! 641: ! 642: i = rxring->next_to_clean; ! 643: rxdesc += i; ! 644: while (rxring->bufinf[i] && ! 645: !(rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) && ! 646: (rxdesc->descwb.desccnt & RXWBDCNT_WBCPL) && ! 647: limit--) { ! 648: ! 649: rmb(); ! 650: desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT; ! 651: DBG2("Cleaning rx desc=%d, cnt=%d\n", i, desccnt); ! 652: ! 653: if (desccnt > 1 || rxdesc->descwb.errstat & RXWBERR_ALLERR) { ! 654: for (j = i, ccnt = desccnt ; ccnt-- ; ) { ! 655: jme_set_clean_rxdesc(jme, j); ! 656: j = (j + 1) & (mask); ! 657: } ! 658: DBG("Dropped packet due to "); ! 659: if (desccnt > 1) ! 660: DBG("long packet.(%d descriptors)\n", desccnt); ! 661: else ! 662: DBG("Packet error.\n"); ! 663: netdev_rx_err(netdev, NULL, -EINVAL); ! 664: } else { ! 665: jme_alloc_and_feed_iob(jme, i); ! 666: } ! 667: ! 668: i = (i + desccnt) & (mask); ! 669: rxdesc = rxring->desc; ! 670: rxdesc += i; ! 671: } ! 672: rxring->next_to_clean = i; ! 673: ! 674: return; ! 675: } ! 676: ! 677: static void ! 678: jme_set_custom_macaddr(struct net_device *netdev) ! 679: { ! 680: struct jme_adapter *jme = netdev->priv; ! 681: uint8_t *addr = netdev->ll_addr; ! 682: u32 val; ! 683: ! 684: val = (addr[3] & 0xff) << 24 | ! 685: (addr[2] & 0xff) << 16 | ! 686: (addr[1] & 0xff) << 8 | ! 687: (addr[0] & 0xff); ! 688: jwrite32(jme, JME_RXUMA_LO, val); ! 689: val = (addr[5] & 0xff) << 8 | ! 690: (addr[4] & 0xff); ! 691: jwrite32(jme, JME_RXUMA_HI, val); ! 692: } ! 693: ! 694: /** ! 695: * Open NIC ! 696: * ! 697: * @v netdev Net device ! 698: * @ret rc Return status code ! 699: */ ! 700: static int ! 701: jme_open(struct net_device *netdev) ! 702: { ! 703: struct jme_adapter *jme = netdev->priv; ! 704: int rc; ! 705: ! 706: /* ! 707: * Allocate receive resources ! 708: */ ! 709: rc = jme_alloc_rx_resources(jme); ! 710: if (rc) { ! 711: DBG("Allocate receive resources error.\n"); ! 712: goto nomem_out; ! 713: } ! 714: ! 715: /* ! 716: * Allocate transmit resources ! 717: */ ! 718: rc = jme_alloc_tx_resources(jme); ! 719: if (rc) { ! 720: DBG("Allocate transmit resources error.\n"); ! 721: goto free_rx_resources_out; ! 722: } ! 723: ! 724: jme_set_custom_macaddr(netdev); ! 725: jme_reset_phy_processor(jme); ! 726: jme_restart_an(jme); ! 727: ! 728: return 0; ! 729: ! 730: free_rx_resources_out: ! 731: jme_free_rx_resources(jme); ! 732: nomem_out: ! 733: return rc; ! 734: } ! 735: ! 736: /** ! 737: * Close NIC ! 738: * ! 739: * @v netdev Net device ! 740: */ ! 741: static void ! 742: jme_close(struct net_device *netdev) ! 743: { ! 744: struct jme_adapter *jme = netdev->priv; ! 745: ! 746: jme_free_tx_resources(jme); ! 747: jme_free_rx_resources(jme); ! 748: jme_reset_mac_processor(jme); ! 749: jme->phylink = 0; ! 750: jme_phy_off(jme); ! 751: netdev_link_down(netdev); ! 752: } ! 753: ! 754: static int ! 755: jme_alloc_txdesc(struct jme_adapter *jme) ! 756: { ! 757: struct jme_ring *txring = &jme->txring; ! 758: int idx; ! 759: ! 760: idx = txring->next_to_use; ! 761: if (txring->nr_free < 1) ! 762: return -1; ! 763: --(txring->nr_free); ! 764: txring->next_to_use = (txring->next_to_use + 1) & jme->tx_ring_mask; ! 765: ! 766: return idx; ! 767: } ! 768: ! 769: static void ! 770: jme_fill_tx_desc(struct jme_adapter *jme, struct io_buffer *iob, int idx) ! 771: { ! 772: struct jme_ring *txring = &jme->txring; ! 773: struct txdesc *txdesc = txring->desc; ! 774: uint16_t len = iob_len(iob); ! 775: unsigned long int mapping; ! 776: ! 777: txdesc += idx; ! 778: mapping = virt_to_bus(iob->data); ! 779: DBG2("TX buffer address: %p(%08lx+%x)\n", ! 780: iob->data, mapping, len); ! 781: txdesc->dw[0] = 0; ! 782: txdesc->dw[1] = 0; ! 783: txdesc->dw[2] = 0; ! 784: txdesc->dw[3] = 0; ! 785: txdesc->desc1.datalen = cpu_to_le16(len); ! 786: txdesc->desc1.pktsize = cpu_to_le16(len); ! 787: txdesc->desc1.bufaddr = cpu_to_le32(mapping); ! 788: /* ! 789: * Set OWN bit at final. ! 790: * When kernel transmit faster than NIC. ! 791: * And NIC trying to send this descriptor before we tell ! 792: * it to start sending this TX queue. ! 793: * Other fields are already filled correctly. ! 794: */ ! 795: wmb(); ! 796: txdesc->desc1.flags = TXFLAG_OWN | TXFLAG_INT; ! 797: /* ! 798: * Set tx buffer info after telling NIC to send ! 799: * For better tx_clean timing ! 800: */ ! 801: wmb(); ! 802: txring->bufinf[idx] = iob; ! 803: } ! 804: ! 805: /** ! 806: * Transmit packet ! 807: * ! 808: * @v netdev Network device ! 809: * @v iobuf I/O buffer ! 810: * @ret rc Return status code ! 811: */ ! 812: static int ! 813: jme_transmit(struct net_device *netdev, struct io_buffer *iobuf) ! 814: { ! 815: struct jme_adapter *jme = netdev->priv; ! 816: int idx; ! 817: ! 818: idx = jme_alloc_txdesc(jme); ! 819: if (idx < 0) { ! 820: /* ! 821: * Pause transmit queue somehow if possible. ! 822: */ ! 823: DBG("TX ring full!\n"); ! 824: return -EOVERFLOW; ! 825: } ! 826: ! 827: jme_fill_tx_desc(jme, iobuf, idx); ! 828: ! 829: jwrite32(jme, JME_TXCS, jme->reg_txcs | ! 830: TXCS_SELECT_QUEUE0 | ! 831: TXCS_QUEUE0S | ! 832: TXCS_ENABLE); ! 833: DBG2("xmit: idx=%d\n", idx); ! 834: ! 835: return 0; ! 836: } ! 837: ! 838: static int ! 839: jme_check_link(struct net_device *netdev, int testonly) ! 840: { ! 841: struct jme_adapter *jme = netdev->priv; ! 842: u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, gpreg1; ! 843: int rc = 0; ! 844: ! 845: phylink = jread32(jme, JME_PHY_LINK); ! 846: ! 847: if (phylink & PHY_LINK_UP) { ! 848: /* ! 849: * Keep polling for speed/duplex resolve complete ! 850: */ ! 851: while (!(phylink & PHY_LINK_SPEEDDPU_RESOLVED) && ! 852: --cnt) { ! 853: ! 854: udelay(1); ! 855: phylink = jread32(jme, JME_PHY_LINK); ! 856: } ! 857: if (!cnt) ! 858: DBG("Waiting speed resolve timeout.\n"); ! 859: ! 860: if (jme->phylink == phylink) { ! 861: rc = 1; ! 862: goto out; ! 863: } ! 864: if (testonly) ! 865: goto out; ! 866: ! 867: jme->phylink = phylink; ! 868: ! 869: ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX | ! 870: GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE | ! 871: GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY); ! 872: switch (phylink & PHY_LINK_SPEED_MASK) { ! 873: case PHY_LINK_SPEED_10M: ! 874: ghc |= GHC_SPEED_10M | ! 875: GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; ! 876: break; ! 877: case PHY_LINK_SPEED_100M: ! 878: ghc |= GHC_SPEED_100M | ! 879: GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; ! 880: break; ! 881: case PHY_LINK_SPEED_1000M: ! 882: ghc |= GHC_SPEED_1000M | ! 883: GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY; ! 884: break; ! 885: default: ! 886: break; ! 887: } ! 888: ! 889: if (phylink & PHY_LINK_DUPLEX) { ! 890: jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT); ! 891: ghc |= GHC_DPX; ! 892: } else { ! 893: jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT | ! 894: TXMCS_BACKOFF | ! 895: TXMCS_CARRIERSENSE | ! 896: TXMCS_COLLISION); ! 897: jwrite32(jme, JME_TXTRHD, TXTRHD_TXPEN | ! 898: ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) | ! 899: TXTRHD_TXREN | ! 900: ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL)); ! 901: } ! 902: ! 903: gpreg1 = GPREG1_DEFAULT; ! 904: if (is_buggy250(jme->pdev->device, jme->chiprev)) { ! 905: if (!(phylink & PHY_LINK_DUPLEX)) ! 906: gpreg1 |= GPREG1_HALFMODEPATCH; ! 907: switch (phylink & PHY_LINK_SPEED_MASK) { ! 908: case PHY_LINK_SPEED_10M: ! 909: jme_set_phyfifoa(jme); ! 910: gpreg1 |= GPREG1_RSSPATCH; ! 911: break; ! 912: case PHY_LINK_SPEED_100M: ! 913: jme_set_phyfifob(jme); ! 914: gpreg1 |= GPREG1_RSSPATCH; ! 915: break; ! 916: case PHY_LINK_SPEED_1000M: ! 917: jme_set_phyfifoa(jme); ! 918: break; ! 919: default: ! 920: break; ! 921: } ! 922: } ! 923: ! 924: jwrite32(jme, JME_GPREG1, gpreg1); ! 925: jwrite32(jme, JME_GHC, ghc); ! 926: jme->reg_ghc = ghc; ! 927: ! 928: DBG("Link is up at %d Mbps, %s-Duplex, MDI%s.\n", ! 929: ((phylink & PHY_LINK_SPEED_MASK) ! 930: == PHY_LINK_SPEED_1000M) ? 1000 : ! 931: ((phylink & PHY_LINK_SPEED_MASK) ! 932: == PHY_LINK_SPEED_100M) ? 100 : 10, ! 933: (phylink & PHY_LINK_DUPLEX) ? "Full" : "Half", ! 934: (phylink & PHY_LINK_MDI_STAT) ? "-X" : ""); ! 935: netdev_link_up(netdev); ! 936: } else { ! 937: if (testonly) ! 938: goto out; ! 939: ! 940: DBG("Link is down.\n"); ! 941: jme->phylink = 0; ! 942: netdev_link_down(netdev); ! 943: } ! 944: ! 945: out: ! 946: return rc; ! 947: } ! 948: ! 949: static void ! 950: jme_link_change(struct net_device *netdev) ! 951: { ! 952: struct jme_adapter *jme = netdev->priv; ! 953: ! 954: /* ! 955: * Do nothing if the link status did not change. ! 956: */ ! 957: if (jme_check_link(netdev, 1)) ! 958: return; ! 959: ! 960: if (netdev_link_ok(netdev)) { ! 961: netdev_link_down(netdev); ! 962: jme_disable_rx_engine(jme); ! 963: jme_disable_tx_engine(jme); ! 964: jme_reset_ghc_speed(jme); ! 965: jme_reset_mac_processor(jme); ! 966: } ! 967: ! 968: jme_check_link(netdev, 0); ! 969: if (netdev_link_ok(netdev)) { ! 970: jme_init_rx_ring(jme); ! 971: jme_enable_rx_engine(jme); ! 972: jme_init_tx_ring(jme); ! 973: jme_enable_tx_engine(jme); ! 974: } ! 975: ! 976: return; ! 977: } ! 978: ! 979: static void ! 980: jme_tx_clean(struct jme_adapter *jme) ! 981: { ! 982: struct jme_ring *txring = &jme->txring; ! 983: struct txdesc *txdesc = txring->desc; ! 984: struct io_buffer *txbi; ! 985: struct net_device *netdev = jme->mii_if.dev; ! 986: int i, cnt = 0, max, err, mask; ! 987: ! 988: max = jme->tx_ring_size - txring->nr_free; ! 989: mask = jme->tx_ring_mask; ! 990: ! 991: for (i = txring->next_to_clean ; cnt < max ; ++cnt) { ! 992: ! 993: txbi = txring->bufinf[i]; ! 994: ! 995: if (txbi && !(txdesc[i].descwb.flags & TXWBFLAG_OWN)) { ! 996: DBG2("TX clean address: %08lx(%08lx+%zx)\n", ! 997: (unsigned long)txbi->data, ! 998: virt_to_bus(txbi->data), ! 999: iob_len(txbi)); ! 1000: err = txdesc[i].descwb.flags & TXWBFLAG_ALLERR; ! 1001: if (err) ! 1002: netdev_tx_complete_err(netdev, txbi, -EIO); ! 1003: else ! 1004: netdev_tx_complete(netdev, txbi); ! 1005: txring->bufinf[i] = NULL; ! 1006: } else { ! 1007: break; ! 1008: } ! 1009: ! 1010: i = (i + 1) & mask; ! 1011: } ! 1012: ! 1013: DBG2("txclean: next %d\n", i); ! 1014: txring->next_to_clean = i; ! 1015: txring->nr_free += cnt; ! 1016: } ! 1017: /** ! 1018: * Poll for received packets ! 1019: * ! 1020: * @v netdev Network device ! 1021: */ ! 1022: static void ! 1023: jme_poll(struct net_device *netdev) ! 1024: { ! 1025: struct jme_adapter *jme = netdev->priv; ! 1026: u32 intrstat; ! 1027: ! 1028: intrstat = jread32(jme, JME_IEVE); ! 1029: ! 1030: /* ! 1031: * Check if any actions needs to perform. ! 1032: */ ! 1033: if ((intrstat & INTR_ENABLE) == 0) ! 1034: return; ! 1035: ! 1036: /* ! 1037: * Check if the device still exist ! 1038: */ ! 1039: if (intrstat == ~((typeof(intrstat))0)) ! 1040: return; ! 1041: ! 1042: DBG2("intrstat 0x%08x\n", intrstat); ! 1043: if (intrstat & (INTR_LINKCH | INTR_SWINTR)) { ! 1044: DBG2("Link changed\n"); ! 1045: jme_link_change(netdev); ! 1046: ! 1047: /* ! 1048: * Clear all interrupt status ! 1049: */ ! 1050: jwrite32(jme, JME_IEVE, intrstat); ! 1051: ! 1052: /* ! 1053: * Link change event is critical ! 1054: * all other events are ignored ! 1055: */ ! 1056: return; ! 1057: } ! 1058: ! 1059: /* ! 1060: * Process transmission complete first to free more memory. ! 1061: */ ! 1062: if (intrstat & INTR_TX0) { ! 1063: DBG2("Packet transmit complete\n"); ! 1064: jme_tx_clean(jme); ! 1065: jwrite32(jme, JME_IEVE, intrstat & INTR_TX0); ! 1066: } ! 1067: ! 1068: if (intrstat & (INTR_RX0 | INTR_RX0EMP)) { ! 1069: DBG2("Packet received\n"); ! 1070: jme_process_receive(jme); ! 1071: jwrite32(jme, JME_IEVE, ! 1072: intrstat & (INTR_RX0 | INTR_RX0EMP)); ! 1073: if (intrstat & INTR_RX0EMP) ! 1074: jme_restart_rx_engine(jme); ! 1075: } ! 1076: ! 1077: /* ! 1078: * Clean all other interrupt status ! 1079: */ ! 1080: jwrite32(jme, JME_IEVE, ! 1081: intrstat & ~(INTR_RX0 | INTR_RX0EMP | INTR_TX0)); ! 1082: } ! 1083: ! 1084: /** ! 1085: * Enable/disable interrupts ! 1086: * ! 1087: * @v netdev Network device ! 1088: * @v enable Interrupts should be enabled ! 1089: */ ! 1090: static void ! 1091: jme_irq(struct net_device *netdev, int enable) ! 1092: { ! 1093: struct jme_adapter *jme = netdev->priv; ! 1094: ! 1095: DBG("jme interrupts %s\n", (enable ? "enabled" : "disabled")); ! 1096: if (enable) ! 1097: jme_start_irq(jme); ! 1098: else ! 1099: jme_stop_irq(jme); ! 1100: } ! 1101: ! 1102: /** JME net device operations */ ! 1103: static struct net_device_operations jme_operations = { ! 1104: .open = jme_open, ! 1105: .close = jme_close, ! 1106: .transmit = jme_transmit, ! 1107: .poll = jme_poll, ! 1108: .irq = jme_irq, ! 1109: }; ! 1110: ! 1111: static void ! 1112: jme_check_hw_ver(struct jme_adapter *jme) ! 1113: { ! 1114: u32 chipmode; ! 1115: ! 1116: chipmode = jread32(jme, JME_CHIPMODE); ! 1117: ! 1118: jme->fpgaver = (chipmode & CM_FPGAVER_MASK) >> CM_FPGAVER_SHIFT; ! 1119: jme->chiprev = (chipmode & CM_CHIPREV_MASK) >> CM_CHIPREV_SHIFT; ! 1120: } ! 1121: ! 1122: static int ! 1123: jme_reload_eeprom(struct jme_adapter *jme) ! 1124: { ! 1125: u32 val; ! 1126: int i; ! 1127: ! 1128: val = jread32(jme, JME_SMBCSR); ! 1129: ! 1130: if (val & SMBCSR_EEPROMD) { ! 1131: val |= SMBCSR_CNACK; ! 1132: jwrite32(jme, JME_SMBCSR, val); ! 1133: val |= SMBCSR_RELOAD; ! 1134: jwrite32(jme, JME_SMBCSR, val); ! 1135: mdelay(12); ! 1136: ! 1137: for (i = JME_EEPROM_RELOAD_TIMEOUT; i > 0; --i) { ! 1138: mdelay(1); ! 1139: if ((jread32(jme, JME_SMBCSR) & SMBCSR_RELOAD) == 0) ! 1140: break; ! 1141: } ! 1142: ! 1143: if (i == 0) { ! 1144: DBG("eeprom reload timeout\n"); ! 1145: return -EIO; ! 1146: } ! 1147: } ! 1148: ! 1149: return 0; ! 1150: } ! 1151: ! 1152: static void ! 1153: jme_load_macaddr(struct net_device *netdev) ! 1154: { ! 1155: struct jme_adapter *jme = netdev_priv(netdev); ! 1156: unsigned char macaddr[6]; ! 1157: u32 val; ! 1158: ! 1159: val = jread32(jme, JME_RXUMA_LO); ! 1160: macaddr[0] = (val >> 0) & 0xFF; ! 1161: macaddr[1] = (val >> 8) & 0xFF; ! 1162: macaddr[2] = (val >> 16) & 0xFF; ! 1163: macaddr[3] = (val >> 24) & 0xFF; ! 1164: val = jread32(jme, JME_RXUMA_HI); ! 1165: macaddr[4] = (val >> 0) & 0xFF; ! 1166: macaddr[5] = (val >> 8) & 0xFF; ! 1167: memcpy(netdev->hw_addr, macaddr, 6); ! 1168: } ! 1169: ! 1170: /** ! 1171: * Probe PCI device ! 1172: * ! 1173: * @v pci PCI device ! 1174: * @v id PCI ID ! 1175: * @ret rc Return status code ! 1176: */ ! 1177: static int ! 1178: jme_probe(struct pci_device *pci) ! 1179: { ! 1180: struct net_device *netdev; ! 1181: struct jme_adapter *jme; ! 1182: int rc; ! 1183: uint8_t mrrs; ! 1184: ! 1185: /* Allocate net device */ ! 1186: netdev = alloc_etherdev(sizeof(*jme)); ! 1187: if (!netdev) ! 1188: return -ENOMEM; ! 1189: netdev_init(netdev, &jme_operations); ! 1190: jme = netdev->priv; ! 1191: pci_set_drvdata(pci, netdev); ! 1192: netdev->dev = &pci->dev; ! 1193: jme->regs = ioremap(pci->membase, JME_REGS_SIZE); ! 1194: if (!(jme->regs)) { ! 1195: DBG("Mapping PCI resource region error.\n"); ! 1196: rc = -ENOMEM; ! 1197: goto err_out; ! 1198: } ! 1199: jme->reg_ghc = 0; ! 1200: jme->reg_rxcs = RXCS_DEFAULT; ! 1201: jme->reg_rxmcs = RXMCS_DEFAULT; ! 1202: jme->phylink = 0; ! 1203: jme->pdev = pci; ! 1204: jme->mii_if.dev = netdev; ! 1205: jme->mii_if.phy_id = 1; ! 1206: jme->mii_if.mdio_read = jme_mdio_read; ! 1207: jme->mii_if.mdio_write = jme_mdio_write; ! 1208: jme->rx_ring_size = 1 << 4; ! 1209: jme->rx_ring_mask = jme->rx_ring_size - 1; ! 1210: jme->tx_ring_size = 1 << 4; ! 1211: jme->tx_ring_mask = jme->tx_ring_size - 1; ! 1212: ! 1213: /* Fix up PCI device */ ! 1214: adjust_pci_device(pci); ! 1215: ! 1216: /* ! 1217: * Get Max Read Req Size from PCI Config Space ! 1218: */ ! 1219: pci_read_config_byte(pci, PCI_DCSR_MRRS, &mrrs); ! 1220: mrrs &= PCI_DCSR_MRRS_MASK; ! 1221: switch (mrrs) { ! 1222: case MRRS_128B: ! 1223: jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_128B; ! 1224: break; ! 1225: case MRRS_256B: ! 1226: jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_256B; ! 1227: break; ! 1228: default: ! 1229: jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_512B; ! 1230: break; ! 1231: }; ! 1232: ! 1233: /* ! 1234: * Get basic hardware info. ! 1235: */ ! 1236: jme_check_hw_ver(jme); ! 1237: if (pci->device == PCI_DEVICE_ID_JMICRON_JMC250) ! 1238: jme->mii_if.supports_gmii = 1; ! 1239: else ! 1240: jme->mii_if.supports_gmii = 0; ! 1241: ! 1242: /* ! 1243: * Initialize PHY ! 1244: */ ! 1245: jme_set_phyfifoa(jme); ! 1246: jme_phy_init(jme); ! 1247: ! 1248: /* ! 1249: * Bring down phy before interface is opened. ! 1250: */ ! 1251: jme_phy_off(jme); ! 1252: ! 1253: /* ! 1254: * Reset MAC processor and reload EEPROM for MAC Address ! 1255: */ ! 1256: jme_reset_mac_processor(jme); ! 1257: rc = jme_reload_eeprom(jme); ! 1258: if (rc) { ! 1259: DBG("Reload eeprom for reading MAC Address error.\n"); ! 1260: goto err_unmap; ! 1261: } ! 1262: jme_load_macaddr(netdev); ! 1263: ! 1264: /* Register network device */ ! 1265: if ((rc = register_netdev(netdev)) != 0) { ! 1266: DBG("Register net_device error.\n"); ! 1267: goto err_unmap; ! 1268: } ! 1269: ! 1270: return 0; ! 1271: ! 1272: err_unmap: ! 1273: iounmap(jme->regs); ! 1274: err_out: ! 1275: netdev_nullify(netdev); ! 1276: netdev_put(netdev); ! 1277: return rc; ! 1278: } ! 1279: ! 1280: /** ! 1281: * Remove PCI device ! 1282: * ! 1283: * @v pci PCI device ! 1284: */ ! 1285: static void ! 1286: jme_remove(struct pci_device *pci) ! 1287: { ! 1288: struct net_device *netdev = pci_get_drvdata(pci); ! 1289: struct jme_adapter *jme = netdev->priv; ! 1290: ! 1291: iounmap(jme->regs); ! 1292: unregister_netdev(netdev); ! 1293: netdev_nullify(netdev); ! 1294: netdev_put(netdev); ! 1295: } ! 1296: ! 1297: static struct pci_device_id jm_nics[] = { ! 1298: PCI_ROM(0x197b, 0x0250, "jme", "JMicron Gigabit Ethernet", 0), ! 1299: PCI_ROM(0x197b, 0x0260, "jmfe", "JMicron Fast Ethernet", 0), ! 1300: }; ! 1301: ! 1302: struct pci_driver jme_driver __pci_driver = { ! 1303: .ids = jm_nics, ! 1304: .id_count = ( sizeof ( jm_nics ) / sizeof ( jm_nics[0] ) ), ! 1305: .probe = jme_probe, ! 1306: .remove = jme_remove, ! 1307: }; ! 1308:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.