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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2008 Marty Connor <[email protected]>
        !             3:  * Copyright (c) 2008 Entity Cyber, Inc.
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or
        !             6:  * modify it under the terms of the GNU General Public License as
        !             7:  * published by the Free Software Foundation; either version 2 of the
        !             8:  * License, or any later version.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            13:  * 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:  * This driver is based on rtl8169 data sheets and work by:
        !            20:  *
        !            21:  * Copyright (c) 2002 ShuChen <[email protected]>
        !            22:  * Copyright (c) 2003 - 2007 Francois Romieu <[email protected]>
        !            23:  * Copyright (c) a lot of people too. Please respect their work.
        !            24:  */
        !            25: 
        !            26: FILE_LICENCE ( GPL2_OR_LATER );
        !            27: 
        !            28: #include <stdint.h>
        !            29: #include <stdio.h>
        !            30: #include <stdlib.h>
        !            31: #include <string.h>
        !            32: #include <unistd.h>
        !            33: #include <assert.h>
        !            34: #include <byteswap.h>
        !            35: #include <errno.h>
        !            36: #include <ipxe/ethernet.h>
        !            37: #include <ipxe/if_ether.h>
        !            38: #include <ipxe/io.h>
        !            39: #include <ipxe/iobuf.h>
        !            40: #include <ipxe/malloc.h>
        !            41: #include <ipxe/netdevice.h>
        !            42: #include <ipxe/pci.h>
        !            43: #include <ipxe/timer.h>
        !            44: #include <mii.h>
        !            45: 
        !            46: #include "r8169.h"
        !            47: 
        !            48: /*** Low level hardware routines ***/
        !            49: 
        !            50: static void mdio_write(void *ioaddr, int reg_addr, int value)
        !            51: {
        !            52:        int i;
        !            53: 
        !            54:        DBGP ( "mdio_write\n" );
        !            55: 
        !            56:        RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
        !            57: 
        !            58:        for (i = 20; i > 0; i--) {
        !            59:                /*
        !            60:                 * Check if the RTL8169 has completed writing to the specified
        !            61:                 * MII register.
        !            62:                 */
        !            63:                if (!(RTL_R32(PHYAR) & 0x80000000))
        !            64:                        break;
        !            65:                udelay(25);
        !            66:        }
        !            67: }
        !            68: 
        !            69: static int mdio_read(void *ioaddr, int reg_addr)
        !            70: {
        !            71:        int i, value = -1;
        !            72: 
        !            73:        DBGP ( "mdio_read\n" );
        !            74: 
        !            75:        RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
        !            76: 
        !            77:        for (i = 20; i > 0; i--) {
        !            78:                /*
        !            79:                 * Check if the RTL8169 has completed retrieving data from
        !            80:                 * the specified MII register.
        !            81:                 */
        !            82:                if (RTL_R32(PHYAR) & 0x80000000) {
        !            83:                        value = RTL_R32(PHYAR) & 0xffff;
        !            84:                        break;
        !            85:                }
        !            86:                udelay(25);
        !            87:        }
        !            88:        return value;
        !            89: }
        !            90: 
        !            91: static void mdio_patch(void *ioaddr, int reg_addr, int value)
        !            92: {
        !            93:        DBGP ( "mdio_patch\n" );
        !            94: 
        !            95:        mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
        !            96: }
        !            97: 
        !            98: static void rtl_ephy_write(void *ioaddr, int reg_addr, int value)
        !            99: {
        !           100:        unsigned int i;
        !           101: 
        !           102:        DBGP ( "rtl_ephy_write\n" );
        !           103: 
        !           104:        RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
        !           105:                (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
        !           106: 
        !           107:        for (i = 0; i < 100; i++) {
        !           108:                if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
        !           109:                        break;
        !           110:                udelay(10);
        !           111:        }
        !           112: }
        !           113: 
        !           114: static u16 rtl_ephy_read(void *ioaddr, int reg_addr)
        !           115: {
        !           116:        u16 value = 0xffff;
        !           117:        unsigned int i;
        !           118: 
        !           119:        DBGP ( "rtl_ephy_read\n" );
        !           120: 
        !           121:        RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
        !           122: 
        !           123:        for (i = 0; i < 100; i++) {
        !           124:                if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
        !           125:                        value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
        !           126:                        break;
        !           127:                }
        !           128:                udelay(10);
        !           129:        }
        !           130: 
        !           131:        return value;
        !           132: }
        !           133: 
        !           134: static void rtl_csi_write(void *ioaddr, int addr, int value)
        !           135: {
        !           136:        unsigned int i;
        !           137: 
        !           138:        DBGP ( "rtl_csi_write\n" );
        !           139: 
        !           140:        RTL_W32(CSIDR, value);
        !           141:        RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
        !           142:                CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
        !           143: 
        !           144:        for (i = 0; i < 100; i++) {
        !           145:                if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
        !           146:                        break;
        !           147:                udelay(10);
        !           148:        }
        !           149: }
        !           150: 
        !           151: static u32 rtl_csi_read(void *ioaddr, int addr)
        !           152: {
        !           153:        u32 value = ~0x00;
        !           154:        unsigned int i;
        !           155: 
        !           156:        DBGP ( "rtl_csi_read\n" );
        !           157: 
        !           158:        RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
        !           159:                CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
        !           160: 
        !           161:        for (i = 0; i < 100; i++) {
        !           162:                if (RTL_R32(CSIAR) & CSIAR_FLAG) {
        !           163:                        value = RTL_R32(CSIDR);
        !           164:                        break;
        !           165:                }
        !           166:                udelay(10);
        !           167:        }
        !           168: 
        !           169:        return value;
        !           170: }
        !           171: 
        !           172: static void rtl8169_irq_mask_and_ack(void *ioaddr)
        !           173: {
        !           174:        DBGP ( "rtl8169_irq_mask_and_ack\n" );
        !           175: 
        !           176:        RTL_W16(IntrMask, 0x0000);
        !           177: 
        !           178:        RTL_W16(IntrStatus, 0xffff);
        !           179: }
        !           180: 
        !           181: static unsigned int rtl8169_tbi_reset_pending(void *ioaddr)
        !           182: {
        !           183:        DBGP ( "rtl8169_tbi_reset_pending\n" );
        !           184: 
        !           185:        return RTL_R32(TBICSR) & TBIReset;
        !           186: }
        !           187: 
        !           188: static unsigned int rtl8169_xmii_reset_pending(void *ioaddr)
        !           189: {
        !           190:        DBGP ( "rtl8169_xmii_reset_pending\n" );
        !           191: 
        !           192:        return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET;
        !           193: }
        !           194: 
        !           195: static unsigned int rtl8169_tbi_link_ok(void *ioaddr)
        !           196: {
        !           197:        DBGP ( "rtl8169_tbi_link_ok\n" );
        !           198: 
        !           199:        return RTL_R32(TBICSR) & TBILinkOk;
        !           200: }
        !           201: 
        !           202: static unsigned int rtl8169_xmii_link_ok(void *ioaddr)
        !           203: {
        !           204:        DBGP ( "rtl8169_xmii_link_ok\n" );
        !           205: 
        !           206:        return RTL_R8(PHYstatus) & LinkStatus;
        !           207: }
        !           208: 
        !           209: static void rtl8169_tbi_reset_enable(void *ioaddr)
        !           210: {
        !           211:        DBGP ( "rtl8169_tbi_reset_enable\n" );
        !           212: 
        !           213:        RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
        !           214: }
        !           215: 
        !           216: static void rtl8169_xmii_reset_enable(void *ioaddr)
        !           217: {
        !           218:        unsigned int val;
        !           219: 
        !           220:        DBGP ( "rtl8169_xmii_reset_enable\n" );
        !           221: 
        !           222:        val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
        !           223:        mdio_write(ioaddr, MII_BMCR, val & 0xffff);
        !           224: }
        !           225: 
        !           226: static int rtl8169_set_speed_tbi(struct net_device *dev,
        !           227:                                 u8 autoneg, u16 speed, u8 duplex)
        !           228: {
        !           229:        struct rtl8169_private *tp = netdev_priv(dev);
        !           230:        void *ioaddr = tp->mmio_addr;
        !           231:        int ret = 0;
        !           232:        u32 reg;
        !           233: 
        !           234:        DBGP ( "rtl8169_set_speed_tbi\n" );
        !           235: 
        !           236:        reg = RTL_R32(TBICSR);
        !           237:        if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) &&
        !           238:            (duplex == DUPLEX_FULL)) {
        !           239:                RTL_W32(TBICSR, reg & ~(TBINwEnable | TBINwRestart));
        !           240:        } else if (autoneg == AUTONEG_ENABLE)
        !           241:                RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
        !           242:        else {
        !           243:                DBG ( "incorrect speed setting refused in TBI mode\n" );
        !           244:                ret = -EOPNOTSUPP;
        !           245:        }
        !           246:        return ret;
        !           247: }
        !           248: 
        !           249: static int rtl8169_set_speed_xmii(struct net_device *dev,
        !           250:                                  u8 autoneg, u16 speed, u8 duplex)
        !           251: {
        !           252:        struct rtl8169_private *tp = netdev_priv(dev);
        !           253:        void *ioaddr = tp->mmio_addr;
        !           254:        int auto_nego, giga_ctrl;
        !           255: 
        !           256:        DBGP ( "rtl8169_set_speed_xmii\n" );
        !           257: 
        !           258:        auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
        !           259:        auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
        !           260:                       ADVERTISE_100HALF | ADVERTISE_100FULL);
        !           261:        giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
        !           262:        giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
        !           263: 
        !           264:        if (autoneg == AUTONEG_ENABLE) {
        !           265:                auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
        !           266:                              ADVERTISE_100HALF | ADVERTISE_100FULL);
        !           267:                giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
        !           268:        } else {
        !           269:                if (speed == SPEED_10)
        !           270:                        auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
        !           271:                else if (speed == SPEED_100)
        !           272:                        auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
        !           273:                else if (speed == SPEED_1000)
        !           274:                        giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
        !           275: 
        !           276:                if (duplex == DUPLEX_HALF)
        !           277:                        auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
        !           278: 
        !           279:                if (duplex == DUPLEX_FULL)
        !           280:                        auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
        !           281: 
        !           282:                /* This tweak comes straight from Realtek's driver. */
        !           283:                if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
        !           284:                    ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
        !           285:                     (tp->mac_version == RTL_GIGA_MAC_VER_16))) {
        !           286:                        auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
        !           287:                }
        !           288:        }
        !           289: 
        !           290:        /* The 8100e/8101e/8102e do Fast Ethernet only. */
        !           291:        if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
        !           292:            (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
        !           293:            (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
        !           294:            (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
        !           295:            (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
        !           296:            (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
        !           297:            (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
        !           298:            (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
        !           299:                if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF))) {
        !           300:                        DBG ( "PHY does not support 1000Mbps.\n" );
        !           301:                }
        !           302:                giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
        !           303:        }
        !           304: 
        !           305:        auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
        !           306: 
        !           307:        if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
        !           308:            (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
        !           309:            (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
        !           310:                /*
        !           311:                 * Wake up the PHY.
        !           312:                 * Vendor specific (0x1f) and reserved (0x0e) MII registers.
        !           313:                 */
        !           314:                mdio_write(ioaddr, 0x1f, 0x0000);
        !           315:                mdio_write(ioaddr, 0x0e, 0x0000);
        !           316:        }
        !           317: 
        !           318:        tp->phy_auto_nego_reg = auto_nego;
        !           319:        tp->phy_1000_ctrl_reg = giga_ctrl;
        !           320: 
        !           321:        mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
        !           322:        mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
        !           323:        mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
        !           324:        return 0;
        !           325: }
        !           326: 
        !           327: static int rtl8169_set_speed(struct net_device *dev,
        !           328:                             u8 autoneg, u16 speed, u8 duplex)
        !           329: {
        !           330:        struct rtl8169_private *tp = netdev_priv(dev);
        !           331:        int ret;
        !           332: 
        !           333:        DBGP ( "rtl8169_set_speed\n" );
        !           334: 
        !           335:        ret = tp->set_speed(dev, autoneg, speed, duplex);
        !           336: 
        !           337:        return ret;
        !           338: }
        !           339: 
        !           340: static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg,
        !           341:                                       int bitnum, int bitval)
        !           342: {
        !           343:        int val;
        !           344: 
        !           345:        DBGP ( "rtl8169_write_gmii_reg_bit\n" );
        !           346: 
        !           347:        val = mdio_read(ioaddr, reg);
        !           348:        val = (bitval == 1) ?
        !           349:                val | (bitval << bitnum) :  val & ~(0x0001 << bitnum);
        !           350:        mdio_write(ioaddr, reg, val & 0xffff);
        !           351: }
        !           352: 
        !           353: static void rtl8169_get_mac_version(struct rtl8169_private *tp,
        !           354:                                    void *ioaddr)
        !           355: {
        !           356:        /*
        !           357:         * The driver currently handles the 8168Bf and the 8168Be identically
        !           358:         * but they can be identified more specifically through the test below
        !           359:         * if needed:
        !           360:         *
        !           361:         * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
        !           362:         *
        !           363:         * Same thing for the 8101Eb and the 8101Ec:
        !           364:         *
        !           365:         * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
        !           366:         */
        !           367:        const struct {
        !           368:                u32 mask;
        !           369:                u32 val;
        !           370:                int mac_version;
        !           371:        } mac_info[] = {
        !           372:                /* 8168D family. */
        !           373:                { 0x7c800000, 0x28000000,       RTL_GIGA_MAC_VER_25 },
        !           374: 
        !           375:                /* 8168C family. */
        !           376:                { 0x7cf00000, 0x3ca00000,       RTL_GIGA_MAC_VER_24 },
        !           377:                { 0x7cf00000, 0x3c900000,       RTL_GIGA_MAC_VER_23 },
        !           378:                { 0x7cf00000, 0x3c800000,       RTL_GIGA_MAC_VER_18 },
        !           379:                { 0x7c800000, 0x3c800000,       RTL_GIGA_MAC_VER_24 },
        !           380:                { 0x7cf00000, 0x3c000000,       RTL_GIGA_MAC_VER_19 },
        !           381:                { 0x7cf00000, 0x3c200000,       RTL_GIGA_MAC_VER_20 },
        !           382:                { 0x7cf00000, 0x3c300000,       RTL_GIGA_MAC_VER_21 },
        !           383:                { 0x7cf00000, 0x3c400000,       RTL_GIGA_MAC_VER_22 },
        !           384:                { 0x7c800000, 0x3c000000,       RTL_GIGA_MAC_VER_22 },
        !           385: 
        !           386:                /* 8168B family. */
        !           387:                { 0x7cf00000, 0x38000000,       RTL_GIGA_MAC_VER_12 },
        !           388:                { 0x7cf00000, 0x38500000,       RTL_GIGA_MAC_VER_17 },
        !           389:                { 0x7c800000, 0x38000000,       RTL_GIGA_MAC_VER_17 },
        !           390:                { 0x7c800000, 0x30000000,       RTL_GIGA_MAC_VER_11 },
        !           391: 
        !           392:                /* 8101 family. */
        !           393:                { 0x7cf00000, 0x34a00000,       RTL_GIGA_MAC_VER_09 },
        !           394:                { 0x7cf00000, 0x24a00000,       RTL_GIGA_MAC_VER_09 },
        !           395:                { 0x7cf00000, 0x34900000,       RTL_GIGA_MAC_VER_08 },
        !           396:                { 0x7cf00000, 0x24900000,       RTL_GIGA_MAC_VER_08 },
        !           397:                { 0x7cf00000, 0x34800000,       RTL_GIGA_MAC_VER_07 },
        !           398:                { 0x7cf00000, 0x24800000,       RTL_GIGA_MAC_VER_07 },
        !           399:                { 0x7cf00000, 0x34000000,       RTL_GIGA_MAC_VER_13 },
        !           400:                { 0x7cf00000, 0x34300000,       RTL_GIGA_MAC_VER_10 },
        !           401:                { 0x7cf00000, 0x34200000,       RTL_GIGA_MAC_VER_16 },
        !           402:                { 0x7c800000, 0x34800000,       RTL_GIGA_MAC_VER_09 },
        !           403:                { 0x7c800000, 0x24800000,       RTL_GIGA_MAC_VER_09 },
        !           404:                { 0x7c800000, 0x34000000,       RTL_GIGA_MAC_VER_16 },
        !           405:                /* FIXME: where did these entries come from ? -- FR */
        !           406:                { 0xfc800000, 0x38800000,       RTL_GIGA_MAC_VER_15 },
        !           407:                { 0xfc800000, 0x30800000,       RTL_GIGA_MAC_VER_14 },
        !           408: 
        !           409:                /* 8110 family. */
        !           410:                { 0xfc800000, 0x98000000,       RTL_GIGA_MAC_VER_06 },
        !           411:                { 0xfc800000, 0x18000000,       RTL_GIGA_MAC_VER_05 },
        !           412:                { 0xfc800000, 0x10000000,       RTL_GIGA_MAC_VER_04 },
        !           413:                { 0xfc800000, 0x04000000,       RTL_GIGA_MAC_VER_03 },
        !           414:                { 0xfc800000, 0x00800000,       RTL_GIGA_MAC_VER_02 },
        !           415:                { 0xfc800000, 0x00000000,       RTL_GIGA_MAC_VER_01 },
        !           416: 
        !           417:                { 0x00000000, 0x00000000,       RTL_GIGA_MAC_VER_01 }   /* Catch-all */
        !           418:        }, *p = mac_info;
        !           419:        u32 reg;
        !           420: 
        !           421:        DBGP ( "rtl8169_get_mac_version\n" );
        !           422: 
        !           423:        reg = RTL_R32(TxConfig);
        !           424:        while ((reg & p->mask) != p->val)
        !           425:                p++;
        !           426:        tp->mac_version = p->mac_version;
        !           427: 
        !           428:        DBG ( "tp->mac_version = %d\n", tp->mac_version );
        !           429: 
        !           430:        if (p->mask == 0x00000000) {
        !           431:                DBG ( "unknown MAC (%08x)\n", reg );
        !           432:        }
        !           433: }
        !           434: 
        !           435: struct phy_reg {
        !           436:        u16 reg;
        !           437:        u16 val;
        !           438: };
        !           439: 
        !           440: static void rtl_phy_write(void *ioaddr, struct phy_reg *regs, int len)
        !           441: {
        !           442:        DBGP ( "rtl_phy_write\n" );
        !           443: 
        !           444:        while (len-- > 0) {
        !           445:                mdio_write(ioaddr, regs->reg, regs->val);
        !           446:                regs++;
        !           447:        }
        !           448: }
        !           449: 
        !           450: static void rtl8169s_hw_phy_config(void *ioaddr)
        !           451: {
        !           452:        struct {
        !           453:                u16 regs[5]; /* Beware of bit-sign propagation */
        !           454:        } phy_magic[5] = { {
        !           455:                { 0x0000,       //w 4 15 12 0
        !           456:                  0x00a1,       //w 3 15 0 00a1
        !           457:                  0x0008,       //w 2 15 0 0008
        !           458:                  0x1020,       //w 1 15 0 1020
        !           459:                  0x1000 } },{  //w 0 15 0 1000
        !           460:                { 0x7000,       //w 4 15 12 7
        !           461:                  0xff41,       //w 3 15 0 ff41
        !           462:                  0xde60,       //w 2 15 0 de60
        !           463:                  0x0140,       //w 1 15 0 0140
        !           464:                  0x0077 } },{  //w 0 15 0 0077
        !           465:                { 0xa000,       //w 4 15 12 a
        !           466:                  0xdf01,       //w 3 15 0 df01
        !           467:                  0xdf20,       //w 2 15 0 df20
        !           468:                  0xff95,       //w 1 15 0 ff95
        !           469:                  0xfa00 } },{  //w 0 15 0 fa00
        !           470:                { 0xb000,       //w 4 15 12 b
        !           471:                  0xff41,       //w 3 15 0 ff41
        !           472:                  0xde20,       //w 2 15 0 de20
        !           473:                  0x0140,       //w 1 15 0 0140
        !           474:                  0x00bb } },{  //w 0 15 0 00bb
        !           475:                { 0xf000,       //w 4 15 12 f
        !           476:                  0xdf01,       //w 3 15 0 df01
        !           477:                  0xdf20,       //w 2 15 0 df20
        !           478:                  0xff95,       //w 1 15 0 ff95
        !           479:                  0xbf00 }      //w 0 15 0 bf00
        !           480:                }
        !           481:        }, *p = phy_magic;
        !           482:        unsigned int i;
        !           483: 
        !           484:        DBGP ( "rtl8169s_hw_phy_config\n" );
        !           485: 
        !           486:        mdio_write(ioaddr, 0x1f, 0x0001);               //w 31 2 0 1
        !           487:        mdio_write(ioaddr, 0x15, 0x1000);               //w 21 15 0 1000
        !           488:        mdio_write(ioaddr, 0x18, 0x65c7);               //w 24 15 0 65c7
        !           489:        rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0);   //w 4 11 11 0
        !           490: 
        !           491:        for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) {
        !           492:                int val, pos = 4;
        !           493: 
        !           494:                val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff);
        !           495:                mdio_write(ioaddr, pos, val);
        !           496:                while (--pos >= 0)
        !           497:                        mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff);
        !           498:                rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1
        !           499:                rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
        !           500:        }
        !           501:        mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0
        !           502: }
        !           503: 
        !           504: static void rtl8169sb_hw_phy_config(void *ioaddr)
        !           505: {
        !           506:        struct phy_reg phy_reg_init[] = {
        !           507:                { 0x1f, 0x0002 },
        !           508:                { 0x01, 0x90d0 },
        !           509:                { 0x1f, 0x0000 }
        !           510:        };
        !           511: 
        !           512:        DBGP ( "rtl8169sb_hw_phy_config\n" );
        !           513: 
        !           514:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           515: }
        !           516: 
        !           517: static void rtl8168bb_hw_phy_config(void *ioaddr)
        !           518: {
        !           519:        struct phy_reg phy_reg_init[] = {
        !           520:                { 0x10, 0xf41b },
        !           521:                { 0x1f, 0x0000 }
        !           522:        };
        !           523: 
        !           524:        mdio_write(ioaddr, 0x1f, 0x0001);
        !           525:        mdio_patch(ioaddr, 0x16, 1 << 0);
        !           526: 
        !           527:        DBGP ( "rtl8168bb_hw_phy_config\n" );
        !           528: 
        !           529:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           530: }
        !           531: 
        !           532: static void rtl8168bef_hw_phy_config(void *ioaddr)
        !           533: {
        !           534:        struct phy_reg phy_reg_init[] = {
        !           535:                { 0x1f, 0x0001 },
        !           536:                { 0x10, 0xf41b },
        !           537:                { 0x1f, 0x0000 }
        !           538:        };
        !           539: 
        !           540:        DBGP ( "rtl8168bef_hw_phy_config\n" );
        !           541: 
        !           542:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           543: }
        !           544: 
        !           545: static void rtl8168cp_1_hw_phy_config(void *ioaddr)
        !           546: {
        !           547:        struct phy_reg phy_reg_init[] = {
        !           548:                { 0x1f, 0x0000 },
        !           549:                { 0x1d, 0x0f00 },
        !           550:                { 0x1f, 0x0002 },
        !           551:                { 0x0c, 0x1ec8 },
        !           552:                { 0x1f, 0x0000 }
        !           553:        };
        !           554: 
        !           555:        DBGP ( "rtl8168cp_1_hw_phy_config\n" );
        !           556: 
        !           557:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           558: }
        !           559: 
        !           560: static void rtl8168cp_2_hw_phy_config(void *ioaddr)
        !           561: {
        !           562:        struct phy_reg phy_reg_init[] = {
        !           563:                { 0x1f, 0x0001 },
        !           564:                { 0x1d, 0x3d98 },
        !           565:                { 0x1f, 0x0000 }
        !           566:        };
        !           567: 
        !           568:        DBGP ( "rtl8168cp_2_hw_phy_config\n" );
        !           569: 
        !           570:        mdio_write(ioaddr, 0x1f, 0x0000);
        !           571:        mdio_patch(ioaddr, 0x14, 1 << 5);
        !           572:        mdio_patch(ioaddr, 0x0d, 1 << 5);
        !           573: 
        !           574:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           575: }
        !           576: 
        !           577: static void rtl8168c_1_hw_phy_config(void *ioaddr)
        !           578: {
        !           579:        struct phy_reg phy_reg_init[] = {
        !           580:                { 0x1f, 0x0001 },
        !           581:                { 0x12, 0x2300 },
        !           582:                { 0x1f, 0x0002 },
        !           583:                { 0x00, 0x88d4 },
        !           584:                { 0x01, 0x82b1 },
        !           585:                { 0x03, 0x7002 },
        !           586:                { 0x08, 0x9e30 },
        !           587:                { 0x09, 0x01f0 },
        !           588:                { 0x0a, 0x5500 },
        !           589:                { 0x0c, 0x00c8 },
        !           590:                { 0x1f, 0x0003 },
        !           591:                { 0x12, 0xc096 },
        !           592:                { 0x16, 0x000a },
        !           593:                { 0x1f, 0x0000 },
        !           594:                { 0x1f, 0x0000 },
        !           595:                { 0x09, 0x2000 },
        !           596:                { 0x09, 0x0000 }
        !           597:        };
        !           598: 
        !           599:        DBGP ( "rtl8168c_1_hw_phy_config\n" );
        !           600: 
        !           601:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           602: 
        !           603:        mdio_patch(ioaddr, 0x14, 1 << 5);
        !           604:        mdio_patch(ioaddr, 0x0d, 1 << 5);
        !           605:        mdio_write(ioaddr, 0x1f, 0x0000);
        !           606: }
        !           607: 
        !           608: static void rtl8168c_2_hw_phy_config(void *ioaddr)
        !           609: {
        !           610:        struct phy_reg phy_reg_init[] = {
        !           611:                { 0x1f, 0x0001 },
        !           612:                { 0x12, 0x2300 },
        !           613:                { 0x03, 0x802f },
        !           614:                { 0x02, 0x4f02 },
        !           615:                { 0x01, 0x0409 },
        !           616:                { 0x00, 0xf099 },
        !           617:                { 0x04, 0x9800 },
        !           618:                { 0x04, 0x9000 },
        !           619:                { 0x1d, 0x3d98 },
        !           620:                { 0x1f, 0x0002 },
        !           621:                { 0x0c, 0x7eb8 },
        !           622:                { 0x06, 0x0761 },
        !           623:                { 0x1f, 0x0003 },
        !           624:                { 0x16, 0x0f0a },
        !           625:                { 0x1f, 0x0000 }
        !           626:        };
        !           627: 
        !           628:        DBGP ( "rtl8168c_2_hw_phy_config\n" );
        !           629: 
        !           630:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           631: 
        !           632:        mdio_patch(ioaddr, 0x16, 1 << 0);
        !           633:        mdio_patch(ioaddr, 0x14, 1 << 5);
        !           634:        mdio_patch(ioaddr, 0x0d, 1 << 5);
        !           635:        mdio_write(ioaddr, 0x1f, 0x0000);
        !           636: }
        !           637: 
        !           638: static void rtl8168c_3_hw_phy_config(void *ioaddr)
        !           639: {
        !           640:        struct phy_reg phy_reg_init[] = {
        !           641:                { 0x1f, 0x0001 },
        !           642:                { 0x12, 0x2300 },
        !           643:                { 0x1d, 0x3d98 },
        !           644:                { 0x1f, 0x0002 },
        !           645:                { 0x0c, 0x7eb8 },
        !           646:                { 0x06, 0x5461 },
        !           647:                { 0x1f, 0x0003 },
        !           648:                { 0x16, 0x0f0a },
        !           649:                { 0x1f, 0x0000 }
        !           650:        };
        !           651: 
        !           652:        DBGP ( "rtl8168c_3_hw_phy_config\n" );
        !           653: 
        !           654:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           655: 
        !           656:        mdio_patch(ioaddr, 0x16, 1 << 0);
        !           657:        mdio_patch(ioaddr, 0x14, 1 << 5);
        !           658:        mdio_patch(ioaddr, 0x0d, 1 << 5);
        !           659:        mdio_write(ioaddr, 0x1f, 0x0000);
        !           660: }
        !           661: 
        !           662: static void rtl8168c_4_hw_phy_config(void *ioaddr)
        !           663: {
        !           664:        DBGP ( "rtl8168c_4_hw_phy_config\n" );
        !           665: 
        !           666:        rtl8168c_3_hw_phy_config(ioaddr);
        !           667: }
        !           668: 
        !           669: static void rtl8168d_hw_phy_config(void *ioaddr)
        !           670: {
        !           671:        struct phy_reg phy_reg_init_0[] = {
        !           672:                { 0x1f, 0x0001 },
        !           673:                { 0x09, 0x2770 },
        !           674:                { 0x08, 0x04d0 },
        !           675:                { 0x0b, 0xad15 },
        !           676:                { 0x0c, 0x5bf0 },
        !           677:                { 0x1c, 0xf101 },
        !           678:                { 0x1f, 0x0003 },
        !           679:                { 0x14, 0x94d7 },
        !           680:                { 0x12, 0xf4d6 },
        !           681:                { 0x09, 0xca0f },
        !           682:                { 0x1f, 0x0002 },
        !           683:                { 0x0b, 0x0b10 },
        !           684:                { 0x0c, 0xd1f7 },
        !           685:                { 0x1f, 0x0002 },
        !           686:                { 0x06, 0x5461 },
        !           687:                { 0x1f, 0x0002 },
        !           688:                { 0x05, 0x6662 },
        !           689:                { 0x1f, 0x0000 },
        !           690:                { 0x14, 0x0060 },
        !           691:                { 0x1f, 0x0000 },
        !           692:                { 0x0d, 0xf8a0 },
        !           693:                { 0x1f, 0x0005 },
        !           694:                { 0x05, 0xffc2 }
        !           695:        };
        !           696: 
        !           697:        DBGP ( "rtl8168d_hw_phy_config\n" );
        !           698: 
        !           699:        rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
        !           700: 
        !           701:        if (mdio_read(ioaddr, 0x06) == 0xc400) {
        !           702:                struct phy_reg phy_reg_init_1[] = {
        !           703:                        { 0x1f, 0x0005 },
        !           704:                        { 0x01, 0x0300 },
        !           705:                        { 0x1f, 0x0000 },
        !           706:                        { 0x11, 0x401c },
        !           707:                        { 0x16, 0x4100 },
        !           708:                        { 0x1f, 0x0005 },
        !           709:                        { 0x07, 0x0010 },
        !           710:                        { 0x05, 0x83dc },
        !           711:                        { 0x06, 0x087d },
        !           712:                        { 0x05, 0x8300 },
        !           713:                        { 0x06, 0x0101 },
        !           714:                        { 0x06, 0x05f8 },
        !           715:                        { 0x06, 0xf9fa },
        !           716:                        { 0x06, 0xfbef },
        !           717:                        { 0x06, 0x79e2 },
        !           718:                        { 0x06, 0x835f },
        !           719:                        { 0x06, 0xe0f8 },
        !           720:                        { 0x06, 0x9ae1 },
        !           721:                        { 0x06, 0xf89b },
        !           722:                        { 0x06, 0xef31 },
        !           723:                        { 0x06, 0x3b65 },
        !           724:                        { 0x06, 0xaa07 },
        !           725:                        { 0x06, 0x81e4 },
        !           726:                        { 0x06, 0xf89a },
        !           727:                        { 0x06, 0xe5f8 },
        !           728:                        { 0x06, 0x9baf },
        !           729:                        { 0x06, 0x06ae },
        !           730:                        { 0x05, 0x83dc },
        !           731:                        { 0x06, 0x8300 },
        !           732:                };
        !           733: 
        !           734:                rtl_phy_write(ioaddr, phy_reg_init_1,
        !           735:                              ARRAY_SIZE(phy_reg_init_1));
        !           736:        }
        !           737: 
        !           738:        mdio_write(ioaddr, 0x1f, 0x0000);
        !           739: }
        !           740: 
        !           741: static void rtl8102e_hw_phy_config(void *ioaddr)
        !           742: {
        !           743:        struct phy_reg phy_reg_init[] = {
        !           744:                { 0x1f, 0x0003 },
        !           745:                { 0x08, 0x441d },
        !           746:                { 0x01, 0x9100 },
        !           747:                { 0x1f, 0x0000 }
        !           748:        };
        !           749: 
        !           750:        DBGP ( "rtl8102e_hw_phy_config\n" );
        !           751: 
        !           752:        mdio_write(ioaddr, 0x1f, 0x0000);
        !           753:        mdio_patch(ioaddr, 0x11, 1 << 12);
        !           754:        mdio_patch(ioaddr, 0x19, 1 << 13);
        !           755: 
        !           756:        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        !           757: }
        !           758: 
        !           759: static void rtl_hw_phy_config(struct net_device *dev)
        !           760: {
        !           761:        struct rtl8169_private *tp = netdev_priv(dev);
        !           762:        void *ioaddr = tp->mmio_addr;
        !           763: 
        !           764:        DBGP ( "rtl_hw_phy_config\n" );
        !           765: 
        !           766:        DBG ( "mac_version = 0x%02x\n", tp->mac_version );
        !           767: 
        !           768:        switch (tp->mac_version) {
        !           769:        case RTL_GIGA_MAC_VER_01:
        !           770:                break;
        !           771:        case RTL_GIGA_MAC_VER_02:
        !           772:        case RTL_GIGA_MAC_VER_03:
        !           773:                rtl8169s_hw_phy_config(ioaddr);
        !           774:                break;
        !           775:        case RTL_GIGA_MAC_VER_04:
        !           776:                rtl8169sb_hw_phy_config(ioaddr);
        !           777:                break;
        !           778:        case RTL_GIGA_MAC_VER_07:
        !           779:        case RTL_GIGA_MAC_VER_08:
        !           780:        case RTL_GIGA_MAC_VER_09:
        !           781:                rtl8102e_hw_phy_config(ioaddr);
        !           782:                break;
        !           783:        case RTL_GIGA_MAC_VER_11:
        !           784:                rtl8168bb_hw_phy_config(ioaddr);
        !           785:                break;
        !           786:        case RTL_GIGA_MAC_VER_12:
        !           787:                rtl8168bef_hw_phy_config(ioaddr);
        !           788:                break;
        !           789:        case RTL_GIGA_MAC_VER_17:
        !           790:                rtl8168bef_hw_phy_config(ioaddr);
        !           791:                break;
        !           792:        case RTL_GIGA_MAC_VER_18:
        !           793:                rtl8168cp_1_hw_phy_config(ioaddr);
        !           794:                break;
        !           795:        case RTL_GIGA_MAC_VER_19:
        !           796:                rtl8168c_1_hw_phy_config(ioaddr);
        !           797:                break;
        !           798:        case RTL_GIGA_MAC_VER_20:
        !           799:                rtl8168c_2_hw_phy_config(ioaddr);
        !           800:                break;
        !           801:        case RTL_GIGA_MAC_VER_21:
        !           802:                rtl8168c_3_hw_phy_config(ioaddr);
        !           803:                break;
        !           804:        case RTL_GIGA_MAC_VER_22:
        !           805:                rtl8168c_4_hw_phy_config(ioaddr);
        !           806:                break;
        !           807:        case RTL_GIGA_MAC_VER_23:
        !           808:        case RTL_GIGA_MAC_VER_24:
        !           809:                rtl8168cp_2_hw_phy_config(ioaddr);
        !           810:                break;
        !           811:        case RTL_GIGA_MAC_VER_25:
        !           812:                rtl8168d_hw_phy_config(ioaddr);
        !           813:                break;
        !           814: 
        !           815:        default:
        !           816:                break;
        !           817:        }
        !           818: }
        !           819: 
        !           820: static void rtl8169_phy_reset(struct net_device *dev __unused,
        !           821:                              struct rtl8169_private *tp)
        !           822: {
        !           823:        void *ioaddr = tp->mmio_addr;
        !           824:        unsigned int i;
        !           825: 
        !           826:        DBGP ( "rtl8169_phy_reset\n" );
        !           827: 
        !           828:        tp->phy_reset_enable(ioaddr);
        !           829:        for (i = 0; i < 100; i++) {
        !           830:                if (!tp->phy_reset_pending(ioaddr))
        !           831:                        return;
        !           832:                mdelay ( 1 );
        !           833:        }
        !           834:        DBG ( "PHY reset failed.\n" );
        !           835: }
        !           836: 
        !           837: static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
        !           838: {
        !           839:        void *ioaddr = tp->mmio_addr;
        !           840: 
        !           841:        DBGP ( "rtl8169_init_phy\n" );
        !           842: 
        !           843:        rtl_hw_phy_config(dev);
        !           844: 
        !           845:        if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
        !           846:                DBG ( "Set MAC Reg C+CR Offset 0x82h = 0x01h\n" );
        !           847:                RTL_W8(0x82, 0x01);
        !           848:        }
        !           849: 
        !           850:        pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
        !           851: 
        !           852:        if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
        !           853:                pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
        !           854: 
        !           855:        if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
        !           856:                DBG ( "Set MAC Reg C+CR Offset 0x82h = 0x01h\n" );
        !           857:                RTL_W8(0x82, 0x01);
        !           858:                DBG ( "Set PHY Reg 0x0bh = 0x00h\n" );
        !           859:                mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
        !           860:        }
        !           861: 
        !           862:        rtl8169_phy_reset(dev, tp);
        !           863: 
        !           864:        /*
        !           865:         * rtl8169_set_speed_xmii takes good care of the Fast Ethernet
        !           866:         * only 8101. Don't panic.
        !           867:         */
        !           868:        rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
        !           869: 
        !           870:        if ((RTL_R8(PHYstatus) & TBI_Enable))
        !           871:                DBG ( "TBI auto-negotiating\n" );
        !           872: }
        !           873: 
        !           874: static const struct rtl_cfg_info {
        !           875:        void (*hw_start)(struct net_device *);
        !           876:        unsigned int region;
        !           877:        unsigned int align;
        !           878:        u16 intr_event;
        !           879:        u16 napi_event;
        !           880:        unsigned features;
        !           881: } rtl_cfg_infos [] = {
        !           882:        [RTL_CFG_0] = {
        !           883:                .hw_start       = rtl_hw_start_8169,
        !           884:                .region         = 1,
        !           885:                .align          = 0,
        !           886:                .intr_event     = SYSErr | LinkChg | RxOverflow |
        !           887:                                  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
        !           888:                .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
        !           889:                .features       = RTL_FEATURE_GMII
        !           890:        },
        !           891:        [RTL_CFG_1] = {
        !           892:                .hw_start       = rtl_hw_start_8168,
        !           893:                .region         = 2,
        !           894:                .align          = 8,
        !           895:                .intr_event     = SYSErr | LinkChg | RxOverflow |
        !           896:                                  TxErr | TxOK | RxOK | RxErr,
        !           897:                .napi_event     = TxErr | TxOK | RxOK | RxOverflow,
        !           898:                .features       = RTL_FEATURE_GMII
        !           899:        },
        !           900:        [RTL_CFG_2] = {
        !           901:                .hw_start       = rtl_hw_start_8101,
        !           902:                .region         = 2,
        !           903:                .align          = 8,
        !           904:                .intr_event     = SYSErr | LinkChg | RxOverflow | PCSTimeout |
        !           905:                                  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
        !           906:                .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
        !           907:        }
        !           908: };
        !           909: 
        !           910: static void rtl8169_hw_reset(void *ioaddr)
        !           911: {
        !           912:        DBGP ( "rtl8169_hw_reset\n" );
        !           913: 
        !           914:        /* Disable interrupts */
        !           915:        rtl8169_irq_mask_and_ack(ioaddr);
        !           916: 
        !           917:        /* Reset the chipset */
        !           918:        RTL_W8(ChipCmd, CmdReset);
        !           919: 
        !           920:        /* PCI commit */
        !           921:        RTL_R8(ChipCmd);
        !           922: }
        !           923: 
        !           924: static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
        !           925: {
        !           926:        void *ioaddr = tp->mmio_addr;
        !           927:        u32 cfg = rtl8169_rx_config;
        !           928: 
        !           929:        DBGP ( "rtl_set_rx_tx_config_registers\n" );
        !           930: 
        !           931:        cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
        !           932:        RTL_W32(RxConfig, cfg);
        !           933: 
        !           934:        /* Set DMA burst size and Interframe Gap Time */
        !           935:        RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
        !           936:                (InterFrameGap << TxInterFrameGapShift));
        !           937: }
        !           938: 
        !           939: static void rtl_soft_reset ( struct net_device *dev )
        !           940: {
        !           941:        struct rtl8169_private *tp = netdev_priv(dev);
        !           942:        void *ioaddr = tp->mmio_addr;
        !           943:        unsigned int i;
        !           944: 
        !           945:        DBGP ( "rtl_hw_soft_reset\n" );
        !           946: 
        !           947:        /* Soft reset the chip. */
        !           948:        RTL_W8(ChipCmd, CmdReset);
        !           949: 
        !           950:        /* Check that the chip has finished the reset. */
        !           951:        for (i = 0; i < 100; i++) {
        !           952:                if ((RTL_R8(ChipCmd) & CmdReset) == 0)
        !           953:                        break;
        !           954:                mdelay ( 1 );
        !           955:        }
        !           956: 
        !           957:        if ( i == 100 ) {
        !           958:                DBG ( "Reset Failed! (> 100 iterations)\n" );
        !           959:        }
        !           960: }
        !           961: 
        !           962: static void rtl_hw_start ( struct net_device *dev )
        !           963: {
        !           964:        struct rtl8169_private *tp = netdev_priv ( dev );
        !           965: 
        !           966:        DBGP ( "rtl_hw_start\n" );
        !           967: 
        !           968:        /* Soft reset NIC */
        !           969:        rtl_soft_reset ( dev );
        !           970: 
        !           971:        tp->hw_start ( dev );
        !           972: }
        !           973: 
        !           974: static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
        !           975:                                         void *ioaddr)
        !           976: {
        !           977:        DBGP ( "rtl_set_rx_tx_desc_registers\n" );
        !           978: 
        !           979:        /*
        !           980:         * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
        !           981:         * register to be written before TxDescAddrLow to work.
        !           982:         * Switching from MMIO to I/O access fixes the issue as well.
        !           983:         */
        !           984:        RTL_W32 ( TxDescStartAddrHigh, 0 );
        !           985:        RTL_W32 ( TxDescStartAddrLow, virt_to_bus ( tp->tx_base ) );
        !           986:        RTL_W32 ( RxDescAddrHigh, 0 );
        !           987:        RTL_W32 ( RxDescAddrLow, virt_to_bus ( tp->rx_base ) );
        !           988: }
        !           989: 
        !           990: static u16 rtl_rw_cpluscmd(void *ioaddr)
        !           991: {
        !           992:        u16 cmd;
        !           993: 
        !           994:        DBGP ( "rtl_rw_cpluscmd\n" );
        !           995: 
        !           996:        cmd = RTL_R16(CPlusCmd);
        !           997:        RTL_W16(CPlusCmd, cmd);
        !           998:        return cmd;
        !           999: }
        !          1000: 
        !          1001: static void rtl_set_rx_max_size(void *ioaddr)
        !          1002: {
        !          1003:        DBGP ( "rtl_set_rx_max_size\n" );
        !          1004: 
        !          1005:        RTL_W16 ( RxMaxSize, RX_BUF_SIZE );
        !          1006: }
        !          1007: 
        !          1008: static void rtl8169_set_magic_reg(void *ioaddr, unsigned mac_version)
        !          1009: {
        !          1010:        struct {
        !          1011:                u32 mac_version;
        !          1012:                u32 clk;
        !          1013:                u32 val;
        !          1014:        } cfg2_info [] = {
        !          1015:                { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd
        !          1016:                { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
        !          1017:                { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
        !          1018:                { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
        !          1019:        }, *p = cfg2_info;
        !          1020:        unsigned int i;
        !          1021:        u32 clk;
        !          1022: 
        !          1023:        DBGP ( "rtl8169_set_magic_reg\n" );
        !          1024: 
        !          1025:        clk = RTL_R8(Config2) & PCI_Clock_66MHz;
        !          1026:        for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) {
        !          1027:                if ((p->mac_version == mac_version) && (p->clk == clk)) {
        !          1028:                        RTL_W32(0x7c, p->val);
        !          1029:                        break;
        !          1030:                }
        !          1031:        }
        !          1032: }
        !          1033: 
        !          1034: static void rtl_set_rx_mode ( struct net_device *netdev )
        !          1035: {
        !          1036:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          1037:        void *ioaddr = tp->mmio_addr;
        !          1038:        u32 tmp;
        !          1039: 
        !          1040:        DBGP ( "rtl_set_rx_mode\n" );
        !          1041: 
        !          1042:        /* Accept all Multicast Packets */
        !          1043: 
        !          1044:        RTL_W32 ( MAR0 + 0, 0xffffffff );
        !          1045:        RTL_W32 ( MAR0 + 4, 0xffffffff );
        !          1046: 
        !          1047:        tmp = rtl8169_rx_config | AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
        !          1048:              ( RTL_R32 ( RxConfig ) & rtl_chip_info[tp->chipset].RxConfigMask );
        !          1049: 
        !          1050:        RTL_W32 ( RxConfig, tmp );
        !          1051: }
        !          1052: 
        !          1053: static void rtl_hw_start_8169(struct net_device *dev)
        !          1054: {
        !          1055:        struct rtl8169_private *tp = netdev_priv(dev);
        !          1056:        void *ioaddr = tp->mmio_addr;
        !          1057:        struct pci_device *pdev = tp->pci_dev;
        !          1058: 
        !          1059:        DBGP ( "rtl_hw_start_8169\n" );
        !          1060: 
        !          1061:        if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
        !          1062:                RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
        !          1063:                pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
        !          1064:        }
        !          1065: 
        !          1066:        RTL_W8(Cfg9346, Cfg9346_Unlock);
        !          1067: 
        !          1068:        if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
        !          1069:            (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
        !          1070:            (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
        !          1071:            (tp->mac_version == RTL_GIGA_MAC_VER_04))
        !          1072:                RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        !          1073: 
        !          1074:        RTL_W8(EarlyTxThres, EarlyTxThld);
        !          1075: 
        !          1076:        rtl_set_rx_max_size(ioaddr);
        !          1077: 
        !          1078:        if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
        !          1079:            (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
        !          1080:            (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
        !          1081:            (tp->mac_version == RTL_GIGA_MAC_VER_04))
        !          1082:                rtl_set_rx_tx_config_registers(tp);
        !          1083: 
        !          1084:        tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
        !          1085: 
        !          1086:        if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
        !          1087:            (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
        !          1088:                DBG ( "Set MAC Reg C+CR Offset 0xE0. "
        !          1089:                        "Bit-3 and bit-14 MUST be 1\n" );
        !          1090:                tp->cp_cmd |= (1 << 14);
        !          1091:        }
        !          1092: 
        !          1093:        RTL_W16(CPlusCmd, tp->cp_cmd);
        !          1094: 
        !          1095:        rtl8169_set_magic_reg(ioaddr, tp->mac_version);
        !          1096: 
        !          1097:        /*
        !          1098:         * Undocumented corner. Supposedly:
        !          1099:         * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
        !          1100:         */
        !          1101:        RTL_W16(IntrMitigate, 0x0000);
        !          1102: 
        !          1103:        rtl_set_rx_tx_desc_registers(tp, ioaddr);
        !          1104: 
        !          1105:        if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
        !          1106:            (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
        !          1107:            (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
        !          1108:            (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
        !          1109:                RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        !          1110:                rtl_set_rx_tx_config_registers(tp);
        !          1111:        }
        !          1112: 
        !          1113:        RTL_W8(Cfg9346, Cfg9346_Lock);
        !          1114: 
        !          1115:        /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
        !          1116:        RTL_R8(IntrMask);
        !          1117: 
        !          1118:        RTL_W32(RxMissed, 0);
        !          1119: 
        !          1120:        rtl_set_rx_mode(dev);
        !          1121: 
        !          1122:        /* no early-rx interrupts */
        !          1123:        RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
        !          1124: 
        !          1125:        //        RTL_W16(IntrMask, tp->intr_event);
        !          1126: }
        !          1127: 
        !          1128: static void rtl_tx_performance_tweak(struct pci_device *pdev, u16 force)
        !          1129: {
        !          1130:        struct net_device *dev = pci_get_drvdata(pdev);
        !          1131:        struct rtl8169_private *tp = netdev_priv(dev);
        !          1132:        int cap = tp->pcie_cap;
        !          1133: 
        !          1134:        DBGP ( "rtl_tx_performance_tweak\n" );
        !          1135: 
        !          1136:        if (cap) {
        !          1137:                u16 ctl;
        !          1138: 
        !          1139:                pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
        !          1140:                ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
        !          1141:                pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
        !          1142:        }
        !          1143: }
        !          1144: 
        !          1145: static void rtl_csi_access_enable(void *ioaddr)
        !          1146: {
        !          1147:        u32 csi;
        !          1148: 
        !          1149:        DBGP ( "rtl_csi_access_enable\n" );
        !          1150: 
        !          1151:        csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
        !          1152:        rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
        !          1153: }
        !          1154: 
        !          1155: struct ephy_info {
        !          1156:        unsigned int offset;
        !          1157:        u16 mask;
        !          1158:        u16 bits;
        !          1159: };
        !          1160: 
        !          1161: static void rtl_ephy_init(void *ioaddr, struct ephy_info *e, int len)
        !          1162: {
        !          1163:        u16 w;
        !          1164: 
        !          1165:        DBGP ( "rtl_ephy_init\n" );
        !          1166: 
        !          1167:        while (len-- > 0) {
        !          1168:                w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
        !          1169:                rtl_ephy_write(ioaddr, e->offset, w);
        !          1170:                e++;
        !          1171:        }
        !          1172: }
        !          1173: 
        !          1174: static void rtl_disable_clock_request(struct pci_device *pdev)
        !          1175: {
        !          1176:        struct net_device *dev = pci_get_drvdata(pdev);
        !          1177:        struct rtl8169_private *tp = netdev_priv(dev);
        !          1178:        int cap = tp->pcie_cap;
        !          1179: 
        !          1180:        DBGP ( "rtl_disable_clock_request\n" );
        !          1181: 
        !          1182:        if (cap) {
        !          1183:                u16 ctl;
        !          1184: 
        !          1185:                pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
        !          1186:                ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
        !          1187:                pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
        !          1188:        }
        !          1189: }
        !          1190: 
        !          1191: #define R8168_CPCMD_QUIRK_MASK (\
        !          1192:        EnableBist | \
        !          1193:        Mac_dbgo_oe | \
        !          1194:        Force_half_dup | \
        !          1195:        Force_rxflow_en | \
        !          1196:        Force_txflow_en | \
        !          1197:        Cxpl_dbg_sel | \
        !          1198:        ASF | \
        !          1199:        PktCntrDisable | \
        !          1200:        Mac_dbgo_sel)
        !          1201: 
        !          1202: static void rtl_hw_start_8168bb(void *ioaddr, struct pci_device *pdev)
        !          1203: {
        !          1204:        DBGP ( "rtl_hw_start_8168bb\n" );
        !          1205: 
        !          1206:        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
        !          1207: 
        !          1208:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
        !          1209: 
        !          1210:        rtl_tx_performance_tweak(pdev,
        !          1211:                (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
        !          1212: }
        !          1213: 
        !          1214: static void rtl_hw_start_8168bef(void *ioaddr, struct pci_device *pdev)
        !          1215: {
        !          1216:        DBGP ( "rtl_hw_start_8168bef\n" );
        !          1217: 
        !          1218:        rtl_hw_start_8168bb(ioaddr, pdev);
        !          1219: 
        !          1220:        RTL_W8(EarlyTxThres, EarlyTxThld);
        !          1221: 
        !          1222:        RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0));
        !          1223: }
        !          1224: 
        !          1225: static void __rtl_hw_start_8168cp(void *ioaddr, struct pci_device *pdev)
        !          1226: {
        !          1227:        DBGP ( "__rtl_hw_start_8168cp\n" );
        !          1228: 
        !          1229:        RTL_W8(Config1, RTL_R8(Config1) | Speed_down);
        !          1230: 
        !          1231:        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
        !          1232: 
        !          1233:        rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
        !          1234: 
        !          1235:        rtl_disable_clock_request(pdev);
        !          1236: 
        !          1237:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
        !          1238: }
        !          1239: 
        !          1240: static void rtl_hw_start_8168cp_1(void *ioaddr, struct pci_device *pdev)
        !          1241: {
        !          1242:        static struct ephy_info e_info_8168cp[] = {
        !          1243:                { 0x01, 0,      0x0001 },
        !          1244:                { 0x02, 0x0800, 0x1000 },
        !          1245:                { 0x03, 0,      0x0042 },
        !          1246:                { 0x06, 0x0080, 0x0000 },
        !          1247:                { 0x07, 0,      0x2000 }
        !          1248:        };
        !          1249: 
        !          1250:        DBGP ( "rtl_hw_start_8168cp_1\n" );
        !          1251: 
        !          1252:        rtl_csi_access_enable(ioaddr);
        !          1253: 
        !          1254:        rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
        !          1255: 
        !          1256:        __rtl_hw_start_8168cp(ioaddr, pdev);
        !          1257: }
        !          1258: 
        !          1259: static void rtl_hw_start_8168cp_2(void *ioaddr, struct pci_device *pdev)
        !          1260: {
        !          1261:        DBGP ( "rtl_hw_start_8168cp_2\n" );
        !          1262: 
        !          1263:        rtl_csi_access_enable(ioaddr);
        !          1264: 
        !          1265:        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
        !          1266: 
        !          1267:        rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
        !          1268: 
        !          1269:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
        !          1270: }
        !          1271: 
        !          1272: static void rtl_hw_start_8168cp_3(void *ioaddr, struct pci_device *pdev)
        !          1273: {
        !          1274:        DBGP ( "rtl_hw_start_8168cp_3\n" );
        !          1275: 
        !          1276:        rtl_csi_access_enable(ioaddr);
        !          1277: 
        !          1278:        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
        !          1279: 
        !          1280:        /* Magic. */
        !          1281:        RTL_W8(DBG_REG, 0x20);
        !          1282: 
        !          1283:        RTL_W8(EarlyTxThres, EarlyTxThld);
        !          1284: 
        !          1285:        rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
        !          1286: 
        !          1287:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
        !          1288: }
        !          1289: 
        !          1290: static void rtl_hw_start_8168c_1(void *ioaddr, struct pci_device *pdev)
        !          1291: {
        !          1292:        static struct ephy_info e_info_8168c_1[] = {
        !          1293:                { 0x02, 0x0800, 0x1000 },
        !          1294:                { 0x03, 0,      0x0002 },
        !          1295:                { 0x06, 0x0080, 0x0000 }
        !          1296:        };
        !          1297: 
        !          1298:        DBGP ( "rtl_hw_start_8168c_1\n" );
        !          1299: 
        !          1300:        rtl_csi_access_enable(ioaddr);
        !          1301: 
        !          1302:        RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
        !          1303: 
        !          1304:        rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1));
        !          1305: 
        !          1306:        __rtl_hw_start_8168cp(ioaddr, pdev);
        !          1307: }
        !          1308: 
        !          1309: static void rtl_hw_start_8168c_2(void *ioaddr, struct pci_device *pdev)
        !          1310: {
        !          1311:        static struct ephy_info e_info_8168c_2[] = {
        !          1312:                { 0x01, 0,      0x0001 },
        !          1313:                { 0x03, 0x0400, 0x0220 }
        !          1314:        };
        !          1315: 
        !          1316:        DBGP ( "rtl_hw_start_8168c_2\n" );
        !          1317: 
        !          1318:        rtl_csi_access_enable(ioaddr);
        !          1319: 
        !          1320:        rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
        !          1321: 
        !          1322:        __rtl_hw_start_8168cp(ioaddr, pdev);
        !          1323: }
        !          1324: 
        !          1325: static void rtl_hw_start_8168c_3(void *ioaddr, struct pci_device *pdev)
        !          1326: {
        !          1327:        DBGP ( "rtl_hw_start_8168c_3\n" );
        !          1328: 
        !          1329:        rtl_hw_start_8168c_2(ioaddr, pdev);
        !          1330: }
        !          1331: 
        !          1332: static void rtl_hw_start_8168c_4(void *ioaddr, struct pci_device *pdev)
        !          1333: {
        !          1334:        DBGP ( "rtl_hw_start_8168c_4\n" );
        !          1335: 
        !          1336:        rtl_csi_access_enable(ioaddr);
        !          1337: 
        !          1338:        __rtl_hw_start_8168cp(ioaddr, pdev);
        !          1339: }
        !          1340: 
        !          1341: static void rtl_hw_start_8168d(void *ioaddr, struct pci_device *pdev)
        !          1342: {
        !          1343:        DBGP ( "rtl_hw_start_8168d\n" );
        !          1344: 
        !          1345:        rtl_csi_access_enable(ioaddr);
        !          1346: 
        !          1347:        rtl_disable_clock_request(pdev);
        !          1348: 
        !          1349:        RTL_W8(EarlyTxThres, EarlyTxThld);
        !          1350: 
        !          1351:        rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
        !          1352: 
        !          1353:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
        !          1354: }
        !          1355: 
        !          1356: static void rtl_hw_start_8168(struct net_device *dev)
        !          1357: {
        !          1358:        struct rtl8169_private *tp = netdev_priv(dev);
        !          1359:        void *ioaddr = tp->mmio_addr;
        !          1360:        struct pci_device *pdev = tp->pci_dev;
        !          1361: 
        !          1362:        DBGP ( "rtl_hw_start_8168\n" );
        !          1363: 
        !          1364:        RTL_W8(Cfg9346, Cfg9346_Unlock);
        !          1365: 
        !          1366:        RTL_W8(EarlyTxThres, EarlyTxThld);
        !          1367: 
        !          1368:        rtl_set_rx_max_size(ioaddr);
        !          1369: 
        !          1370:        tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
        !          1371: 
        !          1372:        RTL_W16(CPlusCmd, tp->cp_cmd);
        !          1373: 
        !          1374:        RTL_W16(IntrMitigate, 0x5151);
        !          1375: 
        !          1376:        /* Work around for RxFIFO overflow. */
        !          1377:        if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
        !          1378:                tp->intr_event |= RxFIFOOver | PCSTimeout;
        !          1379:                tp->intr_event &= ~RxOverflow;
        !          1380:        }
        !          1381: 
        !          1382:        rtl_set_rx_tx_desc_registers(tp, ioaddr);
        !          1383: 
        !          1384:        rtl_set_rx_mode(dev);
        !          1385: 
        !          1386:        RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
        !          1387:                (InterFrameGap << TxInterFrameGapShift));
        !          1388: 
        !          1389:        RTL_R8(IntrMask);
        !          1390: 
        !          1391:        switch (tp->mac_version) {
        !          1392:        case RTL_GIGA_MAC_VER_11:
        !          1393:                rtl_hw_start_8168bb(ioaddr, pdev);
        !          1394:        break;
        !          1395: 
        !          1396:        case RTL_GIGA_MAC_VER_12:
        !          1397:        case RTL_GIGA_MAC_VER_17:
        !          1398:                rtl_hw_start_8168bef(ioaddr, pdev);
        !          1399:        break;
        !          1400: 
        !          1401:        case RTL_GIGA_MAC_VER_18:
        !          1402:                rtl_hw_start_8168cp_1(ioaddr, pdev);
        !          1403:        break;
        !          1404: 
        !          1405:        case RTL_GIGA_MAC_VER_19:
        !          1406:                rtl_hw_start_8168c_1(ioaddr, pdev);
        !          1407:        break;
        !          1408: 
        !          1409:        case RTL_GIGA_MAC_VER_20:
        !          1410:                rtl_hw_start_8168c_2(ioaddr, pdev);
        !          1411:        break;
        !          1412: 
        !          1413:        case RTL_GIGA_MAC_VER_21:
        !          1414:                rtl_hw_start_8168c_3(ioaddr, pdev);
        !          1415:        break;
        !          1416: 
        !          1417:        case RTL_GIGA_MAC_VER_22:
        !          1418:                rtl_hw_start_8168c_4(ioaddr, pdev);
        !          1419:        break;
        !          1420: 
        !          1421:        case RTL_GIGA_MAC_VER_23:
        !          1422:                rtl_hw_start_8168cp_2(ioaddr, pdev);
        !          1423:        break;
        !          1424: 
        !          1425:        case RTL_GIGA_MAC_VER_24:
        !          1426:                rtl_hw_start_8168cp_3(ioaddr, pdev);
        !          1427:        break;
        !          1428: 
        !          1429:        case RTL_GIGA_MAC_VER_25:
        !          1430:                rtl_hw_start_8168d(ioaddr, pdev);
        !          1431:        break;
        !          1432: 
        !          1433:        default:
        !          1434:                DBG ( "Unknown chipset (mac_version = %d).\n",
        !          1435:                      tp->mac_version );
        !          1436:        break;
        !          1437:        }
        !          1438: 
        !          1439:        RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        !          1440: 
        !          1441:        RTL_W8(Cfg9346, Cfg9346_Lock);
        !          1442: 
        !          1443:        RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
        !          1444: 
        !          1445:        //        RTL_W16(IntrMask, tp->intr_event);
        !          1446: }
        !          1447: 
        !          1448: #define R810X_CPCMD_QUIRK_MASK (\
        !          1449:        EnableBist | \
        !          1450:        Mac_dbgo_oe | \
        !          1451:        Force_half_dup | \
        !          1452:        Force_half_dup | \
        !          1453:        Force_txflow_en | \
        !          1454:        Cxpl_dbg_sel | \
        !          1455:        ASF | \
        !          1456:        PktCntrDisable | \
        !          1457:        PCIDAC | \
        !          1458:        PCIMulRW)
        !          1459: 
        !          1460: static void rtl_hw_start_8102e_1(void *ioaddr, struct pci_device *pdev)
        !          1461: {
        !          1462:        static struct ephy_info e_info_8102e_1[] = {
        !          1463:                { 0x01, 0, 0x6e65 },
        !          1464:                { 0x02, 0, 0x091f },
        !          1465:                { 0x03, 0, 0xc2f9 },
        !          1466:                { 0x06, 0, 0xafb5 },
        !          1467:                { 0x07, 0, 0x0e00 },
        !          1468:                { 0x19, 0, 0xec80 },
        !          1469:                { 0x01, 0, 0x2e65 },
        !          1470:                { 0x01, 0, 0x6e65 }
        !          1471:        };
        !          1472:        u8 cfg1;
        !          1473: 
        !          1474:        DBGP ( "rtl_hw_start_8102e_1\n" );
        !          1475: 
        !          1476:        rtl_csi_access_enable(ioaddr);
        !          1477: 
        !          1478:        RTL_W8(DBG_REG, FIX_NAK_1);
        !          1479: 
        !          1480:        rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
        !          1481: 
        !          1482:        RTL_W8(Config1,
        !          1483:               LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
        !          1484:        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
        !          1485: 
        !          1486:        cfg1 = RTL_R8(Config1);
        !          1487:        if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
        !          1488:                RTL_W8(Config1, cfg1 & ~LEDS0);
        !          1489: 
        !          1490:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
        !          1491: 
        !          1492:        rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
        !          1493: }
        !          1494: 
        !          1495: static void rtl_hw_start_8102e_2(void *ioaddr, struct pci_device *pdev)
        !          1496: {
        !          1497:        DBGP ( "rtl_hw_start_8102e_2\n" );
        !          1498: 
        !          1499:        rtl_csi_access_enable(ioaddr);
        !          1500: 
        !          1501:        rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
        !          1502: 
        !          1503:        RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
        !          1504:        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
        !          1505: 
        !          1506:        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
        !          1507: }
        !          1508: 
        !          1509: static void rtl_hw_start_8102e_3(void *ioaddr, struct pci_device *pdev)
        !          1510: {
        !          1511:        DBGP ( "rtl_hw_start_8102e_3\n" );
        !          1512: 
        !          1513:        rtl_hw_start_8102e_2(ioaddr, pdev);
        !          1514: 
        !          1515:        rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
        !          1516: }
        !          1517: 
        !          1518: static void rtl_hw_start_8101(struct net_device *dev)
        !          1519: {
        !          1520:        struct rtl8169_private *tp = netdev_priv(dev);
        !          1521:        void *ioaddr = tp->mmio_addr;
        !          1522:        struct pci_device *pdev = tp->pci_dev;
        !          1523: 
        !          1524:        DBGP ( "rtl_hw_start_8101\n" );
        !          1525: 
        !          1526:        if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
        !          1527:            (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
        !          1528:                int cap = tp->pcie_cap;
        !          1529: 
        !          1530:                if (cap) {
        !          1531:                        pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
        !          1532:                                              PCI_EXP_DEVCTL_NOSNOOP_EN);
        !          1533:                }
        !          1534:        }
        !          1535: 
        !          1536:        switch (tp->mac_version) {
        !          1537:        case RTL_GIGA_MAC_VER_07:
        !          1538:                rtl_hw_start_8102e_1(ioaddr, pdev);
        !          1539:                break;
        !          1540: 
        !          1541:        case RTL_GIGA_MAC_VER_08:
        !          1542:                rtl_hw_start_8102e_3(ioaddr, pdev);
        !          1543:                break;
        !          1544: 
        !          1545:        case RTL_GIGA_MAC_VER_09:
        !          1546:                rtl_hw_start_8102e_2(ioaddr, pdev);
        !          1547:                break;
        !          1548:        }
        !          1549: 
        !          1550:        RTL_W8(Cfg9346, Cfg9346_Unlock);
        !          1551: 
        !          1552:        RTL_W8(EarlyTxThres, EarlyTxThld);
        !          1553: 
        !          1554:        rtl_set_rx_max_size(ioaddr);
        !          1555: 
        !          1556:        tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
        !          1557: 
        !          1558:        RTL_W16(CPlusCmd, tp->cp_cmd);
        !          1559: 
        !          1560:        RTL_W16(IntrMitigate, 0x0000);
        !          1561: 
        !          1562:        rtl_set_rx_tx_desc_registers(tp, ioaddr);
        !          1563: 
        !          1564:        RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        !          1565:        rtl_set_rx_tx_config_registers(tp);
        !          1566: 
        !          1567:        RTL_W8(Cfg9346, Cfg9346_Lock);
        !          1568: 
        !          1569:        RTL_R8(IntrMask);
        !          1570: 
        !          1571:        rtl_set_rx_mode(dev);
        !          1572: 
        !          1573:        RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        !          1574: 
        !          1575:        RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
        !          1576: 
        !          1577:        //        RTL_W16(IntrMask, tp->intr_event);
        !          1578: }
        !          1579: 
        !          1580: /*** iPXE API Support Routines ***/
        !          1581: 
        !          1582: /**
        !          1583:  * setup_tx_resources - allocate tx resources (descriptors)
        !          1584:  *
        !          1585:  * @v tp        Driver private storage
        !          1586:  *
        !          1587:  * @ret rc       Returns 0 on success, negative on failure
        !          1588:  **/
        !          1589: static int
        !          1590: rtl8169_setup_tx_resources ( struct rtl8169_private *tp )
        !          1591: {
        !          1592:        DBGP ( "rtl8169_setup_tx_resources\n" );
        !          1593: 
        !          1594:        tp->tx_base = malloc_dma ( R8169_TX_RING_BYTES, TX_RING_ALIGN );
        !          1595: 
        !          1596:        if ( ! tp->tx_base ) {
        !          1597:                return -ENOMEM;
        !          1598:        }
        !          1599: 
        !          1600:        memset ( tp->tx_base, 0, R8169_TX_RING_BYTES );
        !          1601: 
        !          1602:        DBG ( "tp->tx_base      = %#08lx\n", virt_to_bus ( tp->tx_base ) );
        !          1603: 
        !          1604:        tp->tx_fill_ctr = 0;
        !          1605:        tp->tx_curr = 0;
        !          1606:        tp->tx_tail = 0;
        !          1607: 
        !          1608:        return 0;
        !          1609: }
        !          1610: 
        !          1611: static void
        !          1612: rtl8169_process_tx_packets ( struct net_device *netdev )
        !          1613: {
        !          1614:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          1615: 
        !          1616:        uint32_t tx_status;
        !          1617:        struct TxDesc *tx_curr_desc;
        !          1618: 
        !          1619:        DBGP ( "rtl8169_process_tx_packets\n" );
        !          1620: 
        !          1621:        while ( tp->tx_tail != tp->tx_curr ) {
        !          1622: 
        !          1623:                tx_curr_desc = tp->tx_base  + tp->tx_tail;
        !          1624: 
        !          1625:                tx_status = tx_curr_desc->opts1;
        !          1626: 
        !          1627:                DBG2 ( "Before DescOwn check tx_status: %#08x\n", tx_status );
        !          1628: 
        !          1629:                /* if the packet at tx_tail is not owned by hardware it is for us */
        !          1630:                if ( tx_status & DescOwn )
        !          1631:                        break;
        !          1632: 
        !          1633:                DBG ( "Transmitted packet.\n" );
        !          1634:                DBG ( "tp->tx_fill_ctr     = %d\n", tp->tx_fill_ctr );
        !          1635:                DBG ( "tp->tx_tail         = %d\n", tp->tx_tail );
        !          1636:                DBG ( "tp->tx_curr         = %d\n", tp->tx_curr );
        !          1637:                DBG ( "tx_status           = %d\n", tx_status );
        !          1638:                DBG ( "tx_curr_desc        = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
        !          1639: 
        !          1640:                /* Pass packet to core for processing */
        !          1641:                netdev_tx_complete ( netdev, tp->tx_iobuf[tp->tx_tail] );
        !          1642: 
        !          1643:                memset ( tx_curr_desc, 0, sizeof ( *tx_curr_desc ) );
        !          1644: 
        !          1645:                /* Decrement count of used descriptors */
        !          1646:                tp->tx_fill_ctr--;
        !          1647: 
        !          1648:                /* Increment sent packets index */
        !          1649:                tp->tx_tail = ( tp->tx_tail + 1 ) % NUM_TX_DESC;
        !          1650:        }
        !          1651: }
        !          1652: 
        !          1653: static void
        !          1654: rtl8169_free_tx_resources ( struct rtl8169_private *tp )
        !          1655: {
        !          1656:        DBGP ( "rtl8169_free_tx_resources\n" );
        !          1657: 
        !          1658:        free_dma ( tp->tx_base, R8169_TX_RING_BYTES );
        !          1659: }
        !          1660: 
        !          1661: static void
        !          1662: rtl8169_populate_rx_descriptor ( struct rtl8169_private *tp, struct RxDesc *rx_desc, uint32_t index )
        !          1663: {
        !          1664:        DBGP ( "rtl8169_populate_rx_descriptor\n" );
        !          1665: 
        !          1666:        DBG ( "Populating rx descriptor %d\n", index );
        !          1667: 
        !          1668:        memset ( rx_desc, 0, sizeof ( *rx_desc ) );
        !          1669: 
        !          1670:        rx_desc->addr_hi = 0;
        !          1671:        rx_desc->addr_lo = virt_to_bus ( tp->rx_iobuf[index]->data );
        !          1672:        rx_desc->opts2 = 0;
        !          1673:        rx_desc->opts1 = ( index == ( NUM_RX_DESC - 1 ) ? RingEnd : 0 ) |
        !          1674:                RX_BUF_SIZE;
        !          1675:        rx_desc->opts1 |= DescOwn;
        !          1676: }
        !          1677: 
        !          1678: /**
        !          1679:  * Refill descriptor ring
        !          1680:  *
        !          1681:  * @v netdev           Net device
        !          1682:  */
        !          1683: static void rtl8169_refill_rx_ring ( struct rtl8169_private *tp )
        !          1684: {
        !          1685:        struct RxDesc *rx_curr_desc;
        !          1686:        int i;
        !          1687: 
        !          1688:        DBGP ( "rtl8169_refill_rx_ring\n" );
        !          1689: 
        !          1690:        for ( i = 0; i < NUM_RX_DESC; i++ ) {
        !          1691: 
        !          1692:                rx_curr_desc = ( tp->rx_base ) + i;
        !          1693: 
        !          1694:                /* Don't touch descriptors owned by the NIC */
        !          1695:                if ( rx_curr_desc->opts1 & DescOwn )
        !          1696:                        continue;
        !          1697: 
        !          1698:                /* Don't touch descriptors with iobufs, they still need to be
        !          1699:                   processed by the poll routine */
        !          1700:                if ( tp->rx_iobuf[tp->rx_curr] != NULL )
        !          1701:                        continue;
        !          1702: 
        !          1703:                /** If we can't get an iobuf for this descriptor
        !          1704:                    try again later (next poll).
        !          1705:                 */
        !          1706:                if ( ! ( tp->rx_iobuf[i] = alloc_iob ( RX_BUF_SIZE ) ) ) {
        !          1707:                        DBG ( "Refill rx ring failed!!\n" );
        !          1708:                        break;
        !          1709:                }
        !          1710: 
        !          1711:                rtl8169_populate_rx_descriptor ( tp, rx_curr_desc, i );
        !          1712:        }
        !          1713: }
        !          1714: 
        !          1715: /**
        !          1716:  * setup_rx_resources - allocate Rx resources (Descriptors)
        !          1717:  *
        !          1718:  * @v tp:       Driver private structure
        !          1719:  *
        !          1720:  * @ret rc       Returns 0 on success, negative on failure
        !          1721:  *
        !          1722:  **/
        !          1723: static int
        !          1724: rtl8169_setup_rx_resources ( struct rtl8169_private *tp )
        !          1725: {
        !          1726:        DBGP ( "rtl8169_setup_rx_resources\n" );
        !          1727: 
        !          1728:        tp->rx_base = malloc_dma ( R8169_RX_RING_BYTES, RX_RING_ALIGN );
        !          1729: 
        !          1730:        DBG ( "tp->rx_base      = %#08lx\n", virt_to_bus ( tp->rx_base ) );
        !          1731: 
        !          1732:        if ( ! tp->rx_base ) {
        !          1733:                return -ENOMEM;
        !          1734:        }
        !          1735:        memset ( tp->rx_base, 0, R8169_RX_RING_BYTES );
        !          1736: 
        !          1737:        rtl8169_refill_rx_ring ( tp );
        !          1738: 
        !          1739:        tp->rx_curr = 0;
        !          1740: 
        !          1741:        return 0;
        !          1742: }
        !          1743: 
        !          1744: static void
        !          1745: rtl8169_process_rx_packets ( struct net_device *netdev )
        !          1746: {
        !          1747:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          1748:        uint32_t rx_status;
        !          1749:        uint16_t rx_len;
        !          1750:        struct RxDesc *rx_curr_desc;
        !          1751:        int i;
        !          1752: 
        !          1753:        DBGP ( "rtl8169_process_rx_packets\n" );
        !          1754: 
        !          1755:        for ( i = 0; i < NUM_RX_DESC; i++ ) {
        !          1756: 
        !          1757:                rx_curr_desc = tp->rx_base  + tp->rx_curr;
        !          1758: 
        !          1759:                rx_status = rx_curr_desc->opts1;
        !          1760: 
        !          1761:                DBG2 ( "Before DescOwn check rx_status: %#08x\n", rx_status );
        !          1762: 
        !          1763:                /* Hardware still owns the descriptor */
        !          1764:                if ( rx_status & DescOwn )
        !          1765:                        break;
        !          1766: 
        !          1767:                /* We own the descriptor, but it has not been refilled yet */
        !          1768:                if ( tp->rx_iobuf[tp->rx_curr] == NULL )
        !          1769:                        break;
        !          1770: 
        !          1771:                rx_len = rx_status & 0x3fff;
        !          1772: 
        !          1773:                DBG ( "Received packet.\n" );
        !          1774:                DBG ( "tp->rx_curr         = %d\n", tp->rx_curr );
        !          1775:                DBG ( "rx_len              = %d\n", rx_len );
        !          1776:                DBG ( "rx_status           = %#08x\n", rx_status );
        !          1777:                DBG ( "rx_curr_desc        = %#08lx\n", virt_to_bus ( rx_curr_desc ) );
        !          1778: 
        !          1779:                if ( rx_status & RxRES ) {
        !          1780: 
        !          1781:                        netdev_rx_err ( netdev, tp->rx_iobuf[tp->rx_curr], -EINVAL );
        !          1782: 
        !          1783:                        DBG ( "rtl8169_poll: Corrupted packet received!\n"
        !          1784:                               " rx_status: %#08x\n", rx_status );
        !          1785: 
        !          1786:                } else  {
        !          1787: 
        !          1788:                        /* Adjust size of the iobuf to reflect received data */
        !          1789:                        iob_put ( tp->rx_iobuf[tp->rx_curr], rx_len );
        !          1790: 
        !          1791:                        /* Add this packet to the receive queue.  */
        !          1792:                        netdev_rx ( netdev, tp->rx_iobuf[tp->rx_curr] );
        !          1793:                }
        !          1794: 
        !          1795:                /* Invalidate this iobuf and descriptor */
        !          1796:                tp->rx_iobuf[tp->rx_curr] = NULL;
        !          1797:                memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) );
        !          1798: 
        !          1799:                /* Update pointer to next available rx descriptor */
        !          1800:                tp->rx_curr = ( tp->rx_curr + 1 ) % NUM_RX_DESC;
        !          1801:        }
        !          1802:        rtl8169_refill_rx_ring ( tp );
        !          1803: }
        !          1804: 
        !          1805: static void
        !          1806: rtl8169_free_rx_resources ( struct rtl8169_private *tp )
        !          1807: {
        !          1808:        int i;
        !          1809: 
        !          1810:        DBGP ( "rtl8169_free_rx_resources\n" );
        !          1811: 
        !          1812:        free_dma ( tp->rx_base, R8169_RX_RING_BYTES );
        !          1813: 
        !          1814:        for ( i = 0; i < NUM_RX_DESC; i++ ) {
        !          1815:                free_iob ( tp->rx_iobuf[i] );
        !          1816:                tp->rx_iobuf[i] = NULL;
        !          1817:        }
        !          1818: }
        !          1819: 
        !          1820: static void rtl8169_irq_enable ( struct rtl8169_private *tp )
        !          1821: {
        !          1822:        void *ioaddr = tp->mmio_addr;
        !          1823: 
        !          1824:        DBGP ( "rtl8169_irq_enable\n" );
        !          1825: 
        !          1826:        RTL_W16 ( IntrMask, tp->intr_event );
        !          1827: }
        !          1828: 
        !          1829: static void rtl8169_irq_disable ( struct rtl8169_private *tp )
        !          1830: {
        !          1831:        void *ioaddr = tp->mmio_addr;
        !          1832: 
        !          1833:        DBGP ( "rtl8169_irq_disable\n" );
        !          1834: 
        !          1835:        RTL_W16 ( IntrMask, 0x0000 );
        !          1836: }
        !          1837: 
        !          1838: /*** iPXE Core API Routines ***/
        !          1839: 
        !          1840: /**
        !          1841:  * open - Called when a network interface is made active
        !          1842:  *
        !          1843:  * @v netdev   network interface device structure
        !          1844:  * @ret rc     Return status code, 0 on success, negative value on failure
        !          1845:  *
        !          1846:  **/
        !          1847: static int
        !          1848: rtl8169_open ( struct net_device *netdev )
        !          1849: {
        !          1850:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          1851:        void *ioaddr = tp->mmio_addr;
        !          1852:        int rc;
        !          1853: 
        !          1854:        DBGP ( "rtl8169_open\n" );
        !          1855: 
        !          1856:        /* allocate transmit descriptors */
        !          1857:        rc = rtl8169_setup_tx_resources ( tp );
        !          1858:        if ( rc ) {
        !          1859:                DBG ( "Error setting up TX resources!\n" );
        !          1860:                goto err_setup_tx;
        !          1861:        }
        !          1862: 
        !          1863:        /* allocate receive descriptors */
        !          1864:        rc = rtl8169_setup_rx_resources ( tp );
        !          1865:        if ( rc ) {
        !          1866:                DBG ( "Error setting up RX resources!\n" );
        !          1867:                goto err_setup_rx;
        !          1868:        }
        !          1869: 
        !          1870:        rtl_hw_start ( netdev );
        !          1871: 
        !          1872:        DBG ( "TxDescStartAddrHigh   = %#08lx\n", RTL_R32 ( TxDescStartAddrHigh ) );
        !          1873:        DBG ( "TxDescStartAddrLow    = %#08lx\n", RTL_R32 ( TxDescStartAddrLow  ) );
        !          1874:        DBG ( "RxDescAddrHigh        = %#08lx\n", RTL_R32 ( RxDescAddrHigh ) );
        !          1875:        DBG ( "RxDescAddrLow         = %#08lx\n", RTL_R32 ( RxDescAddrLow  ) );
        !          1876: 
        !          1877:        return 0;
        !          1878: 
        !          1879: err_setup_rx:
        !          1880:        rtl8169_free_tx_resources ( tp );
        !          1881: err_setup_tx:
        !          1882:        rtl8169_hw_reset ( ioaddr );
        !          1883: 
        !          1884:        return rc;
        !          1885: }
        !          1886: 
        !          1887: /**
        !          1888:  * transmit - Transmit a packet
        !          1889:  *
        !          1890:  * @v netdev   Network device
        !          1891:  * @v iobuf    I/O buffer
        !          1892:  *
        !          1893:  * @ret rc       Returns 0 on success, negative on failure
        !          1894:  */
        !          1895: static int
        !          1896: rtl8169_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
        !          1897: {
        !          1898:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          1899:        void *ioaddr = tp->mmio_addr;
        !          1900:        uint32_t tx_len = iob_len ( iobuf );
        !          1901: 
        !          1902:        struct TxDesc *tx_curr_desc;
        !          1903: 
        !          1904:        DBGP ("rtl8169_transmit\n");
        !          1905: 
        !          1906:        if ( tp->tx_fill_ctr == NUM_TX_DESC ) {
        !          1907:                DBG ("TX overflow\n");
        !          1908:                return -ENOBUFS;
        !          1909:        }
        !          1910: 
        !          1911:        /**
        !          1912:         *  The rtl8169 family automatically pads short packets to a
        !          1913:         *  minimum size, but if it did not, like some older cards,
        !          1914:         *  we could do:
        !          1915:         *  iob_pad ( iobuf, ETH_ZLEN );
        !          1916:         */
        !          1917: 
        !          1918:        /* Save pointer to this iobuf we have been given to transmit so
        !          1919:           we can pass it to netdev_tx_complete() later */
        !          1920:        tp->tx_iobuf[tp->tx_curr] = iobuf;
        !          1921: 
        !          1922:        tx_curr_desc = tp->tx_base + tp->tx_curr;
        !          1923: 
        !          1924:        DBG ( "tp->tx_fill_ctr = %d\n", tp->tx_fill_ctr );
        !          1925:        DBG ( "tp->tx_curr     = %d\n", tp->tx_curr );
        !          1926:        DBG ( "tx_curr_desc    = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
        !          1927:        DBG ( "iobuf->data     = %#08lx\n", virt_to_bus ( iobuf->data ) );
        !          1928:        DBG ( "tx_len          = %d\n", tx_len );
        !          1929: 
        !          1930:        /* Configure current descriptor to transmit supplied packet */
        !          1931:        tx_curr_desc->addr_hi = 0;
        !          1932:        tx_curr_desc->addr_lo = virt_to_bus ( iobuf->data );
        !          1933:        tx_curr_desc->opts2 = 0;
        !          1934:        tx_curr_desc->opts1 = FirstFrag | LastFrag |
        !          1935:                ( tp->tx_curr == ( NUM_TX_DESC - 1 ) ? RingEnd : 0 ) |
        !          1936:                tx_len;
        !          1937: 
        !          1938:        /* Mark descriptor as owned by NIC */
        !          1939:        tx_curr_desc->opts1 |= DescOwn;
        !          1940: 
        !          1941:        DBG ( "tx_curr_desc->opts1   = %#08x\n", tx_curr_desc->opts1 );
        !          1942:        DBG ( "tx_curr_desc->opts2   = %#08x\n", tx_curr_desc->opts2 );
        !          1943:        DBG ( "tx_curr_desc->addr_hi = %#08x\n", tx_curr_desc->addr_hi );
        !          1944:        DBG ( "tx_curr_desc->addr_lo = %#08x\n", tx_curr_desc->addr_lo );
        !          1945: 
        !          1946:        RTL_W8 ( TxPoll, NPQ ); /* set polling bit */
        !          1947: 
        !          1948:        /* Point to next free descriptor */
        !          1949:        tp->tx_curr = ( tp->tx_curr + 1 ) % NUM_TX_DESC;
        !          1950: 
        !          1951:        /* Increment number of tx descriptors in use */
        !          1952:        tp->tx_fill_ctr++;
        !          1953: 
        !          1954:        return 0;
        !          1955: }
        !          1956: 
        !          1957: /**
        !          1958:  * poll - Poll for received packets
        !          1959:  *
        !          1960:  * @v netdev   Network device
        !          1961:  */
        !          1962: static void
        !          1963: rtl8169_poll ( struct net_device *netdev )
        !          1964: {
        !          1965:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          1966:        void *ioaddr = tp->mmio_addr;
        !          1967: 
        !          1968:        uint16_t intr_status;
        !          1969:        uint16_t intr_mask;
        !          1970: 
        !          1971:        DBGP ( "rtl8169_poll\n" );
        !          1972: 
        !          1973:        intr_status = RTL_R16 ( IntrStatus );
        !          1974:        intr_mask   = RTL_R16 ( IntrMask );
        !          1975: 
        !          1976:        DBG2 ( "rtl8169_poll (before): intr_mask = %#04x  intr_status = %#04x\n",
        !          1977:              intr_mask, intr_status );
        !          1978: 
        !          1979:        RTL_W16 ( IntrStatus, 0xffff );
        !          1980: 
        !          1981:        /* hotplug / major error / no more work / shared irq */
        !          1982:        if ( intr_status == 0xffff )
        !          1983:                return;
        !          1984: 
        !          1985:        /* Process transmitted packets */
        !          1986:        rtl8169_process_tx_packets ( netdev );
        !          1987: 
        !          1988:        /* Process received packets  */
        !          1989:        rtl8169_process_rx_packets ( netdev );
        !          1990: }
        !          1991: 
        !          1992: /**
        !          1993:  * close - Disable network interface
        !          1994:  *
        !          1995:  * @v netdev   network interface device structure
        !          1996:  *
        !          1997:  **/
        !          1998: static void
        !          1999: rtl8169_close ( struct net_device *netdev )
        !          2000: {
        !          2001:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          2002:        void *ioaddr = tp->mmio_addr;
        !          2003: 
        !          2004:        DBGP ( "r8169_close\n" );
        !          2005: 
        !          2006:        rtl8169_hw_reset ( ioaddr );
        !          2007: 
        !          2008:        rtl8169_free_tx_resources ( tp );
        !          2009:        rtl8169_free_rx_resources ( tp );
        !          2010: }
        !          2011: 
        !          2012: /**
        !          2013:  * irq - enable or Disable interrupts
        !          2014:  *
        !          2015:  * @v netdev    network adapter
        !          2016:  * @v action    requested interrupt action
        !          2017:  *
        !          2018:  **/
        !          2019: static void
        !          2020: rtl8169_irq ( struct net_device *netdev, int action )
        !          2021: {
        !          2022:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          2023: 
        !          2024:        DBGP ( "rtl8169_irq\n" );
        !          2025: 
        !          2026:        switch ( action ) {
        !          2027:        case 0 :
        !          2028:                rtl8169_irq_disable ( tp );
        !          2029:                break;
        !          2030:        default :
        !          2031:                rtl8169_irq_enable ( tp );
        !          2032:                break;
        !          2033:        }
        !          2034: }
        !          2035: 
        !          2036: static struct net_device_operations rtl8169_operations = {
        !          2037:        .open           = rtl8169_open,
        !          2038:        .transmit       = rtl8169_transmit,
        !          2039:        .poll           = rtl8169_poll,
        !          2040:        .close          = rtl8169_close,
        !          2041:        .irq            = rtl8169_irq,
        !          2042: };
        !          2043: 
        !          2044: /**
        !          2045:  * probe - Initial configuration of NIC
        !          2046:  *
        !          2047:  * @v pci      PCI device
        !          2048:  * @v id       PCI IDs
        !          2049:  *
        !          2050:  * @ret rc     Return status code
        !          2051:  **/
        !          2052: static int
        !          2053: rtl8169_probe ( struct pci_device *pdev )
        !          2054: {
        !          2055:        int i, rc;
        !          2056:        struct net_device *netdev;
        !          2057:        struct rtl8169_private *tp;
        !          2058:        void *ioaddr;
        !          2059: 
        !          2060:        const struct rtl_cfg_info *cfg = rtl_cfg_infos + pdev->id->driver_data;
        !          2061: 
        !          2062:        DBGP ( "rtl8169_probe\n" );
        !          2063: 
        !          2064:        DBG ( "id->vendor = %#04x, id->device = %#04x\n",
        !          2065:              pdev->id->vendor, pdev->id->device );
        !          2066: 
        !          2067:        DBG ( "cfg->intr_event = %#04x\n", cfg->intr_event );
        !          2068: 
        !          2069:        rc = -ENOMEM;
        !          2070: 
        !          2071:        /* Allocate net device ( also allocates memory for netdev->priv
        !          2072:           and makes netdev-priv point to it )
        !          2073:         */
        !          2074:        netdev = alloc_etherdev ( sizeof ( *tp ) );
        !          2075: 
        !          2076:        if ( ! netdev )
        !          2077:                goto err_alloc_etherdev;
        !          2078: 
        !          2079:        /* Associate driver-specific network operations with
        !          2080:           generic network device layer
        !          2081:         */
        !          2082:        netdev_init ( netdev, &rtl8169_operations );
        !          2083: 
        !          2084:        /* Associate this network device with the given PCI device */
        !          2085:        pci_set_drvdata ( pdev, netdev );
        !          2086:        netdev->dev = &pdev->dev;
        !          2087: 
        !          2088:        /* Initialize driver private storage */
        !          2089:        tp = netdev_priv ( netdev );
        !          2090:        memset ( tp, 0, ( sizeof ( *tp ) ) );
        !          2091: 
        !          2092:        tp->pci_dev    = pdev;
        !          2093:        tp->irqno      = pdev->irq;
        !          2094:        tp->netdev     = netdev;
        !          2095:        tp->intr_event = cfg->intr_event;
        !          2096:        tp->cp_cmd     = PCIMulRW;
        !          2097: 
        !          2098:        tp->hw_start = cfg->hw_start;
        !          2099: 
        !          2100:        rc = -EIO;
        !          2101: 
        !          2102:        adjust_pci_device ( pdev );
        !          2103: 
        !          2104:        /* ioremap MMIO region */
        !          2105:        ioaddr = ioremap ( pdev->membase, R8169_REGS_SIZE );
        !          2106: 
        !          2107:        if ( ! ioaddr ) {
        !          2108:                DBG ( "cannot remap MMIO\n" );
        !          2109:                rc = -EIO;
        !          2110:                goto err_ioremap;
        !          2111:        }
        !          2112: 
        !          2113:        tp->mmio_addr = ioaddr;
        !          2114: 
        !          2115:        tp->pcie_cap = pci_find_capability ( pdev, PCI_CAP_ID_EXP );
        !          2116:        if ( tp->pcie_cap ) {
        !          2117:                DBG (  "PCI Express capability\n" );
        !          2118:        } else {
        !          2119:                DBG (  "No PCI Express capability\n" );
        !          2120:        }
        !          2121: 
        !          2122:        /* Mask interrupts just in case */
        !          2123:        rtl8169_irq_mask_and_ack ( ioaddr );
        !          2124: 
        !          2125:        /* Soft reset NIC */
        !          2126:        rtl_soft_reset ( netdev );
        !          2127: 
        !          2128:        /* Identify chip attached to board */
        !          2129:        rtl8169_get_mac_version ( tp, ioaddr );
        !          2130: 
        !          2131:        for ( i = 0; (u32) i < ARRAY_SIZE ( rtl_chip_info ); i++ ) {
        !          2132:                if ( tp->mac_version == rtl_chip_info[i].mac_version )
        !          2133:                        break;
        !          2134:        }
        !          2135:        if ( i == ARRAY_SIZE(rtl_chip_info ) ) {
        !          2136:                /* Unknown chip: assume array element #0, original RTL-8169 */
        !          2137:                DBG ( "Unknown chip version, assuming %s\n", rtl_chip_info[0].name );
        !          2138:                i = 0;
        !          2139:        }
        !          2140:        tp->chipset = i;
        !          2141: 
        !          2142:        if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) &&
        !          2143:            (RTL_R8(PHYstatus) & TBI_Enable)) {
        !          2144:                tp->set_speed = rtl8169_set_speed_tbi;
        !          2145:                tp->phy_reset_enable = rtl8169_tbi_reset_enable;
        !          2146:                tp->phy_reset_pending = rtl8169_tbi_reset_pending;
        !          2147:                tp->link_ok = rtl8169_tbi_link_ok;
        !          2148: 
        !          2149:                tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
        !          2150:        } else {
        !          2151:                tp->set_speed = rtl8169_set_speed_xmii;
        !          2152:                tp->phy_reset_enable = rtl8169_xmii_reset_enable;
        !          2153:                tp->phy_reset_pending = rtl8169_xmii_reset_pending;
        !          2154:                tp->link_ok = rtl8169_xmii_link_ok;
        !          2155:        }
        !          2156: 
        !          2157:        /* Get MAC address */
        !          2158:        for ( i = 0; i < MAC_ADDR_LEN; i++ )
        !          2159:                netdev->hw_addr[i] = RTL_R8 ( MAC0 + i );
        !          2160: 
        !          2161:        DBG ( "%s\n", eth_ntoa ( netdev->hw_addr ) );
        !          2162: 
        !          2163:        rtl8169_init_phy ( netdev, tp );
        !          2164: 
        !          2165:        if ( ( rc = register_netdev ( netdev ) ) != 0 )
        !          2166:                goto err_register;
        !          2167: 
        !          2168:        /* Mark as link up; we don't yet handle link state */
        !          2169:        netdev_link_up ( netdev );
        !          2170: 
        !          2171:        DBG ( "rtl8169_probe succeeded!\n" );
        !          2172: 
        !          2173:        /* No errors, return success */
        !          2174:        return 0;
        !          2175: 
        !          2176: /* Error return paths */
        !          2177: err_register:
        !          2178: err_ioremap:
        !          2179:        netdev_put ( netdev );
        !          2180: err_alloc_etherdev:
        !          2181:        return rc;
        !          2182: }
        !          2183: 
        !          2184: /**
        !          2185:  * remove - Device Removal Routine
        !          2186:  *
        !          2187:  * @v pdev PCI device information struct
        !          2188:  *
        !          2189:  **/
        !          2190: static void
        !          2191: rtl8169_remove ( struct pci_device *pdev )
        !          2192: {
        !          2193:        struct net_device *netdev = pci_get_drvdata ( pdev );
        !          2194:        struct rtl8169_private *tp = netdev_priv ( netdev );
        !          2195:        void *ioaddr = tp->mmio_addr;
        !          2196: 
        !          2197:        DBGP ( "rtl8169_remove\n" );
        !          2198: 
        !          2199:        rtl8169_hw_reset ( ioaddr );
        !          2200: 
        !          2201:        unregister_netdev ( netdev );
        !          2202:        netdev_nullify ( netdev );
        !          2203:        netdev_put ( netdev );
        !          2204: }
        !          2205: 
        !          2206: static struct pci_device_id rtl8169_nics[] = {
        !          2207:        PCI_ROM(0x10ec, 0x8129, "rtl8169-0x8129", "rtl8169-0x8129", RTL_CFG_0),
        !          2208:        PCI_ROM(0x10ec, 0x8136, "rtl8169-0x8136", "rtl8169-0x8136", RTL_CFG_2),
        !          2209:        PCI_ROM(0x10ec, 0x8167, "rtl8169-0x8167", "rtl8169-0x8167", RTL_CFG_0),
        !          2210:        PCI_ROM(0x10ec, 0x8168, "rtl8169-0x8168", "rtl8169-0x8168", RTL_CFG_1),
        !          2211:        PCI_ROM(0x10ec, 0x8169, "rtl8169-0x8169", "rtl8169-0x8169", RTL_CFG_0),
        !          2212:        PCI_ROM(0x1186, 0x4300, "rtl8169-0x4300", "rtl8169-0x4300", RTL_CFG_0),
        !          2213:        PCI_ROM(0x1259, 0xc107, "rtl8169-0xc107", "rtl8169-0xc107", RTL_CFG_0),
        !          2214:        PCI_ROM(0x16ec, 0x0116, "rtl8169-0x0116", "rtl8169-0x0116", RTL_CFG_0),
        !          2215:        PCI_ROM(0x1737, 0x1032, "rtl8169-0x1032", "rtl8169-0x1032", RTL_CFG_0),
        !          2216:        PCI_ROM(0x0001, 0x8168, "rtl8169-0x8168", "rtl8169-0x8168", RTL_CFG_2),
        !          2217: };
        !          2218: 
        !          2219: struct pci_driver rtl8169_driver __pci_driver = {
        !          2220:   .ids = rtl8169_nics,
        !          2221:   .id_count = ( sizeof ( rtl8169_nics ) / sizeof ( rtl8169_nics[0] ) ),
        !          2222:   .probe = rtl8169_probe,
        !          2223:   .remove = rtl8169_remove,
        !          2224: };
        !          2225: 
        !          2226: /*
        !          2227:  * Local variables:
        !          2228:  *  c-basic-offset: 8
        !          2229:  *  c-indent-level: 8
        !          2230:  *  tab-width: 8
        !          2231:  * End:
        !          2232:  */

unix.superglobalmegacorp.com

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