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

1.1     ! root        1: /*
        !             2:  * iPXE driver for Marvell Yukon chipset and SysKonnect Gigabit
        !             3:  * Ethernet adapters. Derived from Linux skge driver (v1.13), which was
        !             4:  * based on earlier sk98lin, e100 and FreeBSD if_sk drivers.
        !             5:  *
        !             6:  * This driver intentionally does not support all the features of the
        !             7:  * original driver such as link fail-over and link management because
        !             8:  * those should be done at higher levels.
        !             9:  *
        !            10:  * Copyright (C) 2004, 2005 Stephen Hemminger <[email protected]>
        !            11:  *
        !            12:  * Modified for iPXE, July 2008 by Michael Decker <[email protected]>
        !            13:  * Tested and Modified in December 2009 by
        !            14:  *    Thomas Miletich <[email protected]>
        !            15:  *
        !            16:  * This program is free software; you can redistribute it and/or modify
        !            17:  * it under the terms of the GNU General Public License as published by
        !            18:  * the Free Software Foundation; either version 2 of the License.
        !            19:  *
        !            20:  * This program is distributed in the hope that it will be useful,
        !            21:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            22:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            23:  * GNU General Public License for more details.
        !            24:  *
        !            25:  * You should have received a copy of the GNU General Public License
        !            26:  * along with this program; if not, write to the Free Software
        !            27:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            28:  */
        !            29: 
        !            30: FILE_LICENCE ( GPL2_ONLY );
        !            31: 
        !            32: #include <stdint.h>
        !            33: #include <errno.h>
        !            34: #include <stdio.h>
        !            35: #include <unistd.h>
        !            36: #include <ipxe/netdevice.h>
        !            37: #include <ipxe/ethernet.h>
        !            38: #include <ipxe/if_ether.h>
        !            39: #include <ipxe/iobuf.h>
        !            40: #include <ipxe/malloc.h>
        !            41: #include <ipxe/pci.h>
        !            42: 
        !            43: #include "skge.h"
        !            44: 
        !            45: static struct pci_device_id skge_id_table[] = {
        !            46:        PCI_ROM(0x10b7, 0x1700,     "3C940",     "3COM 3C940", 0),
        !            47:        PCI_ROM(0x10b7, 0x80eb,     "3C940B",    "3COM 3C940", 0),
        !            48:        PCI_ROM(0x1148, 0x4300,     "GE",        "Syskonnect GE", 0),
        !            49:        PCI_ROM(0x1148, 0x4320,     "YU",        "Syskonnect YU", 0),
        !            50:        PCI_ROM(0x1186, 0x4C00,     "DGE510T",   "DLink DGE-510T", 0),
        !            51:        PCI_ROM(0x1186, 0x4b01,     "DGE530T",   "DLink DGE-530T", 0),
        !            52:        PCI_ROM(0x11ab, 0x4320,     "id4320",    "Marvell id4320", 0),
        !            53:        PCI_ROM(0x11ab, 0x5005,     "id5005",    "Marvell id5005", 0), /* Belkin */
        !            54:        PCI_ROM(0x1371, 0x434e,     "Gigacard",  "CNET Gigacard", 0),
        !            55:        PCI_ROM(0x1737, 0x1064,     "EG1064",    "Linksys EG1064", 0),
        !            56:        PCI_ROM(0x1737, 0xffff,     "id_any",    "Linksys [any]", 0)
        !            57: };
        !            58: 
        !            59: static int skge_up(struct net_device *dev);
        !            60: static void skge_down(struct net_device *dev);
        !            61: static void skge_tx_clean(struct net_device *dev);
        !            62: static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
        !            63: static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
        !            64: static void yukon_init(struct skge_hw *hw, int port);
        !            65: static void genesis_mac_init(struct skge_hw *hw, int port);
        !            66: static void genesis_link_up(struct skge_port *skge);
        !            67: 
        !            68: static void skge_phyirq(struct skge_hw *hw);
        !            69: static void skge_poll(struct net_device *dev);
        !            70: static int skge_xmit_frame(struct net_device *dev, struct io_buffer *iob);
        !            71: static void skge_net_irq ( struct net_device *dev, int enable );
        !            72: 
        !            73: static void skge_rx_refill(struct net_device *dev);
        !            74: 
        !            75: static struct net_device_operations skge_operations = {
        !            76:        .open     = skge_up,
        !            77:        .close    = skge_down,
        !            78:        .transmit = skge_xmit_frame,
        !            79:        .poll     = skge_poll,
        !            80:        .irq      = skge_net_irq
        !            81: };
        !            82: 
        !            83: /* Avoid conditionals by using array */
        !            84: static const int txqaddr[] = { Q_XA1, Q_XA2 };
        !            85: static const int rxqaddr[] = { Q_R1, Q_R2 };
        !            86: static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
        !            87: static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
        !            88: static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
        !            89: static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 };
        !            90: 
        !            91: /* Determine supported/advertised modes based on hardware.
        !            92:  * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
        !            93:  */
        !            94: static u32 skge_supported_modes(const struct skge_hw *hw)
        !            95: {
        !            96:        u32 supported;
        !            97: 
        !            98:        if (hw->copper) {
        !            99:                supported = SUPPORTED_10baseT_Half
        !           100:                        | SUPPORTED_10baseT_Full
        !           101:                        | SUPPORTED_100baseT_Half
        !           102:                        | SUPPORTED_100baseT_Full
        !           103:                        | SUPPORTED_1000baseT_Half
        !           104:                        | SUPPORTED_1000baseT_Full
        !           105:                        | SUPPORTED_Autoneg| SUPPORTED_TP;
        !           106: 
        !           107:                if (hw->chip_id == CHIP_ID_GENESIS)
        !           108:                        supported &= ~(SUPPORTED_10baseT_Half
        !           109:                                             | SUPPORTED_10baseT_Full
        !           110:                                             | SUPPORTED_100baseT_Half
        !           111:                                             | SUPPORTED_100baseT_Full);
        !           112: 
        !           113:                else if (hw->chip_id == CHIP_ID_YUKON)
        !           114:                        supported &= ~SUPPORTED_1000baseT_Half;
        !           115:        } else
        !           116:                supported = SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half
        !           117:                        | SUPPORTED_FIBRE | SUPPORTED_Autoneg;
        !           118: 
        !           119:        return supported;
        !           120: }
        !           121: 
        !           122: /* Chip internal frequency for clock calculations */
        !           123: static inline u32 hwkhz(const struct skge_hw *hw)
        !           124: {
        !           125:        return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125;
        !           126: }
        !           127: 
        !           128: /* Microseconds to chip HZ */
        !           129: static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
        !           130: {
        !           131:        return hwkhz(hw) * usec / 1000;
        !           132: }
        !           133: 
        !           134: enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST };
        !           135: static void skge_led(struct skge_port *skge, enum led_mode mode)
        !           136: {
        !           137:        struct skge_hw *hw = skge->hw;
        !           138:        int port = skge->port;
        !           139: 
        !           140:        if (hw->chip_id == CHIP_ID_GENESIS) {
        !           141:                switch (mode) {
        !           142:                case LED_MODE_OFF:
        !           143:                        if (hw->phy_type == SK_PHY_BCOM)
        !           144:                                xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
        !           145:                        else {
        !           146:                                skge_write32(hw, SK_REG(port, TX_LED_VAL), 0);
        !           147:                                skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF);
        !           148:                        }
        !           149:                        skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
        !           150:                        skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
        !           151:                        skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
        !           152:                        break;
        !           153: 
        !           154:                case LED_MODE_ON:
        !           155:                        skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
        !           156:                        skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
        !           157: 
        !           158:                        skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
        !           159:                        skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
        !           160: 
        !           161:                        break;
        !           162: 
        !           163:                case LED_MODE_TST:
        !           164:                        skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
        !           165:                        skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
        !           166:                        skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
        !           167: 
        !           168:                        if (hw->phy_type == SK_PHY_BCOM)
        !           169:                                xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
        !           170:                        else {
        !           171:                                skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON);
        !           172:                                skge_write32(hw, SK_REG(port, TX_LED_VAL), 100);
        !           173:                                skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
        !           174:                        }
        !           175: 
        !           176:                }
        !           177:        } else {
        !           178:                switch (mode) {
        !           179:                case LED_MODE_OFF:
        !           180:                        gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
        !           181:                        gm_phy_write(hw, port, PHY_MARV_LED_OVER,
        !           182:                                     PHY_M_LED_MO_DUP(MO_LED_OFF)  |
        !           183:                                     PHY_M_LED_MO_10(MO_LED_OFF)   |
        !           184:                                     PHY_M_LED_MO_100(MO_LED_OFF)  |
        !           185:                                     PHY_M_LED_MO_1000(MO_LED_OFF) |
        !           186:                                     PHY_M_LED_MO_RX(MO_LED_OFF));
        !           187:                        break;
        !           188:                case LED_MODE_ON:
        !           189:                        gm_phy_write(hw, port, PHY_MARV_LED_CTRL,
        !           190:                                     PHY_M_LED_PULS_DUR(PULS_170MS) |
        !           191:                                     PHY_M_LED_BLINK_RT(BLINK_84MS) |
        !           192:                                     PHY_M_LEDC_TX_CTRL |
        !           193:                                     PHY_M_LEDC_DP_CTRL);
        !           194: 
        !           195:                        gm_phy_write(hw, port, PHY_MARV_LED_OVER,
        !           196:                                     PHY_M_LED_MO_RX(MO_LED_OFF) |
        !           197:                                     (skge->speed == SPEED_100 ?
        !           198:                                      PHY_M_LED_MO_100(MO_LED_ON) : 0));
        !           199:                        break;
        !           200:                case LED_MODE_TST:
        !           201:                        gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
        !           202:                        gm_phy_write(hw, port, PHY_MARV_LED_OVER,
        !           203:                                     PHY_M_LED_MO_DUP(MO_LED_ON)  |
        !           204:                                     PHY_M_LED_MO_10(MO_LED_ON)   |
        !           205:                                     PHY_M_LED_MO_100(MO_LED_ON)  |
        !           206:                                     PHY_M_LED_MO_1000(MO_LED_ON) |
        !           207:                                     PHY_M_LED_MO_RX(MO_LED_ON));
        !           208:                }
        !           209:        }
        !           210: }
        !           211: 
        !           212: /*
        !           213:  * I've left in these EEPROM and VPD functions, as someone may desire to
        !           214:  * integrate them in the future. -mdeck
        !           215:  *
        !           216:  * static int skge_get_eeprom_len(struct net_device *dev)
        !           217:  * {
        !           218:  *     struct skge_port *skge = netdev_priv(dev);
        !           219:  *     u32 reg2;
        !           220:  *
        !           221:  *     pci_read_config_dword(skge->hw->pdev, PCI_DEV_REG2, &reg2);
        !           222:  *     return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
        !           223:  * }
        !           224:  *
        !           225:  * static u32 skge_vpd_read(struct pci_dev *pdev, int cap, u16 offset)
        !           226:  * {
        !           227:  *     u32 val;
        !           228:  *
        !           229:  *     pci_write_config_word(pdev, cap + PCI_VPD_ADDR, offset);
        !           230:  *
        !           231:  *     do {
        !           232:  *             pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
        !           233:  *     } while (!(offset & PCI_VPD_ADDR_F));
        !           234:  *
        !           235:  *     pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &val);
        !           236:  *     return val;
        !           237:  * }
        !           238:  *
        !           239:  * static void skge_vpd_write(struct pci_dev *pdev, int cap, u16 offset, u32 val)
        !           240:  * {
        !           241:  *     pci_write_config_dword(pdev, cap + PCI_VPD_DATA, val);
        !           242:  *     pci_write_config_word(pdev, cap + PCI_VPD_ADDR,
        !           243:  *                           offset | PCI_VPD_ADDR_F);
        !           244:  *
        !           245:  *     do {
        !           246:  *             pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
        !           247:  *     } while (offset & PCI_VPD_ADDR_F);
        !           248:  * }
        !           249:  *
        !           250:  * static int skge_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        !           251:  *                        u8 *data)
        !           252:  * {
        !           253:  *     struct skge_port *skge = netdev_priv(dev);
        !           254:  *     struct pci_dev *pdev = skge->hw->pdev;
        !           255:  *     int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD);
        !           256:  *     int length = eeprom->len;
        !           257:  *     u16 offset = eeprom->offset;
        !           258:  *
        !           259:  *     if (!cap)
        !           260:  *             return -EINVAL;
        !           261:  *
        !           262:  *     eeprom->magic = SKGE_EEPROM_MAGIC;
        !           263:  *
        !           264:  *     while (length > 0) {
        !           265:  *             u32 val = skge_vpd_read(pdev, cap, offset);
        !           266:  *             int n = min_t(int, length, sizeof(val));
        !           267:  *
        !           268:  *             memcpy(data, &val, n);
        !           269:  *             length -= n;
        !           270:  *             data += n;
        !           271:  *             offset += n;
        !           272:  *     }
        !           273:  *     return 0;
        !           274:  * }
        !           275:  *
        !           276:  * static int skge_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        !           277:  *                        u8 *data)
        !           278:  * {
        !           279:  *     struct skge_port *skge = netdev_priv(dev);
        !           280:  *     struct pci_dev *pdev = skge->hw->pdev;
        !           281:  *     int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD);
        !           282:  *     int length = eeprom->len;
        !           283:  *     u16 offset = eeprom->offset;
        !           284:  *
        !           285:  *     if (!cap)
        !           286:  *             return -EINVAL;
        !           287:  *
        !           288:  *     if (eeprom->magic != SKGE_EEPROM_MAGIC)
        !           289:  *             return -EINVAL;
        !           290:  *
        !           291:  *     while (length > 0) {
        !           292:  *             u32 val;
        !           293:  *             int n = min_t(int, length, sizeof(val));
        !           294:  *
        !           295:  *             if (n < sizeof(val))
        !           296:  *                     val = skge_vpd_read(pdev, cap, offset);
        !           297:  *             memcpy(&val, data, n);
        !           298:  *
        !           299:  *             skge_vpd_write(pdev, cap, offset, val);
        !           300:  *
        !           301:  *             length -= n;
        !           302:  *             data += n;
        !           303:  *             offset += n;
        !           304:  *     }
        !           305:  *     return 0;
        !           306:  * }
        !           307:  */
        !           308: 
        !           309: /*
        !           310:  * Allocate ring elements and chain them together
        !           311:  * One-to-one association of board descriptors with ring elements
        !           312:  */
        !           313: static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base,
        !           314:                            size_t num)
        !           315: {
        !           316:        struct skge_tx_desc *d;
        !           317:        struct skge_element *e;
        !           318:        unsigned int i;
        !           319: 
        !           320:        ring->start = zalloc(num*sizeof(*e));
        !           321:        if (!ring->start)
        !           322:                return -ENOMEM;
        !           323: 
        !           324:        for (i = 0, e = ring->start, d = vaddr; i < num; i++, e++, d++) {
        !           325:                e->desc = d;
        !           326:                if (i == num - 1) {
        !           327:                        e->next = ring->start;
        !           328:                        d->next_offset = base;
        !           329:                } else {
        !           330:                        e->next = e + 1;
        !           331:                        d->next_offset = base + (i+1) * sizeof(*d);
        !           332:                }
        !           333:        }
        !           334:        ring->to_use = ring->to_clean = ring->start;
        !           335: 
        !           336:        return 0;
        !           337: }
        !           338: 
        !           339: /* Allocate and setup a new buffer for receiving */
        !           340: static void skge_rx_setup(struct skge_port *skge __unused,
        !           341:                          struct skge_element *e,
        !           342:                          struct io_buffer *iob, unsigned int bufsize)
        !           343: {
        !           344:        struct skge_rx_desc *rd = e->desc;
        !           345:        u64 map;
        !           346: 
        !           347:        map = ( iob != NULL ) ? virt_to_bus(iob->data) : 0;
        !           348: 
        !           349:        rd->dma_lo = map;
        !           350:        rd->dma_hi = map >> 32;
        !           351:        e->iob = iob;
        !           352:        rd->csum1_start = ETH_HLEN;
        !           353:        rd->csum2_start = ETH_HLEN;
        !           354:        rd->csum1 = 0;
        !           355:        rd->csum2 = 0;
        !           356: 
        !           357:        wmb();
        !           358: 
        !           359:        rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
        !           360: }
        !           361: 
        !           362: /* Resume receiving using existing skb,
        !           363:  * Note: DMA address is not changed by chip.
        !           364:  *      MTU not changed while receiver active.
        !           365:  */
        !           366: static inline void skge_rx_reuse(struct skge_element *e, unsigned int size)
        !           367: {
        !           368:        struct skge_rx_desc *rd = e->desc;
        !           369: 
        !           370:        rd->csum2 = 0;
        !           371:        rd->csum2_start = ETH_HLEN;
        !           372: 
        !           373:        wmb();
        !           374: 
        !           375:        rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size;
        !           376: }
        !           377: 
        !           378: 
        !           379: /* Free all  buffers in receive ring, assumes receiver stopped */
        !           380: static void skge_rx_clean(struct skge_port *skge)
        !           381: {
        !           382:        struct skge_ring *ring = &skge->rx_ring;
        !           383:        struct skge_element *e;
        !           384: 
        !           385:        e = ring->start;
        !           386:        do {
        !           387:                struct skge_rx_desc *rd = e->desc;
        !           388:                rd->control = 0;
        !           389:                if (e->iob) {
        !           390:                        free_iob(e->iob);
        !           391:                        e->iob = NULL;
        !           392:                }
        !           393:        } while ((e = e->next) != ring->start);
        !           394: }
        !           395: 
        !           396: static void skge_link_up(struct skge_port *skge)
        !           397: {
        !           398:        skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
        !           399:                    LED_BLK_OFF|LED_SYNC_OFF|LED_ON);
        !           400: 
        !           401:        netdev_link_up(skge->netdev);
        !           402: 
        !           403:        DBG2(PFX "%s: Link is up at %d Mbps, %s duplex\n",
        !           404:             skge->netdev->name, skge->speed,
        !           405:             skge->duplex == DUPLEX_FULL ? "full" : "half");
        !           406: }
        !           407: 
        !           408: static void skge_link_down(struct skge_port *skge)
        !           409: {
        !           410:        skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
        !           411:        netdev_link_down(skge->netdev);
        !           412: 
        !           413:        DBG2(PFX "%s: Link is down.\n", skge->netdev->name);
        !           414: }
        !           415: 
        !           416: 
        !           417: static void xm_link_down(struct skge_hw *hw, int port)
        !           418: {
        !           419:        struct net_device *dev = hw->dev[port];
        !           420:        struct skge_port *skge = netdev_priv(dev);
        !           421: 
        !           422:        xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);
        !           423: 
        !           424:        if (netdev_link_ok(dev))
        !           425:                skge_link_down(skge);
        !           426: }
        !           427: 
        !           428: static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
        !           429: {
        !           430:        int i;
        !           431: 
        !           432:        xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
        !           433:        *val = xm_read16(hw, port, XM_PHY_DATA);
        !           434: 
        !           435:        if (hw->phy_type == SK_PHY_XMAC)
        !           436:                goto ready;
        !           437: 
        !           438:        for (i = 0; i < PHY_RETRIES; i++) {
        !           439:                if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
        !           440:                        goto ready;
        !           441:                udelay(1);
        !           442:        }
        !           443: 
        !           444:        return -ETIMEDOUT;
        !           445:  ready:
        !           446:        *val = xm_read16(hw, port, XM_PHY_DATA);
        !           447: 
        !           448:        return 0;
        !           449: }
        !           450: 
        !           451: static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
        !           452: {
        !           453:        u16 v = 0;
        !           454:        if (__xm_phy_read(hw, port, reg, &v))
        !           455:                DBG(PFX "%s: phy read timed out\n",
        !           456:                       hw->dev[port]->name);
        !           457:        return v;
        !           458: }
        !           459: 
        !           460: static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
        !           461: {
        !           462:        int i;
        !           463: 
        !           464:        xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
        !           465:        for (i = 0; i < PHY_RETRIES; i++) {
        !           466:                if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
        !           467:                        goto ready;
        !           468:                udelay(1);
        !           469:        }
        !           470:        return -EIO;
        !           471: 
        !           472:  ready:
        !           473:        xm_write16(hw, port, XM_PHY_DATA, val);
        !           474:        for (i = 0; i < PHY_RETRIES; i++) {
        !           475:                if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
        !           476:                        return 0;
        !           477:                udelay(1);
        !           478:        }
        !           479:        return -ETIMEDOUT;
        !           480: }
        !           481: 
        !           482: static void genesis_init(struct skge_hw *hw)
        !           483: {
        !           484:        /* set blink source counter */
        !           485:        skge_write32(hw, B2_BSC_INI, (SK_BLK_DUR * SK_FACT_53) / 100);
        !           486:        skge_write8(hw, B2_BSC_CTRL, BSC_START);
        !           487: 
        !           488:        /* configure mac arbiter */
        !           489:        skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
        !           490: 
        !           491:        /* configure mac arbiter timeout values */
        !           492:        skge_write8(hw, B3_MA_TOINI_RX1, SK_MAC_TO_53);
        !           493:        skge_write8(hw, B3_MA_TOINI_RX2, SK_MAC_TO_53);
        !           494:        skge_write8(hw, B3_MA_TOINI_TX1, SK_MAC_TO_53);
        !           495:        skge_write8(hw, B3_MA_TOINI_TX2, SK_MAC_TO_53);
        !           496: 
        !           497:        skge_write8(hw, B3_MA_RCINI_RX1, 0);
        !           498:        skge_write8(hw, B3_MA_RCINI_RX2, 0);
        !           499:        skge_write8(hw, B3_MA_RCINI_TX1, 0);
        !           500:        skge_write8(hw, B3_MA_RCINI_TX2, 0);
        !           501: 
        !           502:        /* configure packet arbiter timeout */
        !           503:        skge_write16(hw, B3_PA_CTRL, PA_RST_CLR);
        !           504:        skge_write16(hw, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
        !           505:        skge_write16(hw, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
        !           506:        skge_write16(hw, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
        !           507:        skge_write16(hw, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
        !           508: }
        !           509: 
        !           510: static void genesis_reset(struct skge_hw *hw, int port)
        !           511: {
        !           512:        const u8 zero[8]  = { 0 };
        !           513:        u32 reg;
        !           514: 
        !           515:        skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
        !           516: 
        !           517:        /* reset the statistics module */
        !           518:        xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
        !           519:        xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);
        !           520:        xm_write32(hw, port, XM_MODE, 0);               /* clear Mode Reg */
        !           521:        xm_write16(hw, port, XM_TX_CMD, 0);     /* reset TX CMD Reg */
        !           522:        xm_write16(hw, port, XM_RX_CMD, 0);     /* reset RX CMD Reg */
        !           523: 
        !           524:        /* disable Broadcom PHY IRQ */
        !           525:        if (hw->phy_type == SK_PHY_BCOM)
        !           526:                xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
        !           527: 
        !           528:        xm_outhash(hw, port, XM_HSM, zero);
        !           529: 
        !           530:        /* Flush TX and RX fifo */
        !           531:        reg = xm_read32(hw, port, XM_MODE);
        !           532:        xm_write32(hw, port, XM_MODE, reg | XM_MD_FTF);
        !           533:        xm_write32(hw, port, XM_MODE, reg | XM_MD_FRF);
        !           534: }
        !           535: 
        !           536: 
        !           537: /* Convert mode to MII values  */
        !           538: static const u16 phy_pause_map[] = {
        !           539:        [FLOW_MODE_NONE] =      0,
        !           540:        [FLOW_MODE_LOC_SEND] =  PHY_AN_PAUSE_ASYM,
        !           541:        [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
        !           542:        [FLOW_MODE_SYM_OR_REM]  = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
        !           543: };
        !           544: 
        !           545: /* special defines for FIBER (88E1011S only) */
        !           546: static const u16 fiber_pause_map[] = {
        !           547:        [FLOW_MODE_NONE]        = PHY_X_P_NO_PAUSE,
        !           548:        [FLOW_MODE_LOC_SEND]    = PHY_X_P_ASYM_MD,
        !           549:        [FLOW_MODE_SYMMETRIC]   = PHY_X_P_SYM_MD,
        !           550:        [FLOW_MODE_SYM_OR_REM]  = PHY_X_P_BOTH_MD,
        !           551: };
        !           552: 
        !           553: 
        !           554: /* Check status of Broadcom phy link */
        !           555: static void bcom_check_link(struct skge_hw *hw, int port)
        !           556: {
        !           557:        struct net_device *dev = hw->dev[port];
        !           558:        struct skge_port *skge = netdev_priv(dev);
        !           559:        u16 status;
        !           560: 
        !           561:        /* read twice because of latch */
        !           562:        xm_phy_read(hw, port, PHY_BCOM_STAT);
        !           563:        status = xm_phy_read(hw, port, PHY_BCOM_STAT);
        !           564: 
        !           565:        if ((status & PHY_ST_LSYNC) == 0) {
        !           566:                xm_link_down(hw, port);
        !           567:                return;
        !           568:        }
        !           569: 
        !           570:        if (skge->autoneg == AUTONEG_ENABLE) {
        !           571:                u16 lpa, aux;
        !           572: 
        !           573:                if (!(status & PHY_ST_AN_OVER))
        !           574:                        return;
        !           575: 
        !           576:                lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
        !           577:                if (lpa & PHY_B_AN_RF) {
        !           578:                        DBG(PFX "%s: remote fault\n",
        !           579:                               dev->name);
        !           580:                        return;
        !           581:                }
        !           582: 
        !           583:                aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
        !           584: 
        !           585:                /* Check Duplex mismatch */
        !           586:                switch (aux & PHY_B_AS_AN_RES_MSK) {
        !           587:                case PHY_B_RES_1000FD:
        !           588:                        skge->duplex = DUPLEX_FULL;
        !           589:                        break;
        !           590:                case PHY_B_RES_1000HD:
        !           591:                        skge->duplex = DUPLEX_HALF;
        !           592:                        break;
        !           593:                default:
        !           594:                        DBG(PFX "%s: duplex mismatch\n",
        !           595:                               dev->name);
        !           596:                        return;
        !           597:                }
        !           598: 
        !           599:                /* We are using IEEE 802.3z/D5.0 Table 37-4 */
        !           600:                switch (aux & PHY_B_AS_PAUSE_MSK) {
        !           601:                case PHY_B_AS_PAUSE_MSK:
        !           602:                        skge->flow_status = FLOW_STAT_SYMMETRIC;
        !           603:                        break;
        !           604:                case PHY_B_AS_PRR:
        !           605:                        skge->flow_status = FLOW_STAT_REM_SEND;
        !           606:                        break;
        !           607:                case PHY_B_AS_PRT:
        !           608:                        skge->flow_status = FLOW_STAT_LOC_SEND;
        !           609:                        break;
        !           610:                default:
        !           611:                        skge->flow_status = FLOW_STAT_NONE;
        !           612:                }
        !           613:                skge->speed = SPEED_1000;
        !           614:        }
        !           615: 
        !           616:        if (!netdev_link_ok(dev))
        !           617:                genesis_link_up(skge);
        !           618: }
        !           619: 
        !           620: /* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
        !           621:  * Phy on for 100 or 10Mbit operation
        !           622:  */
        !           623: static void bcom_phy_init(struct skge_port *skge)
        !           624: {
        !           625:        struct skge_hw *hw = skge->hw;
        !           626:        int port = skge->port;
        !           627:        unsigned int i;
        !           628:        u16 id1, r, ext, ctl;
        !           629: 
        !           630:        /* magic workaround patterns for Broadcom */
        !           631:        static const struct {
        !           632:                u16 reg;
        !           633:                u16 val;
        !           634:        } A1hack[] = {
        !           635:                { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 },
        !           636:                { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 },
        !           637:                { 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 },
        !           638:                { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
        !           639:        }, C0hack[] = {
        !           640:                { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 },
        !           641:                { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
        !           642:        };
        !           643: 
        !           644:        /* read Id from external PHY (all have the same address) */
        !           645:        id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
        !           646: 
        !           647:        /* Optimize MDIO transfer by suppressing preamble. */
        !           648:        r = xm_read16(hw, port, XM_MMU_CMD);
        !           649:        r |=  XM_MMU_NO_PRE;
        !           650:        xm_write16(hw, port, XM_MMU_CMD,r);
        !           651: 
        !           652:        switch (id1) {
        !           653:        case PHY_BCOM_ID1_C0:
        !           654:                /*
        !           655:                 * Workaround BCOM Errata for the C0 type.
        !           656:                 * Write magic patterns to reserved registers.
        !           657:                 */
        !           658:                for (i = 0; i < ARRAY_SIZE(C0hack); i++)
        !           659:                        xm_phy_write(hw, port,
        !           660:                                     C0hack[i].reg, C0hack[i].val);
        !           661: 
        !           662:                break;
        !           663:        case PHY_BCOM_ID1_A1:
        !           664:                /*
        !           665:                 * Workaround BCOM Errata for the A1 type.
        !           666:                 * Write magic patterns to reserved registers.
        !           667:                 */
        !           668:                for (i = 0; i < ARRAY_SIZE(A1hack); i++)
        !           669:                        xm_phy_write(hw, port,
        !           670:                                     A1hack[i].reg, A1hack[i].val);
        !           671:                break;
        !           672:        }
        !           673: 
        !           674:        /*
        !           675:         * Workaround BCOM Errata (#10523) for all BCom PHYs.
        !           676:         * Disable Power Management after reset.
        !           677:         */
        !           678:        r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
        !           679:        r |= PHY_B_AC_DIS_PM;
        !           680:        xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r);
        !           681: 
        !           682:        /* Dummy read */
        !           683:        xm_read16(hw, port, XM_ISRC);
        !           684: 
        !           685:        ext = PHY_B_PEC_EN_LTR; /* enable tx led */
        !           686:        ctl = PHY_CT_SP1000;    /* always 1000mbit */
        !           687: 
        !           688:        if (skge->autoneg == AUTONEG_ENABLE) {
        !           689:                /*
        !           690:                 * Workaround BCOM Errata #1 for the C5 type.
        !           691:                 * 1000Base-T Link Acquisition Failure in Slave Mode
        !           692:                 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
        !           693:                 */
        !           694:                u16 adv = PHY_B_1000C_RD;
        !           695:                if (skge->advertising & ADVERTISED_1000baseT_Half)
        !           696:                        adv |= PHY_B_1000C_AHD;
        !           697:                if (skge->advertising & ADVERTISED_1000baseT_Full)
        !           698:                        adv |= PHY_B_1000C_AFD;
        !           699:                xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv);
        !           700: 
        !           701:                ctl |= PHY_CT_ANE | PHY_CT_RE_CFG;
        !           702:        } else {
        !           703:                if (skge->duplex == DUPLEX_FULL)
        !           704:                        ctl |= PHY_CT_DUP_MD;
        !           705:                /* Force to slave */
        !           706:                xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE);
        !           707:        }
        !           708: 
        !           709:        /* Set autonegotiation pause parameters */
        !           710:        xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV,
        !           711:                     phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
        !           712: 
        !           713:        xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
        !           714:        xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
        !           715: 
        !           716:        /* Use link status change interrupt */
        !           717:        xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
        !           718: }
        !           719: 
        !           720: static void xm_phy_init(struct skge_port *skge)
        !           721: {
        !           722:        struct skge_hw *hw = skge->hw;
        !           723:        int port = skge->port;
        !           724:        u16 ctrl = 0;
        !           725: 
        !           726:        if (skge->autoneg == AUTONEG_ENABLE) {
        !           727:                if (skge->advertising & ADVERTISED_1000baseT_Half)
        !           728:                        ctrl |= PHY_X_AN_HD;
        !           729:                if (skge->advertising & ADVERTISED_1000baseT_Full)
        !           730:                        ctrl |= PHY_X_AN_FD;
        !           731: 
        !           732:                ctrl |= fiber_pause_map[skge->flow_control];
        !           733: 
        !           734:                xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl);
        !           735: 
        !           736:                /* Restart Auto-negotiation */
        !           737:                ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
        !           738:        } else {
        !           739:                /* Set DuplexMode in Config register */
        !           740:                if (skge->duplex == DUPLEX_FULL)
        !           741:                        ctrl |= PHY_CT_DUP_MD;
        !           742:                /*
        !           743:                 * Do NOT enable Auto-negotiation here. This would hold
        !           744:                 * the link down because no IDLEs are transmitted
        !           745:                 */
        !           746:        }
        !           747: 
        !           748:        xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);
        !           749: 
        !           750:        /* Poll PHY for status changes */
        !           751:        skge->use_xm_link_timer = 1;
        !           752: }
        !           753: 
        !           754: static int xm_check_link(struct net_device *dev)
        !           755: {
        !           756:        struct skge_port *skge = netdev_priv(dev);
        !           757:        struct skge_hw *hw = skge->hw;
        !           758:        int port = skge->port;
        !           759:        u16 status;
        !           760: 
        !           761:        /* read twice because of latch */
        !           762:        xm_phy_read(hw, port, PHY_XMAC_STAT);
        !           763:        status = xm_phy_read(hw, port, PHY_XMAC_STAT);
        !           764: 
        !           765:        if ((status & PHY_ST_LSYNC) == 0) {
        !           766:                xm_link_down(hw, port);
        !           767:                return 0;
        !           768:        }
        !           769: 
        !           770:        if (skge->autoneg == AUTONEG_ENABLE) {
        !           771:                u16 lpa, res;
        !           772: 
        !           773:                if (!(status & PHY_ST_AN_OVER))
        !           774:                        return 0;
        !           775: 
        !           776:                lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
        !           777:                if (lpa & PHY_B_AN_RF) {
        !           778:                        DBG(PFX "%s: remote fault\n",
        !           779:                               dev->name);
        !           780:                        return 0;
        !           781:                }
        !           782: 
        !           783:                res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI);
        !           784: 
        !           785:                /* Check Duplex mismatch */
        !           786:                switch (res & (PHY_X_RS_HD | PHY_X_RS_FD)) {
        !           787:                case PHY_X_RS_FD:
        !           788:                        skge->duplex = DUPLEX_FULL;
        !           789:                        break;
        !           790:                case PHY_X_RS_HD:
        !           791:                        skge->duplex = DUPLEX_HALF;
        !           792:                        break;
        !           793:                default:
        !           794:                        DBG(PFX "%s: duplex mismatch\n",
        !           795:                               dev->name);
        !           796:                        return 0;
        !           797:                }
        !           798: 
        !           799:                /* We are using IEEE 802.3z/D5.0 Table 37-4 */
        !           800:                if ((skge->flow_control == FLOW_MODE_SYMMETRIC ||
        !           801:                     skge->flow_control == FLOW_MODE_SYM_OR_REM) &&
        !           802:                    (lpa & PHY_X_P_SYM_MD))
        !           803:                        skge->flow_status = FLOW_STAT_SYMMETRIC;
        !           804:                else if (skge->flow_control == FLOW_MODE_SYM_OR_REM &&
        !           805:                         (lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
        !           806:                        /* Enable PAUSE receive, disable PAUSE transmit */
        !           807:                        skge->flow_status  = FLOW_STAT_REM_SEND;
        !           808:                else if (skge->flow_control == FLOW_MODE_LOC_SEND &&
        !           809:                         (lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
        !           810:                        /* Disable PAUSE receive, enable PAUSE transmit */
        !           811:                        skge->flow_status = FLOW_STAT_LOC_SEND;
        !           812:                else
        !           813:                        skge->flow_status = FLOW_STAT_NONE;
        !           814: 
        !           815:                skge->speed = SPEED_1000;
        !           816:        }
        !           817: 
        !           818:        if (!netdev_link_ok(dev))
        !           819:                genesis_link_up(skge);
        !           820:        return 1;
        !           821: }
        !           822: 
        !           823: /* Poll to check for link coming up.
        !           824:  *
        !           825:  * Since internal PHY is wired to a level triggered pin, can't
        !           826:  * get an interrupt when carrier is detected, need to poll for
        !           827:  * link coming up.
        !           828:  */
        !           829: static void xm_link_timer(struct skge_port *skge)
        !           830: {
        !           831:        struct net_device *dev = skge->netdev;
        !           832:        struct skge_hw *hw = skge->hw;
        !           833:        int port = skge->port;
        !           834:        int i;
        !           835: 
        !           836:        /*
        !           837:         * Verify that the link by checking GPIO register three times.
        !           838:         * This pin has the signal from the link_sync pin connected to it.
        !           839:         */
        !           840:        for (i = 0; i < 3; i++) {
        !           841:                if (xm_read16(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
        !           842:                        return;
        !           843:        }
        !           844: 
        !           845:         /* Re-enable interrupt to detect link down */
        !           846:        if (xm_check_link(dev)) {
        !           847:                u16 msk = xm_read16(hw, port, XM_IMSK);
        !           848:                msk &= ~XM_IS_INP_ASS;
        !           849:                xm_write16(hw, port, XM_IMSK, msk);
        !           850:                xm_read16(hw, port, XM_ISRC);
        !           851:        }
        !           852: }
        !           853: 
        !           854: static void genesis_mac_init(struct skge_hw *hw, int port)
        !           855: {
        !           856:        struct net_device *dev = hw->dev[port];
        !           857:        struct skge_port *skge = netdev_priv(dev);
        !           858:        int i;
        !           859:        u32 r;
        !           860:        const u8 zero[6]  = { 0 };
        !           861: 
        !           862:        for (i = 0; i < 10; i++) {
        !           863:                skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
        !           864:                             MFF_SET_MAC_RST);
        !           865:                if (skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST)
        !           866:                        goto reset_ok;
        !           867:                udelay(1);
        !           868:        }
        !           869: 
        !           870:        DBG(PFX "%s: genesis reset failed\n", dev->name);
        !           871: 
        !           872:  reset_ok:
        !           873:        /* Unreset the XMAC. */
        !           874:        skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
        !           875: 
        !           876:        /*
        !           877:         * Perform additional initialization for external PHYs,
        !           878:         * namely for the 1000baseTX cards that use the XMAC's
        !           879:         * GMII mode.
        !           880:         */
        !           881:        if (hw->phy_type != SK_PHY_XMAC) {
        !           882:                /* Take external Phy out of reset */
        !           883:                r = skge_read32(hw, B2_GP_IO);
        !           884:                if (port == 0)
        !           885:                        r |= GP_DIR_0|GP_IO_0;
        !           886:                else
        !           887:                        r |= GP_DIR_2|GP_IO_2;
        !           888: 
        !           889:                skge_write32(hw, B2_GP_IO, r);
        !           890: 
        !           891:                /* Enable GMII interface */
        !           892:                xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
        !           893:        }
        !           894: 
        !           895: 
        !           896:        switch(hw->phy_type) {
        !           897:        case SK_PHY_XMAC:
        !           898:                xm_phy_init(skge);
        !           899:                break;
        !           900:        case SK_PHY_BCOM:
        !           901:                bcom_phy_init(skge);
        !           902:                bcom_check_link(hw, port);
        !           903:        }
        !           904: 
        !           905:        /* Set Station Address */
        !           906:        xm_outaddr(hw, port, XM_SA, dev->ll_addr);
        !           907: 
        !           908:        /* We don't use match addresses so clear */
        !           909:        for (i = 1; i < 16; i++)
        !           910:                xm_outaddr(hw, port, XM_EXM(i), zero);
        !           911: 
        !           912:        /* Clear MIB counters */
        !           913:        xm_write16(hw, port, XM_STAT_CMD,
        !           914:                        XM_SC_CLR_RXC | XM_SC_CLR_TXC);
        !           915:        /* Clear two times according to Errata #3 */
        !           916:        xm_write16(hw, port, XM_STAT_CMD,
        !           917:                        XM_SC_CLR_RXC | XM_SC_CLR_TXC);
        !           918: 
        !           919:        /* configure Rx High Water Mark (XM_RX_HI_WM) */
        !           920:        xm_write16(hw, port, XM_RX_HI_WM, 1450);
        !           921: 
        !           922:        /* We don't need the FCS appended to the packet. */
        !           923:        r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS;
        !           924: 
        !           925:        if (skge->duplex == DUPLEX_HALF) {
        !           926:                /*
        !           927:                 * If in manual half duplex mode the other side might be in
        !           928:                 * full duplex mode, so ignore if a carrier extension is not seen
        !           929:                 * on frames received
        !           930:                 */
        !           931:                r |= XM_RX_DIS_CEXT;
        !           932:        }
        !           933:        xm_write16(hw, port, XM_RX_CMD, r);
        !           934: 
        !           935:        /* We want short frames padded to 60 bytes. */
        !           936:        xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);
        !           937: 
        !           938:        xm_write16(hw, port, XM_TX_THR, 512);
        !           939: 
        !           940:        /*
        !           941:         * Enable the reception of all error frames. This is is
        !           942:         * a necessary evil due to the design of the XMAC. The
        !           943:         * XMAC's receive FIFO is only 8K in size, however jumbo
        !           944:         * frames can be up to 9000 bytes in length. When bad
        !           945:         * frame filtering is enabled, the XMAC's RX FIFO operates
        !           946:         * in 'store and forward' mode. For this to work, the
        !           947:         * entire frame has to fit into the FIFO, but that means
        !           948:         * that jumbo frames larger than 8192 bytes will be
        !           949:         * truncated. Disabling all bad frame filtering causes
        !           950:         * the RX FIFO to operate in streaming mode, in which
        !           951:         * case the XMAC will start transferring frames out of the
        !           952:         * RX FIFO as soon as the FIFO threshold is reached.
        !           953:         */
        !           954:        xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
        !           955: 
        !           956: 
        !           957:        /*
        !           958:         * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
        !           959:         *      - Enable all bits excepting 'Octets Rx OK Low CntOv'
        !           960:         *        and 'Octets Rx OK Hi Cnt Ov'.
        !           961:         */
        !           962:        xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK);
        !           963: 
        !           964:        /*
        !           965:         * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
        !           966:         *      - Enable all bits excepting 'Octets Tx OK Low CntOv'
        !           967:         *        and 'Octets Tx OK Hi Cnt Ov'.
        !           968:         */
        !           969:        xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK);
        !           970: 
        !           971:        /* Configure MAC arbiter */
        !           972:        skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
        !           973: 
        !           974:        /* configure timeout values */
        !           975:        skge_write8(hw, B3_MA_TOINI_RX1, 72);
        !           976:        skge_write8(hw, B3_MA_TOINI_RX2, 72);
        !           977:        skge_write8(hw, B3_MA_TOINI_TX1, 72);
        !           978:        skge_write8(hw, B3_MA_TOINI_TX2, 72);
        !           979: 
        !           980:        skge_write8(hw, B3_MA_RCINI_RX1, 0);
        !           981:        skge_write8(hw, B3_MA_RCINI_RX2, 0);
        !           982:        skge_write8(hw, B3_MA_RCINI_TX1, 0);
        !           983:        skge_write8(hw, B3_MA_RCINI_TX2, 0);
        !           984: 
        !           985:        /* Configure Rx MAC FIFO */
        !           986:        skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
        !           987:        skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
        !           988:        skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
        !           989: 
        !           990:        /* Configure Tx MAC FIFO */
        !           991:        skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
        !           992:        skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
        !           993:        skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
        !           994: 
        !           995:        /* enable timeout timers */
        !           996:        skge_write16(hw, B3_PA_CTRL,
        !           997:                     (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
        !           998: }
        !           999: 
        !          1000: static void genesis_stop(struct skge_port *skge)
        !          1001: {
        !          1002:        struct skge_hw *hw = skge->hw;
        !          1003:        int port = skge->port;
        !          1004:        unsigned retries = 1000;
        !          1005:        u16 cmd;
        !          1006: 
        !          1007:        /* Disable Tx and Rx */
        !          1008:        cmd = xm_read16(hw, port, XM_MMU_CMD);
        !          1009:        cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
        !          1010:        xm_write16(hw, port, XM_MMU_CMD, cmd);
        !          1011: 
        !          1012:        genesis_reset(hw, port);
        !          1013: 
        !          1014:        /* Clear Tx packet arbiter timeout IRQ */
        !          1015:        skge_write16(hw, B3_PA_CTRL,
        !          1016:                     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
        !          1017: 
        !          1018:        /* Reset the MAC */
        !          1019:        skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
        !          1020:        do {
        !          1021:                skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
        !          1022:                if (!(skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST))
        !          1023:                        break;
        !          1024:        } while (--retries > 0);
        !          1025: 
        !          1026:        /* For external PHYs there must be special handling */
        !          1027:        if (hw->phy_type != SK_PHY_XMAC) {
        !          1028:                u32 reg = skge_read32(hw, B2_GP_IO);
        !          1029:                if (port == 0) {
        !          1030:                        reg |= GP_DIR_0;
        !          1031:                        reg &= ~GP_IO_0;
        !          1032:                } else {
        !          1033:                        reg |= GP_DIR_2;
        !          1034:                        reg &= ~GP_IO_2;
        !          1035:                }
        !          1036:                skge_write32(hw, B2_GP_IO, reg);
        !          1037:                skge_read32(hw, B2_GP_IO);
        !          1038:        }
        !          1039: 
        !          1040:        xm_write16(hw, port, XM_MMU_CMD,
        !          1041:                        xm_read16(hw, port, XM_MMU_CMD)
        !          1042:                        & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
        !          1043: 
        !          1044:        xm_read16(hw, port, XM_MMU_CMD);
        !          1045: }
        !          1046: 
        !          1047: static void genesis_link_up(struct skge_port *skge)
        !          1048: {
        !          1049:        struct skge_hw *hw = skge->hw;
        !          1050:        int port = skge->port;
        !          1051:        u16 cmd, msk;
        !          1052:        u32 mode;
        !          1053: 
        !          1054:        cmd = xm_read16(hw, port, XM_MMU_CMD);
        !          1055: 
        !          1056:        /*
        !          1057:         * enabling pause frame reception is required for 1000BT
        !          1058:         * because the XMAC is not reset if the link is going down
        !          1059:         */
        !          1060:        if (skge->flow_status == FLOW_STAT_NONE ||
        !          1061:            skge->flow_status == FLOW_STAT_LOC_SEND)
        !          1062:                /* Disable Pause Frame Reception */
        !          1063:                cmd |= XM_MMU_IGN_PF;
        !          1064:        else
        !          1065:                /* Enable Pause Frame Reception */
        !          1066:                cmd &= ~XM_MMU_IGN_PF;
        !          1067: 
        !          1068:        xm_write16(hw, port, XM_MMU_CMD, cmd);
        !          1069: 
        !          1070:        mode = xm_read32(hw, port, XM_MODE);
        !          1071:        if (skge->flow_status== FLOW_STAT_SYMMETRIC ||
        !          1072:            skge->flow_status == FLOW_STAT_LOC_SEND) {
        !          1073:                /*
        !          1074:                 * Configure Pause Frame Generation
        !          1075:                 * Use internal and external Pause Frame Generation.
        !          1076:                 * Sending pause frames is edge triggered.
        !          1077:                 * Send a Pause frame with the maximum pause time if
        !          1078:                 * internal oder external FIFO full condition occurs.
        !          1079:                 * Send a zero pause time frame to re-start transmission.
        !          1080:                 */
        !          1081:                /* XM_PAUSE_DA = '010000C28001' (default) */
        !          1082:                /* XM_MAC_PTIME = 0xffff (maximum) */
        !          1083:                /* remember this value is defined in big endian (!) */
        !          1084:                xm_write16(hw, port, XM_MAC_PTIME, 0xffff);
        !          1085: 
        !          1086:                mode |= XM_PAUSE_MODE;
        !          1087:                skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
        !          1088:        } else {
        !          1089:                /*
        !          1090:                 * disable pause frame generation is required for 1000BT
        !          1091:                 * because the XMAC is not reset if the link is going down
        !          1092:                 */
        !          1093:                /* Disable Pause Mode in Mode Register */
        !          1094:                mode &= ~XM_PAUSE_MODE;
        !          1095: 
        !          1096:                skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
        !          1097:        }
        !          1098: 
        !          1099:        xm_write32(hw, port, XM_MODE, mode);
        !          1100: 
        !          1101:        /* Turn on detection of Tx underrun */
        !          1102:        msk = xm_read16(hw, port, XM_IMSK);
        !          1103:        msk &= ~XM_IS_TXF_UR;
        !          1104:        xm_write16(hw, port, XM_IMSK, msk);
        !          1105: 
        !          1106:        xm_read16(hw, port, XM_ISRC);
        !          1107: 
        !          1108:        /* get MMU Command Reg. */
        !          1109:        cmd = xm_read16(hw, port, XM_MMU_CMD);
        !          1110:        if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
        !          1111:                cmd |= XM_MMU_GMII_FD;
        !          1112: 
        !          1113:        /*
        !          1114:         * Workaround BCOM Errata (#10523) for all BCom Phys
        !          1115:         * Enable Power Management after link up
        !          1116:         */
        !          1117:        if (hw->phy_type == SK_PHY_BCOM) {
        !          1118:                xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
        !          1119:                             xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
        !          1120:                             & ~PHY_B_AC_DIS_PM);
        !          1121:                xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
        !          1122:        }
        !          1123: 
        !          1124:        /* enable Rx/Tx */
        !          1125:        xm_write16(hw, port, XM_MMU_CMD,
        !          1126:                        cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
        !          1127:        skge_link_up(skge);
        !          1128: }
        !          1129: 
        !          1130: 
        !          1131: static inline void bcom_phy_intr(struct skge_port *skge)
        !          1132: {
        !          1133:        struct skge_hw *hw = skge->hw;
        !          1134:        int port = skge->port;
        !          1135:        u16 isrc;
        !          1136: 
        !          1137:        isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
        !          1138:        DBGIO(PFX "%s: phy interrupt status 0x%x\n",
        !          1139:             skge->netdev->name, isrc);
        !          1140: 
        !          1141:        if (isrc & PHY_B_IS_PSE)
        !          1142:                DBG(PFX "%s: uncorrectable pair swap error\n",
        !          1143:                    hw->dev[port]->name);
        !          1144: 
        !          1145:        /* Workaround BCom Errata:
        !          1146:         *      enable and disable loopback mode if "NO HCD" occurs.
        !          1147:         */
        !          1148:        if (isrc & PHY_B_IS_NO_HDCL) {
        !          1149:                u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL);
        !          1150:                xm_phy_write(hw, port, PHY_BCOM_CTRL,
        !          1151:                                  ctrl | PHY_CT_LOOP);
        !          1152:                xm_phy_write(hw, port, PHY_BCOM_CTRL,
        !          1153:                                  ctrl & ~PHY_CT_LOOP);
        !          1154:        }
        !          1155: 
        !          1156:        if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
        !          1157:                bcom_check_link(hw, port);
        !          1158: 
        !          1159: }
        !          1160: 
        !          1161: static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
        !          1162: {
        !          1163:        int i;
        !          1164: 
        !          1165:        gma_write16(hw, port, GM_SMI_DATA, val);
        !          1166:        gma_write16(hw, port, GM_SMI_CTRL,
        !          1167:                         GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
        !          1168:        for (i = 0; i < PHY_RETRIES; i++) {
        !          1169:                udelay(1);
        !          1170: 
        !          1171:                if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
        !          1172:                        return 0;
        !          1173:        }
        !          1174: 
        !          1175:        DBG(PFX "%s: phy write timeout port %x reg %x val %x\n",
        !          1176:            hw->dev[port]->name,
        !          1177:            port, reg, val);
        !          1178:        return -EIO;
        !          1179: }
        !          1180: 
        !          1181: static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
        !          1182: {
        !          1183:        int i;
        !          1184: 
        !          1185:        gma_write16(hw, port, GM_SMI_CTRL,
        !          1186:                         GM_SMI_CT_PHY_AD(hw->phy_addr)
        !          1187:                         | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
        !          1188: 
        !          1189:        for (i = 0; i < PHY_RETRIES; i++) {
        !          1190:                udelay(1);
        !          1191:                if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
        !          1192:                        goto ready;
        !          1193:        }
        !          1194: 
        !          1195:        return -ETIMEDOUT;
        !          1196:  ready:
        !          1197:        *val = gma_read16(hw, port, GM_SMI_DATA);
        !          1198:        return 0;
        !          1199: }
        !          1200: 
        !          1201: static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
        !          1202: {
        !          1203:        u16 v = 0;
        !          1204:        if (__gm_phy_read(hw, port, reg, &v))
        !          1205:                DBG(PFX "%s: phy read timeout port %x reg %x val %x\n",
        !          1206:               hw->dev[port]->name,
        !          1207:               port, reg, v);
        !          1208:        return v;
        !          1209: }
        !          1210: 
        !          1211: /* Marvell Phy Initialization */
        !          1212: static void yukon_init(struct skge_hw *hw, int port)
        !          1213: {
        !          1214:        struct skge_port *skge = netdev_priv(hw->dev[port]);
        !          1215:        u16 ctrl, ct1000, adv;
        !          1216: 
        !          1217:        if (skge->autoneg == AUTONEG_ENABLE) {
        !          1218:                u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
        !          1219: 
        !          1220:                ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
        !          1221:                          PHY_M_EC_MAC_S_MSK);
        !          1222:                ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
        !          1223: 
        !          1224:                ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
        !          1225: 
        !          1226:                gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
        !          1227:        }
        !          1228: 
        !          1229:        ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
        !          1230:        if (skge->autoneg == AUTONEG_DISABLE)
        !          1231:                ctrl &= ~PHY_CT_ANE;
        !          1232: 
        !          1233:        ctrl |= PHY_CT_RESET;
        !          1234:        gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
        !          1235: 
        !          1236:        ctrl = 0;
        !          1237:        ct1000 = 0;
        !          1238:        adv = PHY_AN_CSMA;
        !          1239: 
        !          1240:        if (skge->autoneg == AUTONEG_ENABLE) {
        !          1241:                if (hw->copper) {
        !          1242:                        if (skge->advertising & ADVERTISED_1000baseT_Full)
        !          1243:                                ct1000 |= PHY_M_1000C_AFD;
        !          1244:                        if (skge->advertising & ADVERTISED_1000baseT_Half)
        !          1245:                                ct1000 |= PHY_M_1000C_AHD;
        !          1246:                        if (skge->advertising & ADVERTISED_100baseT_Full)
        !          1247:                                adv |= PHY_M_AN_100_FD;
        !          1248:                        if (skge->advertising & ADVERTISED_100baseT_Half)
        !          1249:                                adv |= PHY_M_AN_100_HD;
        !          1250:                        if (skge->advertising & ADVERTISED_10baseT_Full)
        !          1251:                                adv |= PHY_M_AN_10_FD;
        !          1252:                        if (skge->advertising & ADVERTISED_10baseT_Half)
        !          1253:                                adv |= PHY_M_AN_10_HD;
        !          1254: 
        !          1255:                        /* Set Flow-control capabilities */
        !          1256:                        adv |= phy_pause_map[skge->flow_control];
        !          1257:                } else {
        !          1258:                        if (skge->advertising & ADVERTISED_1000baseT_Full)
        !          1259:                                adv |= PHY_M_AN_1000X_AFD;
        !          1260:                        if (skge->advertising & ADVERTISED_1000baseT_Half)
        !          1261:                                adv |= PHY_M_AN_1000X_AHD;
        !          1262: 
        !          1263:                        adv |= fiber_pause_map[skge->flow_control];
        !          1264:                }
        !          1265: 
        !          1266:                /* Restart Auto-negotiation */
        !          1267:                ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
        !          1268:        } else {
        !          1269:                /* forced speed/duplex settings */
        !          1270:                ct1000 = PHY_M_1000C_MSE;
        !          1271: 
        !          1272:                if (skge->duplex == DUPLEX_FULL)
        !          1273:                        ctrl |= PHY_CT_DUP_MD;
        !          1274: 
        !          1275:                switch (skge->speed) {
        !          1276:                case SPEED_1000:
        !          1277:                        ctrl |= PHY_CT_SP1000;
        !          1278:                        break;
        !          1279:                case SPEED_100:
        !          1280:                        ctrl |= PHY_CT_SP100;
        !          1281:                        break;
        !          1282:                }
        !          1283: 
        !          1284:                ctrl |= PHY_CT_RESET;
        !          1285:        }
        !          1286: 
        !          1287:        gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
        !          1288: 
        !          1289:        gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
        !          1290:        gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
        !          1291: 
        !          1292:        /* Enable phy interrupt on autonegotiation complete (or link up) */
        !          1293:        if (skge->autoneg == AUTONEG_ENABLE)
        !          1294:                gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK);
        !          1295:        else
        !          1296:                gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK);
        !          1297: }
        !          1298: 
        !          1299: static void yukon_reset(struct skge_hw *hw, int port)
        !          1300: {
        !          1301:        gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
        !          1302:        gma_write16(hw, port, GM_MC_ADDR_H1, 0);        /* clear MC hash */
        !          1303:        gma_write16(hw, port, GM_MC_ADDR_H2, 0);
        !          1304:        gma_write16(hw, port, GM_MC_ADDR_H3, 0);
        !          1305:        gma_write16(hw, port, GM_MC_ADDR_H4, 0);
        !          1306: 
        !          1307:        gma_write16(hw, port, GM_RX_CTRL,
        !          1308:                         gma_read16(hw, port, GM_RX_CTRL)
        !          1309:                         | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
        !          1310: }
        !          1311: 
        !          1312: /* Apparently, early versions of Yukon-Lite had wrong chip_id? */
        !          1313: static int is_yukon_lite_a0(struct skge_hw *hw)
        !          1314: {
        !          1315:        u32 reg;
        !          1316:        int ret;
        !          1317: 
        !          1318:        if (hw->chip_id != CHIP_ID_YUKON)
        !          1319:                return 0;
        !          1320: 
        !          1321:        reg = skge_read32(hw, B2_FAR);
        !          1322:        skge_write8(hw, B2_FAR + 3, 0xff);
        !          1323:        ret = (skge_read8(hw, B2_FAR + 3) != 0);
        !          1324:        skge_write32(hw, B2_FAR, reg);
        !          1325:        return ret;
        !          1326: }
        !          1327: 
        !          1328: static void yukon_mac_init(struct skge_hw *hw, int port)
        !          1329: {
        !          1330:        struct skge_port *skge = netdev_priv(hw->dev[port]);
        !          1331:        int i;
        !          1332:        u32 reg;
        !          1333:        const u8 *addr = hw->dev[port]->ll_addr;
        !          1334: 
        !          1335:        /* WA code for COMA mode -- set PHY reset */
        !          1336:        if (hw->chip_id == CHIP_ID_YUKON_LITE &&
        !          1337:            hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
        !          1338:                reg = skge_read32(hw, B2_GP_IO);
        !          1339:                reg |= GP_DIR_9 | GP_IO_9;
        !          1340:                skge_write32(hw, B2_GP_IO, reg);
        !          1341:        }
        !          1342: 
        !          1343:        /* hard reset */
        !          1344:        skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
        !          1345:        skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
        !          1346: 
        !          1347:        /* WA code for COMA mode -- clear PHY reset */
        !          1348:        if (hw->chip_id == CHIP_ID_YUKON_LITE &&
        !          1349:            hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
        !          1350:                reg = skge_read32(hw, B2_GP_IO);
        !          1351:                reg |= GP_DIR_9;
        !          1352:                reg &= ~GP_IO_9;
        !          1353:                skge_write32(hw, B2_GP_IO, reg);
        !          1354:        }
        !          1355: 
        !          1356:        /* Set hardware config mode */
        !          1357:        reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
        !          1358:                GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE;
        !          1359:        reg |= hw->copper ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB;
        !          1360: 
        !          1361:        /* Clear GMC reset */
        !          1362:        skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
        !          1363:        skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
        !          1364:        skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
        !          1365: 
        !          1366:        if (skge->autoneg == AUTONEG_DISABLE) {
        !          1367:                reg = GM_GPCR_AU_ALL_DIS;
        !          1368:                gma_write16(hw, port, GM_GP_CTRL,
        !          1369:                                 gma_read16(hw, port, GM_GP_CTRL) | reg);
        !          1370: 
        !          1371:                switch (skge->speed) {
        !          1372:                case SPEED_1000:
        !          1373:                        reg &= ~GM_GPCR_SPEED_100;
        !          1374:                        reg |= GM_GPCR_SPEED_1000;
        !          1375:                        break;
        !          1376:                case SPEED_100:
        !          1377:                        reg &= ~GM_GPCR_SPEED_1000;
        !          1378:                        reg |= GM_GPCR_SPEED_100;
        !          1379:                        break;
        !          1380:                case SPEED_10:
        !          1381:                        reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
        !          1382:                        break;
        !          1383:                }
        !          1384: 
        !          1385:                if (skge->duplex == DUPLEX_FULL)
        !          1386:                        reg |= GM_GPCR_DUP_FULL;
        !          1387:        } else
        !          1388:                reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
        !          1389: 
        !          1390:        switch (skge->flow_control) {
        !          1391:        case FLOW_MODE_NONE:
        !          1392:                skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
        !          1393:                reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
        !          1394:                break;
        !          1395:        case FLOW_MODE_LOC_SEND:
        !          1396:                /* disable Rx flow-control */
        !          1397:                reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
        !          1398:                break;
        !          1399:        case FLOW_MODE_SYMMETRIC:
        !          1400:        case FLOW_MODE_SYM_OR_REM:
        !          1401:                /* enable Tx & Rx flow-control */
        !          1402:                break;
        !          1403:        }
        !          1404: 
        !          1405:        gma_write16(hw, port, GM_GP_CTRL, reg);
        !          1406:        skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
        !          1407: 
        !          1408:        yukon_init(hw, port);
        !          1409: 
        !          1410:        /* MIB clear */
        !          1411:        reg = gma_read16(hw, port, GM_PHY_ADDR);
        !          1412:        gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
        !          1413: 
        !          1414:        for (i = 0; i < GM_MIB_CNT_SIZE; i++)
        !          1415:                gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
        !          1416:        gma_write16(hw, port, GM_PHY_ADDR, reg);
        !          1417: 
        !          1418:        /* transmit control */
        !          1419:        gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
        !          1420: 
        !          1421:        /* receive control reg: unicast + multicast + no FCS  */
        !          1422:        gma_write16(hw, port, GM_RX_CTRL,
        !          1423:                         GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
        !          1424: 
        !          1425:        /* transmit flow control */
        !          1426:        gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
        !          1427: 
        !          1428:        /* transmit parameter */
        !          1429:        gma_write16(hw, port, GM_TX_PARAM,
        !          1430:                         TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
        !          1431:                         TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
        !          1432:                         TX_IPG_JAM_DATA(TX_IPG_JAM_DEF));
        !          1433: 
        !          1434:        /* configure the Serial Mode Register */
        !          1435:        reg = DATA_BLIND_VAL(DATA_BLIND_DEF)
        !          1436:                | GM_SMOD_VLAN_ENA
        !          1437:                | IPG_DATA_VAL(IPG_DATA_DEF);
        !          1438: 
        !          1439:        gma_write16(hw, port, GM_SERIAL_MODE, reg);
        !          1440: 
        !          1441:        /* physical address: used for pause frames */
        !          1442:        gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
        !          1443:        /* virtual address for data */
        !          1444:        gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
        !          1445: 
        !          1446:        /* enable interrupt mask for counter overflows */
        !          1447:        gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
        !          1448:        gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
        !          1449:        gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
        !          1450: 
        !          1451:        /* Initialize Mac Fifo */
        !          1452: 
        !          1453:        /* Configure Rx MAC FIFO */
        !          1454:        skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
        !          1455:        reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
        !          1456: 
        !          1457:        /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
        !          1458:        if (is_yukon_lite_a0(hw))
        !          1459:                reg &= ~GMF_RX_F_FL_ON;
        !          1460: 
        !          1461:        skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
        !          1462:        skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
        !          1463:        /*
        !          1464:         * because Pause Packet Truncation in GMAC is not working
        !          1465:         * we have to increase the Flush Threshold to 64 bytes
        !          1466:         * in order to flush pause packets in Rx FIFO on Yukon-1
        !          1467:         */
        !          1468:        skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1);
        !          1469: 
        !          1470:        /* Configure Tx MAC FIFO */
        !          1471:        skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
        !          1472:        skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
        !          1473: }
        !          1474: 
        !          1475: /* Go into power down mode */
        !          1476: static void yukon_suspend(struct skge_hw *hw, int port)
        !          1477: {
        !          1478:        u16 ctrl;
        !          1479: 
        !          1480:        ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
        !          1481:        ctrl |= PHY_M_PC_POL_R_DIS;
        !          1482:        gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
        !          1483: 
        !          1484:        ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
        !          1485:        ctrl |= PHY_CT_RESET;
        !          1486:        gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
        !          1487: 
        !          1488:        /* switch IEEE compatible power down mode on */
        !          1489:        ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
        !          1490:        ctrl |= PHY_CT_PDOWN;
        !          1491:        gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
        !          1492: }
        !          1493: 
        !          1494: static void yukon_stop(struct skge_port *skge)
        !          1495: {
        !          1496:        struct skge_hw *hw = skge->hw;
        !          1497:        int port = skge->port;
        !          1498: 
        !          1499:        skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
        !          1500:        yukon_reset(hw, port);
        !          1501: 
        !          1502:        gma_write16(hw, port, GM_GP_CTRL,
        !          1503:                         gma_read16(hw, port, GM_GP_CTRL)
        !          1504:                         & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
        !          1505:        gma_read16(hw, port, GM_GP_CTRL);
        !          1506: 
        !          1507:        yukon_suspend(hw, port);
        !          1508: 
        !          1509:        /* set GPHY Control reset */
        !          1510:        skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
        !          1511:        skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
        !          1512: }
        !          1513: 
        !          1514: static u16 yukon_speed(const struct skge_hw *hw __unused, u16 aux)
        !          1515: {
        !          1516:        switch (aux & PHY_M_PS_SPEED_MSK) {
        !          1517:        case PHY_M_PS_SPEED_1000:
        !          1518:                return SPEED_1000;
        !          1519:        case PHY_M_PS_SPEED_100:
        !          1520:                return SPEED_100;
        !          1521:        default:
        !          1522:                return SPEED_10;
        !          1523:        }
        !          1524: }
        !          1525: 
        !          1526: static void yukon_link_up(struct skge_port *skge)
        !          1527: {
        !          1528:        struct skge_hw *hw = skge->hw;
        !          1529:        int port = skge->port;
        !          1530:        u16 reg;
        !          1531: 
        !          1532:        /* Enable Transmit FIFO Underrun */
        !          1533:        skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
        !          1534: 
        !          1535:        reg = gma_read16(hw, port, GM_GP_CTRL);
        !          1536:        if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
        !          1537:                reg |= GM_GPCR_DUP_FULL;
        !          1538: 
        !          1539:        /* enable Rx/Tx */
        !          1540:        reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
        !          1541:        gma_write16(hw, port, GM_GP_CTRL, reg);
        !          1542: 
        !          1543:        gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK);
        !          1544:        skge_link_up(skge);
        !          1545: }
        !          1546: 
        !          1547: static void yukon_link_down(struct skge_port *skge)
        !          1548: {
        !          1549:        struct skge_hw *hw = skge->hw;
        !          1550:        int port = skge->port;
        !          1551:        u16 ctrl;
        !          1552: 
        !          1553:        ctrl = gma_read16(hw, port, GM_GP_CTRL);
        !          1554:        ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
        !          1555:        gma_write16(hw, port, GM_GP_CTRL, ctrl);
        !          1556: 
        !          1557:        if (skge->flow_status == FLOW_STAT_REM_SEND) {
        !          1558:                ctrl = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
        !          1559:                ctrl |= PHY_M_AN_ASP;
        !          1560:                /* restore Asymmetric Pause bit */
        !          1561:                gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, ctrl);
        !          1562:        }
        !          1563: 
        !          1564:        skge_link_down(skge);
        !          1565: 
        !          1566:        yukon_init(hw, port);
        !          1567: }
        !          1568: 
        !          1569: static void yukon_phy_intr(struct skge_port *skge)
        !          1570: {
        !          1571:        struct skge_hw *hw = skge->hw;
        !          1572:        int port = skge->port;
        !          1573:        const char *reason = NULL;
        !          1574:        u16 istatus, phystat;
        !          1575: 
        !          1576:        istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
        !          1577:        phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
        !          1578: 
        !          1579:        DBGIO(PFX "%s: phy interrupt status 0x%x 0x%x\n",
        !          1580:             skge->netdev->name, istatus, phystat);
        !          1581: 
        !          1582:        if (istatus & PHY_M_IS_AN_COMPL) {
        !          1583:                if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
        !          1584:                    & PHY_M_AN_RF) {
        !          1585:                        reason = "remote fault";
        !          1586:                        goto failed;
        !          1587:                }
        !          1588: 
        !          1589:                if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
        !          1590:                        reason = "master/slave fault";
        !          1591:                        goto failed;
        !          1592:                }
        !          1593: 
        !          1594:                if (!(phystat & PHY_M_PS_SPDUP_RES)) {
        !          1595:                        reason = "speed/duplex";
        !          1596:                        goto failed;
        !          1597:                }
        !          1598: 
        !          1599:                skge->duplex = (phystat & PHY_M_PS_FULL_DUP)
        !          1600:                        ? DUPLEX_FULL : DUPLEX_HALF;
        !          1601:                skge->speed = yukon_speed(hw, phystat);
        !          1602: 
        !          1603:                /* We are using IEEE 802.3z/D5.0 Table 37-4 */
        !          1604:                switch (phystat & PHY_M_PS_PAUSE_MSK) {
        !          1605:                case PHY_M_PS_PAUSE_MSK:
        !          1606:                        skge->flow_status = FLOW_STAT_SYMMETRIC;
        !          1607:                        break;
        !          1608:                case PHY_M_PS_RX_P_EN:
        !          1609:                        skge->flow_status = FLOW_STAT_REM_SEND;
        !          1610:                        break;
        !          1611:                case PHY_M_PS_TX_P_EN:
        !          1612:                        skge->flow_status = FLOW_STAT_LOC_SEND;
        !          1613:                        break;
        !          1614:                default:
        !          1615:                        skge->flow_status = FLOW_STAT_NONE;
        !          1616:                }
        !          1617: 
        !          1618:                if (skge->flow_status == FLOW_STAT_NONE ||
        !          1619:                    (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF))
        !          1620:                        skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
        !          1621:                else
        !          1622:                        skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
        !          1623:                yukon_link_up(skge);
        !          1624:                return;
        !          1625:        }
        !          1626: 
        !          1627:        if (istatus & PHY_M_IS_LSP_CHANGE)
        !          1628:                skge->speed = yukon_speed(hw, phystat);
        !          1629: 
        !          1630:        if (istatus & PHY_M_IS_DUP_CHANGE)
        !          1631:                skge->duplex = (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
        !          1632:        if (istatus & PHY_M_IS_LST_CHANGE) {
        !          1633:                if (phystat & PHY_M_PS_LINK_UP)
        !          1634:                        yukon_link_up(skge);
        !          1635:                else
        !          1636:                        yukon_link_down(skge);
        !          1637:        }
        !          1638:        return;
        !          1639:  failed:
        !          1640:        DBG(PFX "%s: autonegotiation failed (%s)\n",
        !          1641:               skge->netdev->name, reason);
        !          1642: 
        !          1643:        /* XXX restart autonegotiation? */
        !          1644: }
        !          1645: 
        !          1646: static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
        !          1647: {
        !          1648:        u32 end;
        !          1649: 
        !          1650:        start /= 8;
        !          1651:        len /= 8;
        !          1652:        end = start + len - 1;
        !          1653: 
        !          1654:        skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
        !          1655:        skge_write32(hw, RB_ADDR(q, RB_START), start);
        !          1656:        skge_write32(hw, RB_ADDR(q, RB_WP), start);
        !          1657:        skge_write32(hw, RB_ADDR(q, RB_RP), start);
        !          1658:        skge_write32(hw, RB_ADDR(q, RB_END), end);
        !          1659: 
        !          1660:        if (q == Q_R1 || q == Q_R2) {
        !          1661:                /* Set thresholds on receive queue's */
        !          1662:                skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
        !          1663:                             start + (2*len)/3);
        !          1664:                skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
        !          1665:                             start + (len/3));
        !          1666:        } else {
        !          1667:                /* Enable store & forward on Tx queue's because
        !          1668:                 * Tx FIFO is only 4K on Genesis and 1K on Yukon
        !          1669:                 */
        !          1670:                skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
        !          1671:        }
        !          1672: 
        !          1673:        skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
        !          1674: }
        !          1675: 
        !          1676: /* Setup Bus Memory Interface */
        !          1677: static void skge_qset(struct skge_port *skge, u16 q,
        !          1678:                      const struct skge_element *e)
        !          1679: {
        !          1680:        struct skge_hw *hw = skge->hw;
        !          1681:        u32 watermark = 0x600;
        !          1682:        u64 base = skge->dma + (e->desc - skge->mem);
        !          1683: 
        !          1684:        /* optimization to reduce window on 32bit/33mhz */
        !          1685:        if ((skge_read16(hw, B0_CTST) & (CS_BUS_CLOCK | CS_BUS_SLOT_SZ)) == 0)
        !          1686:                watermark /= 2;
        !          1687: 
        !          1688:        skge_write32(hw, Q_ADDR(q, Q_CSR), CSR_CLR_RESET);
        !          1689:        skge_write32(hw, Q_ADDR(q, Q_F), watermark);
        !          1690:        skge_write32(hw, Q_ADDR(q, Q_DA_H), (u32)(base >> 32));
        !          1691:        skge_write32(hw, Q_ADDR(q, Q_DA_L), (u32)base);
        !          1692: }
        !          1693: 
        !          1694: void skge_free(struct net_device *dev)
        !          1695: {
        !          1696:        struct skge_port *skge = netdev_priv(dev);
        !          1697: 
        !          1698:        free(skge->rx_ring.start);
        !          1699:        skge->rx_ring.start = NULL;
        !          1700: 
        !          1701:        free(skge->tx_ring.start);
        !          1702:        skge->tx_ring.start = NULL;
        !          1703: 
        !          1704:        free_dma(skge->mem, RING_SIZE);
        !          1705:        skge->mem = NULL;
        !          1706:        skge->dma = 0;
        !          1707: }
        !          1708: 
        !          1709: static int skge_up(struct net_device *dev)
        !          1710: {
        !          1711:        struct skge_port *skge = netdev_priv(dev);
        !          1712:        struct skge_hw *hw = skge->hw;
        !          1713:        int port = skge->port;
        !          1714:        u32 chunk, ram_addr;
        !          1715:        int err;
        !          1716: 
        !          1717:        DBG2(PFX "%s: enabling interface\n", dev->name);
        !          1718: 
        !          1719:        skge->mem = malloc_dma(RING_SIZE, SKGE_RING_ALIGN);
        !          1720:        skge->dma = virt_to_bus(skge->mem);
        !          1721:        if (!skge->mem)
        !          1722:                return -ENOMEM;
        !          1723:        memset(skge->mem, 0, RING_SIZE);
        !          1724: 
        !          1725:        assert(!(skge->dma & 7));
        !          1726: 
        !          1727:        /* FIXME: find out whether 64 bit iPXE will be loaded > 4GB */
        !          1728:        if ((u64)skge->dma >> 32 != ((u64) skge->dma + RING_SIZE) >> 32) {
        !          1729:                DBG(PFX "pci_alloc_consistent region crosses 4G boundary\n");
        !          1730:                err = -EINVAL;
        !          1731:                goto err;
        !          1732:        }
        !          1733: 
        !          1734:        err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma, NUM_RX_DESC);
        !          1735:        if (err)
        !          1736:                goto err;
        !          1737: 
        !          1738:        /* this call relies on e->iob and d->control to be 0
        !          1739:         * This is assured by calling memset() on skge->mem and using zalloc()
        !          1740:         * for the skge_element structures.
        !          1741:         */
        !          1742:        skge_rx_refill(dev);
        !          1743: 
        !          1744:        err = skge_ring_alloc(&skge->tx_ring, skge->mem + RX_RING_SIZE,
        !          1745:                              skge->dma + RX_RING_SIZE, NUM_TX_DESC);
        !          1746:        if (err)
        !          1747:                goto err;
        !          1748: 
        !          1749:        /* Initialize MAC */
        !          1750:        if (hw->chip_id == CHIP_ID_GENESIS)
        !          1751:                genesis_mac_init(hw, port);
        !          1752:        else
        !          1753:                yukon_mac_init(hw, port);
        !          1754: 
        !          1755:        /* Configure RAMbuffers - equally between ports and tx/rx */
        !          1756:        chunk = (hw->ram_size  - hw->ram_offset) / (hw->ports * 2);
        !          1757:        ram_addr = hw->ram_offset + 2 * chunk * port;
        !          1758: 
        !          1759:        skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
        !          1760:        skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
        !          1761: 
        !          1762:        assert(!(skge->tx_ring.to_use != skge->tx_ring.to_clean));
        !          1763:        skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
        !          1764:        skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
        !          1765: 
        !          1766:        /* Start receiver BMU */
        !          1767:        wmb();
        !          1768:        skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
        !          1769:        skge_led(skge, LED_MODE_ON);
        !          1770: 
        !          1771:        hw->intr_mask |= portmask[port];
        !          1772:        skge_write32(hw, B0_IMSK, hw->intr_mask);
        !          1773: 
        !          1774:        return 0;
        !          1775: 
        !          1776:  err:
        !          1777:        skge_rx_clean(skge);
        !          1778:        skge_free(dev);
        !          1779: 
        !          1780:        return err;
        !          1781: }
        !          1782: 
        !          1783: /* stop receiver */
        !          1784: static void skge_rx_stop(struct skge_hw *hw, int port)
        !          1785: {
        !          1786:        skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP);
        !          1787:        skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
        !          1788:                     RB_RST_SET|RB_DIS_OP_MD);
        !          1789:        skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
        !          1790: }
        !          1791: 
        !          1792: static void skge_down(struct net_device *dev)
        !          1793: {
        !          1794:        struct skge_port *skge = netdev_priv(dev);
        !          1795:        struct skge_hw *hw = skge->hw;
        !          1796:        int port = skge->port;
        !          1797: 
        !          1798:        if (skge->mem == NULL)
        !          1799:                return;
        !          1800: 
        !          1801:        DBG2(PFX "%s: disabling interface\n", dev->name);
        !          1802: 
        !          1803:        if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
        !          1804:                skge->use_xm_link_timer = 0;
        !          1805: 
        !          1806:        netdev_link_down(dev);
        !          1807: 
        !          1808:        hw->intr_mask &= ~portmask[port];
        !          1809:        skge_write32(hw, B0_IMSK, hw->intr_mask);
        !          1810: 
        !          1811:        skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
        !          1812:        if (hw->chip_id == CHIP_ID_GENESIS)
        !          1813:                genesis_stop(skge);
        !          1814:        else
        !          1815:                yukon_stop(skge);
        !          1816: 
        !          1817:        /* Stop transmitter */
        !          1818:        skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
        !          1819:        skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
        !          1820:                     RB_RST_SET|RB_DIS_OP_MD);
        !          1821: 
        !          1822: 
        !          1823:        /* Disable Force Sync bit and Enable Alloc bit */
        !          1824:        skge_write8(hw, SK_REG(port, TXA_CTRL),
        !          1825:                    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
        !          1826: 
        !          1827:        /* Stop Interval Timer and Limit Counter of Tx Arbiter */
        !          1828:        skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
        !          1829:        skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
        !          1830: 
        !          1831:        /* Reset PCI FIFO */
        !          1832:        skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET);
        !          1833:        skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
        !          1834: 
        !          1835:        /* Reset the RAM Buffer async Tx queue */
        !          1836:        skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET);
        !          1837: 
        !          1838:        skge_rx_stop(hw, port);
        !          1839: 
        !          1840:        if (hw->chip_id == CHIP_ID_GENESIS) {
        !          1841:                skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
        !          1842:                skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
        !          1843:        } else {
        !          1844:                skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
        !          1845:                skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
        !          1846:        }
        !          1847: 
        !          1848:        skge_led(skge, LED_MODE_OFF);
        !          1849: 
        !          1850:        skge_tx_clean(dev);
        !          1851: 
        !          1852:        skge_rx_clean(skge);
        !          1853: 
        !          1854:        skge_free(dev);
        !          1855:        return;
        !          1856: }
        !          1857: 
        !          1858: static inline int skge_tx_avail(const struct skge_ring *ring)
        !          1859: {
        !          1860:        mb();
        !          1861:        return ((ring->to_clean > ring->to_use) ? 0 : NUM_TX_DESC)
        !          1862:                + (ring->to_clean - ring->to_use) - 1;
        !          1863: }
        !          1864: 
        !          1865: static int skge_xmit_frame(struct net_device *dev, struct io_buffer *iob)
        !          1866: {
        !          1867:        struct skge_port *skge = netdev_priv(dev);
        !          1868:        struct skge_hw *hw = skge->hw;
        !          1869:        struct skge_element *e;
        !          1870:        struct skge_tx_desc *td;
        !          1871:        u32 control, len;
        !          1872:        u64 map;
        !          1873: 
        !          1874:        if (skge_tx_avail(&skge->tx_ring) < 1)
        !          1875:                return -EBUSY;
        !          1876: 
        !          1877:        e = skge->tx_ring.to_use;
        !          1878:        td = e->desc;
        !          1879:        assert(!(td->control & BMU_OWN));
        !          1880:        e->iob = iob;
        !          1881:        len = iob_len(iob);
        !          1882:        map = virt_to_bus(iob->data);
        !          1883: 
        !          1884:        td->dma_lo = map;
        !          1885:        td->dma_hi = map >> 32;
        !          1886: 
        !          1887:        control = BMU_CHECK;
        !          1888: 
        !          1889:        control |= BMU_EOF| BMU_IRQ_EOF;
        !          1890:        /* Make sure all the descriptors written */
        !          1891:        wmb();
        !          1892:        td->control = BMU_OWN | BMU_SW | BMU_STF | control | len;
        !          1893:        wmb();
        !          1894: 
        !          1895:        skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START);
        !          1896: 
        !          1897:        DBGIO(PFX "%s: tx queued, slot %td, len %d\n",
        !          1898:             dev->name, e - skge->tx_ring.start, (unsigned int)len);
        !          1899: 
        !          1900:        skge->tx_ring.to_use = e->next;
        !          1901:        wmb();
        !          1902: 
        !          1903:        if (skge_tx_avail(&skge->tx_ring) <= 1) {
        !          1904:                DBG(PFX "%s: transmit queue full\n", dev->name);
        !          1905:        }
        !          1906: 
        !          1907:        return 0;
        !          1908: }
        !          1909: 
        !          1910: /* Free all buffers in transmit ring */
        !          1911: static void skge_tx_clean(struct net_device *dev)
        !          1912: {
        !          1913:        struct skge_port *skge = netdev_priv(dev);
        !          1914:        struct skge_element *e;
        !          1915: 
        !          1916:        for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
        !          1917:                struct skge_tx_desc *td = e->desc;
        !          1918:                td->control = 0;
        !          1919:        }
        !          1920: 
        !          1921:        skge->tx_ring.to_clean = e;
        !          1922: }
        !          1923: 
        !          1924: static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };
        !          1925: 
        !          1926: static inline u16 phy_length(const struct skge_hw *hw, u32 status)
        !          1927: {
        !          1928:        if (hw->chip_id == CHIP_ID_GENESIS)
        !          1929:                return status >> XMR_FS_LEN_SHIFT;
        !          1930:        else
        !          1931:                return status >> GMR_FS_LEN_SHIFT;
        !          1932: }
        !          1933: 
        !          1934: static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
        !          1935: {
        !          1936:        if (hw->chip_id == CHIP_ID_GENESIS)
        !          1937:                return (status & (XMR_FS_ERR | XMR_FS_2L_VLAN)) != 0;
        !          1938:        else
        !          1939:                return (status & GMR_FS_ANY_ERR) ||
        !          1940:                        (status & GMR_FS_RX_OK) == 0;
        !          1941: }
        !          1942: 
        !          1943: /* Free all buffers in Tx ring which are no longer owned by device */
        !          1944: static void skge_tx_done(struct net_device *dev)
        !          1945: {
        !          1946:        struct skge_port *skge = netdev_priv(dev);
        !          1947:        struct skge_ring *ring = &skge->tx_ring;
        !          1948:        struct skge_element *e;
        !          1949: 
        !          1950:        skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);
        !          1951: 
        !          1952:        for (e = ring->to_clean; e != ring->to_use; e = e->next) {
        !          1953:                u32 control = ((const struct skge_tx_desc *) e->desc)->control;
        !          1954: 
        !          1955:                if (control & BMU_OWN)
        !          1956:                        break;
        !          1957: 
        !          1958:                netdev_tx_complete(dev, e->iob);
        !          1959:        }
        !          1960:        skge->tx_ring.to_clean = e;
        !          1961: 
        !          1962:        /* Can run lockless until we need to synchronize to restart queue. */
        !          1963:        mb();
        !          1964: }
        !          1965: 
        !          1966: static void skge_rx_refill(struct net_device *dev)
        !          1967: {
        !          1968:        struct skge_port *skge = netdev_priv(dev);
        !          1969:        struct skge_ring *ring = &skge->rx_ring;
        !          1970:        struct skge_element *e;
        !          1971:        struct io_buffer *iob;
        !          1972:        struct skge_rx_desc *rd;
        !          1973:        u32 control;
        !          1974:        int i;
        !          1975: 
        !          1976:        for (i = 0; i < NUM_RX_DESC; i++) {
        !          1977:                e = ring->to_clean;
        !          1978:                rd = e->desc;
        !          1979:                iob = e->iob;
        !          1980:                control = rd->control;
        !          1981: 
        !          1982:                /* nothing to do here */
        !          1983:                if (iob || (control & BMU_OWN))
        !          1984:                        continue;
        !          1985: 
        !          1986:                DBG2("refilling rx desc %zd: ", (ring->to_clean - ring->start));
        !          1987: 
        !          1988:                iob = alloc_iob(RX_BUF_SIZE);
        !          1989:                if (iob) {
        !          1990:                        skge_rx_setup(skge, e, iob, RX_BUF_SIZE);
        !          1991:                } else {
        !          1992:                        DBG("descr %zd: alloc_iob() failed\n",
        !          1993:                             (ring->to_clean - ring->start));
        !          1994:                        /* We pass the descriptor to the NIC even if the
        !          1995:                         * allocation failed. The card will stop as soon as it
        !          1996:                         * encounters a descriptor with the OWN bit set to 0,
        !          1997:                         * thus never getting to the next descriptor that might
        !          1998:                         * contain a valid io_buffer. This would effectively
        !          1999:                         * stall the receive.
        !          2000:                         */
        !          2001:                        skge_rx_setup(skge, e, NULL, 0);
        !          2002:                }
        !          2003: 
        !          2004:                ring->to_clean = e->next;
        !          2005:        }
        !          2006: }
        !          2007: 
        !          2008: static void skge_rx_done(struct net_device *dev)
        !          2009: {
        !          2010:        struct skge_port *skge = netdev_priv(dev);
        !          2011:        struct skge_ring *ring = &skge->rx_ring;
        !          2012:        struct skge_rx_desc *rd;
        !          2013:        struct skge_element *e;
        !          2014:        struct io_buffer *iob;
        !          2015:        u32 control;
        !          2016:        u16 len;
        !          2017:        int i;
        !          2018: 
        !          2019:        e = ring->to_clean;
        !          2020:        for (i = 0; i < NUM_RX_DESC; i++) {
        !          2021:                iob = e->iob;
        !          2022:                rd = e->desc;
        !          2023: 
        !          2024:                rmb();
        !          2025:                control = rd->control;
        !          2026: 
        !          2027:                if ((control & BMU_OWN))
        !          2028:                        break;
        !          2029: 
        !          2030:                if (!iob)
        !          2031:                        continue;
        !          2032: 
        !          2033:                len = control & BMU_BBC;
        !          2034: 
        !          2035:                /* catch RX errors */
        !          2036:                if ((bad_phy_status(skge->hw, rd->status)) ||
        !          2037:                   (phy_length(skge->hw, rd->status) != len)) {
        !          2038:                        /* report receive errors */
        !          2039:                        DBG("rx error\n");
        !          2040:                        netdev_rx_err(dev, iob, -EIO);
        !          2041:                } else {
        !          2042:                        DBG2("received packet, len %d\n", len);
        !          2043:                        iob_put(iob, len);
        !          2044:                        netdev_rx(dev, iob);
        !          2045:                }
        !          2046: 
        !          2047:                /* io_buffer passed to core, make sure we don't reuse it */
        !          2048:                e->iob = NULL;
        !          2049: 
        !          2050:                e = e->next;
        !          2051:        }
        !          2052:        skge_rx_refill(dev);
        !          2053: }
        !          2054: 
        !          2055: static void skge_poll(struct net_device *dev)
        !          2056: {
        !          2057:        struct skge_port *skge = netdev_priv(dev);
        !          2058:        struct skge_hw *hw = skge->hw;
        !          2059:        u32 status;
        !          2060: 
        !          2061:        /* reading this register ACKs interrupts */
        !          2062:        status = skge_read32(hw, B0_SP_ISRC);
        !          2063: 
        !          2064:        /* Link event? */
        !          2065:        if (status & IS_EXT_REG) {
        !          2066:                skge_phyirq(hw);
        !          2067:                if (skge->use_xm_link_timer)
        !          2068:                        xm_link_timer(skge);
        !          2069:        }
        !          2070: 
        !          2071:        skge_tx_done(dev);
        !          2072: 
        !          2073:        skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);
        !          2074: 
        !          2075:        skge_rx_done(dev);
        !          2076: 
        !          2077:        /* restart receiver */
        !          2078:        wmb();
        !          2079:        skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START);
        !          2080: 
        !          2081:        skge_read32(hw, B0_IMSK);
        !          2082: 
        !          2083:        return;
        !          2084: }
        !          2085: 
        !          2086: static void skge_phyirq(struct skge_hw *hw)
        !          2087: {
        !          2088:        int port;
        !          2089: 
        !          2090:        for (port = 0; port < hw->ports; port++) {
        !          2091:                struct net_device *dev = hw->dev[port];
        !          2092:                struct skge_port *skge = netdev_priv(dev);
        !          2093: 
        !          2094:                if (hw->chip_id != CHIP_ID_GENESIS)
        !          2095:                        yukon_phy_intr(skge);
        !          2096:                else if (hw->phy_type == SK_PHY_BCOM)
        !          2097:                        bcom_phy_intr(skge);
        !          2098:        }
        !          2099: 
        !          2100:        hw->intr_mask |= IS_EXT_REG;
        !          2101:        skge_write32(hw, B0_IMSK, hw->intr_mask);
        !          2102:        skge_read32(hw, B0_IMSK);
        !          2103: }
        !          2104: 
        !          2105: static const struct {
        !          2106:        u8 id;
        !          2107:        const char *name;
        !          2108: } skge_chips[] = {
        !          2109:        { CHIP_ID_GENESIS,      "Genesis" },
        !          2110:        { CHIP_ID_YUKON,         "Yukon" },
        !          2111:        { CHIP_ID_YUKON_LITE,    "Yukon-Lite"},
        !          2112:        { CHIP_ID_YUKON_LP,      "Yukon-LP"},
        !          2113: };
        !          2114: 
        !          2115: static const char *skge_board_name(const struct skge_hw *hw)
        !          2116: {
        !          2117:        unsigned int i;
        !          2118:        static char buf[16];
        !          2119: 
        !          2120:        for (i = 0; i < ARRAY_SIZE(skge_chips); i++)
        !          2121:                if (skge_chips[i].id == hw->chip_id)
        !          2122:                        return skge_chips[i].name;
        !          2123: 
        !          2124:        snprintf(buf, sizeof buf, "chipid 0x%x", hw->chip_id);
        !          2125:        return buf;
        !          2126: }
        !          2127: 
        !          2128: 
        !          2129: /*
        !          2130:  * Setup the board data structure, but don't bring up
        !          2131:  * the port(s)
        !          2132:  */
        !          2133: static int skge_reset(struct skge_hw *hw)
        !          2134: {
        !          2135:        u32 reg;
        !          2136:        u16 ctst, pci_status;
        !          2137:        u8 t8, mac_cfg, pmd_type;
        !          2138:        int i;
        !          2139: 
        !          2140:        ctst = skge_read16(hw, B0_CTST);
        !          2141: 
        !          2142:        /* do a SW reset */
        !          2143:        skge_write8(hw, B0_CTST, CS_RST_SET);
        !          2144:        skge_write8(hw, B0_CTST, CS_RST_CLR);
        !          2145: 
        !          2146:        /* clear PCI errors, if any */
        !          2147:        skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
        !          2148:        skge_write8(hw, B2_TST_CTRL2, 0);
        !          2149: 
        !          2150:        pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status);
        !          2151:        pci_write_config_word(hw->pdev, PCI_STATUS,
        !          2152:                              pci_status | PCI_STATUS_ERROR_BITS);
        !          2153:        skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        !          2154:        skge_write8(hw, B0_CTST, CS_MRST_CLR);
        !          2155: 
        !          2156:        /* restore CLK_RUN bits (for Yukon-Lite) */
        !          2157:        skge_write16(hw, B0_CTST,
        !          2158:                     ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA));
        !          2159: 
        !          2160:        hw->chip_id = skge_read8(hw, B2_CHIP_ID);
        !          2161:        hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
        !          2162:        pmd_type = skge_read8(hw, B2_PMD_TYP);
        !          2163:        hw->copper = (pmd_type == 'T' || pmd_type == '1');
        !          2164: 
        !          2165:        switch (hw->chip_id) {
        !          2166:        case CHIP_ID_GENESIS:
        !          2167:                switch (hw->phy_type) {
        !          2168:                case SK_PHY_XMAC:
        !          2169:                        hw->phy_addr = PHY_ADDR_XMAC;
        !          2170:                        break;
        !          2171:                case SK_PHY_BCOM:
        !          2172:                        hw->phy_addr = PHY_ADDR_BCOM;
        !          2173:                        break;
        !          2174:                default:
        !          2175:                        DBG(PFX "unsupported phy type 0x%x\n",
        !          2176:                               hw->phy_type);
        !          2177:                        return -EOPNOTSUPP;
        !          2178:                }
        !          2179:                break;
        !          2180: 
        !          2181:        case CHIP_ID_YUKON:
        !          2182:        case CHIP_ID_YUKON_LITE:
        !          2183:        case CHIP_ID_YUKON_LP:
        !          2184:                if (hw->phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S')
        !          2185:                        hw->copper = 1;
        !          2186: 
        !          2187:                hw->phy_addr = PHY_ADDR_MARV;
        !          2188:                break;
        !          2189: 
        !          2190:        default:
        !          2191:                DBG(PFX "unsupported chip type 0x%x\n",
        !          2192:                       hw->chip_id);
        !          2193:                return -EOPNOTSUPP;
        !          2194:        }
        !          2195: 
        !          2196:        mac_cfg = skge_read8(hw, B2_MAC_CFG);
        !          2197:        hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2;
        !          2198:        hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4;
        !          2199: 
        !          2200:        /* read the adapters RAM size */
        !          2201:        t8 = skge_read8(hw, B2_E_0);
        !          2202:        if (hw->chip_id == CHIP_ID_GENESIS) {
        !          2203:                if (t8 == 3) {
        !          2204:                        /* special case: 4 x 64k x 36, offset = 0x80000 */
        !          2205:                        hw->ram_size = 0x100000;
        !          2206:                        hw->ram_offset = 0x80000;
        !          2207:                } else
        !          2208:                        hw->ram_size = t8 * 512;
        !          2209:        }
        !          2210:        else if (t8 == 0)
        !          2211:                hw->ram_size = 0x20000;
        !          2212:        else
        !          2213:                hw->ram_size = t8 * 4096;
        !          2214: 
        !          2215:        hw->intr_mask = IS_HW_ERR;
        !          2216: 
        !          2217:        /* Use PHY IRQ for all but fiber based Genesis board */
        !          2218:        if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC))
        !          2219:                hw->intr_mask |= IS_EXT_REG;
        !          2220: 
        !          2221:        if (hw->chip_id == CHIP_ID_GENESIS)
        !          2222:                genesis_init(hw);
        !          2223:        else {
        !          2224:                /* switch power to VCC (WA for VAUX problem) */
        !          2225:                skge_write8(hw, B0_POWER_CTRL,
        !          2226:                            PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
        !          2227: 
        !          2228:                /* avoid boards with stuck Hardware error bits */
        !          2229:                if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
        !          2230:                    (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
        !          2231:                        DBG(PFX "stuck hardware sensor bit\n");
        !          2232:                        hw->intr_mask &= ~IS_HW_ERR;
        !          2233:                }
        !          2234: 
        !          2235:                /* Clear PHY COMA */
        !          2236:                skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
        !          2237:                pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
        !          2238:                reg &= ~PCI_PHY_COMA;
        !          2239:                pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
        !          2240:                skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        !          2241: 
        !          2242: 
        !          2243:                for (i = 0; i < hw->ports; i++) {
        !          2244:                        skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
        !          2245:                        skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
        !          2246:                }
        !          2247:        }
        !          2248: 
        !          2249:        /* turn off hardware timer (unused) */
        !          2250:        skge_write8(hw, B2_TI_CTRL, TIM_STOP);
        !          2251:        skge_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
        !          2252:        skge_write8(hw, B0_LED, LED_STAT_ON);
        !          2253: 
        !          2254:        /* enable the Tx Arbiters */
        !          2255:        for (i = 0; i < hw->ports; i++)
        !          2256:                skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
        !          2257: 
        !          2258:        /* Initialize ram interface */
        !          2259:        skge_write16(hw, B3_RI_CTRL, RI_RST_CLR);
        !          2260: 
        !          2261:        skge_write8(hw, B3_RI_WTO_R1, SK_RI_TO_53);
        !          2262:        skge_write8(hw, B3_RI_WTO_XA1, SK_RI_TO_53);
        !          2263:        skge_write8(hw, B3_RI_WTO_XS1, SK_RI_TO_53);
        !          2264:        skge_write8(hw, B3_RI_RTO_R1, SK_RI_TO_53);
        !          2265:        skge_write8(hw, B3_RI_RTO_XA1, SK_RI_TO_53);
        !          2266:        skge_write8(hw, B3_RI_RTO_XS1, SK_RI_TO_53);
        !          2267:        skge_write8(hw, B3_RI_WTO_R2, SK_RI_TO_53);
        !          2268:        skge_write8(hw, B3_RI_WTO_XA2, SK_RI_TO_53);
        !          2269:        skge_write8(hw, B3_RI_WTO_XS2, SK_RI_TO_53);
        !          2270:        skge_write8(hw, B3_RI_RTO_R2, SK_RI_TO_53);
        !          2271:        skge_write8(hw, B3_RI_RTO_XA2, SK_RI_TO_53);
        !          2272:        skge_write8(hw, B3_RI_RTO_XS2, SK_RI_TO_53);
        !          2273: 
        !          2274:        skge_write32(hw, B0_HWE_IMSK, IS_ERR_MSK);
        !          2275: 
        !          2276:        /* Set interrupt moderation for Transmit only
        !          2277:         * Receive interrupts avoided by NAPI
        !          2278:         */
        !          2279:        skge_write32(hw, B2_IRQM_MSK, IS_XA1_F|IS_XA2_F);
        !          2280:        skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
        !          2281:        skge_write32(hw, B2_IRQM_CTRL, TIM_START);
        !          2282: 
        !          2283:        skge_write32(hw, B0_IMSK, hw->intr_mask);
        !          2284: 
        !          2285:        for (i = 0; i < hw->ports; i++) {
        !          2286:                if (hw->chip_id == CHIP_ID_GENESIS)
        !          2287:                        genesis_reset(hw, i);
        !          2288:                else
        !          2289:                        yukon_reset(hw, i);
        !          2290:        }
        !          2291: 
        !          2292:        return 0;
        !          2293: }
        !          2294: 
        !          2295: /* Initialize network device */
        !          2296: static struct net_device *skge_devinit(struct skge_hw *hw, int port,
        !          2297:                                       int highmem __unused)
        !          2298: {
        !          2299:        struct skge_port *skge;
        !          2300:        struct net_device *dev = alloc_etherdev(sizeof(*skge));
        !          2301: 
        !          2302:        if (!dev) {
        !          2303:                DBG(PFX "etherdev alloc failed\n");
        !          2304:                return NULL;
        !          2305:        }
        !          2306: 
        !          2307:        dev->dev = &hw->pdev->dev;
        !          2308: 
        !          2309:        skge = netdev_priv(dev);
        !          2310:        skge->netdev = dev;
        !          2311:        skge->hw = hw;
        !          2312: 
        !          2313:        /* Auto speed and flow control */
        !          2314:        skge->autoneg = AUTONEG_ENABLE;
        !          2315:        skge->flow_control = FLOW_MODE_SYM_OR_REM;
        !          2316:        skge->duplex = -1;
        !          2317:        skge->speed = -1;
        !          2318:        skge->advertising = skge_supported_modes(hw);
        !          2319: 
        !          2320:        hw->dev[port] = dev;
        !          2321: 
        !          2322:        skge->port = port;
        !          2323: 
        !          2324:        /* read the mac address */
        !          2325:        memcpy(dev->hw_addr, (void *) (hw->regs + B2_MAC_1 + port*8), ETH_ALEN);
        !          2326: 
        !          2327:        return dev;
        !          2328: }
        !          2329: 
        !          2330: static void skge_show_addr(struct net_device *dev)
        !          2331: {
        !          2332:        DBG2(PFX "%s: addr %s\n",
        !          2333:             dev->name, netdev_addr(dev));
        !          2334: }
        !          2335: 
        !          2336: static int skge_probe(struct pci_device *pdev)
        !          2337: {
        !          2338:        struct net_device *dev, *dev1;
        !          2339:        struct skge_hw *hw;
        !          2340:        int err, using_dac = 0;
        !          2341: 
        !          2342:        adjust_pci_device(pdev);
        !          2343: 
        !          2344:        err = -ENOMEM;
        !          2345:        hw = zalloc(sizeof(*hw));
        !          2346:        if (!hw) {
        !          2347:                DBG(PFX "cannot allocate hardware struct\n");
        !          2348:                goto err_out_free_regions;
        !          2349:        }
        !          2350: 
        !          2351:        hw->pdev = pdev;
        !          2352: 
        !          2353:        hw->regs = (unsigned long)ioremap(pci_bar_start(pdev, PCI_BASE_ADDRESS_0),
        !          2354:                                SKGE_REG_SIZE);
        !          2355:        if (!hw->regs) {
        !          2356:                DBG(PFX "cannot map device registers\n");
        !          2357:                goto err_out_free_hw;
        !          2358:        }
        !          2359: 
        !          2360:        err = skge_reset(hw);
        !          2361:        if (err)
        !          2362:                goto err_out_iounmap;
        !          2363: 
        !          2364:        DBG(PFX " addr 0x%llx irq %d chip %s rev %d\n",
        !          2365:            (unsigned long long)pdev->ioaddr, pdev->irq,
        !          2366:            skge_board_name(hw), hw->chip_rev);
        !          2367: 
        !          2368:        dev = skge_devinit(hw, 0, using_dac);
        !          2369:        if (!dev)
        !          2370:                goto err_out_led_off;
        !          2371: 
        !          2372:        netdev_init ( dev, &skge_operations );
        !          2373: 
        !          2374:        err = register_netdev(dev);
        !          2375:        if (err) {
        !          2376:                DBG(PFX "cannot register net device\n");
        !          2377:                goto err_out_free_netdev;
        !          2378:        }
        !          2379: 
        !          2380:        skge_show_addr(dev);
        !          2381: 
        !          2382:        if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) {
        !          2383:                if (register_netdev(dev1) == 0)
        !          2384:                        skge_show_addr(dev1);
        !          2385:                else {
        !          2386:                        /* Failure to register second port need not be fatal */
        !          2387:                        DBG(PFX "register of second port failed\n");
        !          2388:                        hw->dev[1] = NULL;
        !          2389:                        netdev_nullify(dev1);
        !          2390:                        netdev_put(dev1);
        !          2391:                }
        !          2392:        }
        !          2393:        pci_set_drvdata(pdev, hw);
        !          2394: 
        !          2395:        return 0;
        !          2396: 
        !          2397: err_out_free_netdev:
        !          2398:        netdev_nullify(dev);
        !          2399:        netdev_put(dev);
        !          2400: err_out_led_off:
        !          2401:        skge_write16(hw, B0_LED, LED_STAT_OFF);
        !          2402: err_out_iounmap:
        !          2403:        iounmap((void*)hw->regs);
        !          2404: err_out_free_hw:
        !          2405:        free(hw);
        !          2406: err_out_free_regions:
        !          2407:        pci_set_drvdata(pdev, NULL);
        !          2408:        return err;
        !          2409: }
        !          2410: 
        !          2411: static void skge_remove(struct pci_device *pdev)
        !          2412: {
        !          2413:        struct skge_hw *hw  = pci_get_drvdata(pdev);
        !          2414:        struct net_device *dev0, *dev1;
        !          2415: 
        !          2416:        if (!hw)
        !          2417:                return;
        !          2418: 
        !          2419:        if ((dev1 = hw->dev[1]))
        !          2420:                unregister_netdev(dev1);
        !          2421:        dev0 = hw->dev[0];
        !          2422:        unregister_netdev(dev0);
        !          2423: 
        !          2424:        hw->intr_mask = 0;
        !          2425:        skge_write32(hw, B0_IMSK, 0);
        !          2426:        skge_read32(hw, B0_IMSK);
        !          2427: 
        !          2428:        skge_write16(hw, B0_LED, LED_STAT_OFF);
        !          2429:        skge_write8(hw, B0_CTST, CS_RST_SET);
        !          2430: 
        !          2431:        if (dev1) {
        !          2432:                netdev_nullify(dev1);
        !          2433:                netdev_put(dev1);
        !          2434:        }
        !          2435:        netdev_nullify(dev0);
        !          2436:        netdev_put(dev0);
        !          2437: 
        !          2438:        iounmap((void*)hw->regs);
        !          2439:        free(hw);
        !          2440:        pci_set_drvdata(pdev, NULL);
        !          2441: }
        !          2442: 
        !          2443: /*
        !          2444:  * Enable or disable IRQ masking.
        !          2445:  *
        !          2446:  * @v netdev           Device to control.
        !          2447:  * @v enable           Zero to mask off IRQ, non-zero to enable IRQ.
        !          2448:  *
        !          2449:  * This is a iPXE Network Driver API function.
        !          2450:  */
        !          2451: static void skge_net_irq ( struct net_device *dev, int enable ) {
        !          2452:        struct skge_port *skge = netdev_priv(dev);
        !          2453:        struct skge_hw *hw = skge->hw;
        !          2454: 
        !          2455:        if (enable)
        !          2456:                hw->intr_mask |= portmask[skge->port];
        !          2457:        else
        !          2458:                hw->intr_mask &= ~portmask[skge->port];
        !          2459:        skge_write32(hw, B0_IMSK, hw->intr_mask);
        !          2460: }
        !          2461: 
        !          2462: struct pci_driver skge_driver __pci_driver = {
        !          2463:        .ids      = skge_id_table,
        !          2464:        .id_count = ( sizeof (skge_id_table) / sizeof (skge_id_table[0]) ),
        !          2465:        .probe    = skge_probe,
        !          2466:        .remove   = skge_remove
        !          2467: };
        !          2468: 

unix.superglobalmegacorp.com

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