Annotation of qemu/roms/ipxe/src/drivers/net/jme.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.