iPXE
Defines | Functions | Variables
sky2.c File Reference
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include <byteswap.h>
#include <mii.h>
#include "sky2.h"

Go to the source code of this file.

Defines

#define DRV_NAME   "sky2"
#define DRV_VERSION   "1.22"
#define PFX   DRV_NAME " "
#define RX_LE_SIZE   128
#define RX_LE_BYTES   (RX_LE_SIZE*sizeof(struct sky2_rx_le))
#define RX_RING_ALIGN   4096
#define RX_PENDING   (RX_LE_SIZE/6 - 2)
#define TX_RING_SIZE   128
#define TX_PENDING   (TX_RING_SIZE - 1)
#define TX_RING_ALIGN   4096
#define MAX_SKB_TX_LE   4
#define STATUS_RING_SIZE   512 /* 2 ports * (TX + RX) */
#define STATUS_LE_BYTES   (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
#define STATUS_RING_ALIGN   4096
#define PHY_RETRIES   1000
#define SKY2_EEPROM_MAGIC   0x9955aabb
#define RING_NEXT(x, s)   (((x)+1) & ((s)-1))

Functions

 FILE_LICENCE (GPL2_ONLY)
static void sky2_set_multicast (struct net_device *dev)
static int gm_phy_write (struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
static int __gm_phy_read (struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
static u16 gm_phy_read (struct sky2_hw *hw, unsigned port, u16 reg)
static void sky2_power_on (struct sky2_hw *hw)
static void sky2_power_aux (struct sky2_hw *hw)
static void sky2_gmac_reset (struct sky2_hw *hw, unsigned port)
static void sky2_phy_init (struct sky2_hw *hw, unsigned port)
static void sky2_phy_power_up (struct sky2_hw *hw, unsigned port)
static void sky2_phy_power_down (struct sky2_hw *hw, unsigned port)
static void sky2_set_tx_stfwd (struct sky2_hw *hw, unsigned port)
static void sky2_mac_init (struct sky2_hw *hw, unsigned port)
static void sky2_ramset (struct sky2_hw *hw, u16 q, u32 start, u32 space)
static void sky2_qset (struct sky2_hw *hw, u16 q)
static void sky2_prefetch_init (struct sky2_hw *hw, u32 qaddr, u64 addr, u32 last)
static struct sky2_tx_leget_tx_le (struct sky2_port *sky2)
static void tx_init (struct sky2_port *sky2)
static struct tx_ring_infotx_le_re (struct sky2_port *sky2, struct sky2_tx_le *le)
static void sky2_put_idx (struct sky2_hw *hw, unsigned q, u16 idx)
static struct sky2_rx_lesky2_next_rx (struct sky2_port *sky2)
static void sky2_rx_add (struct sky2_port *sky2, u8 op, u32 map, unsigned len)
static void sky2_rx_submit (struct sky2_port *sky2, const struct rx_ring_info *re)
static void sky2_rx_map_iob (struct pci_device *pdev __unused, struct rx_ring_info *re, unsigned size __unused)
static void rx_set_checksum (struct sky2_port *sky2)
static void sky2_rx_stop (struct sky2_port *sky2)
static void sky2_rx_clean (struct sky2_port *sky2)
static struct io_buffersky2_rx_alloc (struct sky2_port *sky2)
static void sky2_rx_update (struct sky2_port *sky2, unsigned rxq)
static int sky2_rx_start (struct sky2_port *sky2)
static void sky2_free_rings (struct sky2_port *sky2)
static int sky2_up (struct net_device *dev)
static int tx_dist (unsigned tail, unsigned head)
static int tx_avail (const struct sky2_port *sky2)
static int sky2_xmit_frame (struct net_device *dev, struct io_buffer *iob)
static void sky2_tx_complete (struct sky2_port *sky2, u16 done)
static void sky2_tx_clean (struct net_device *dev)
static void sky2_down (struct net_device *dev)
static u16 sky2_phy_speed (const struct sky2_hw *hw, u16 aux)
static void sky2_link_up (struct sky2_port *sky2)
static void sky2_link_down (struct sky2_port *sky2)
static int sky2_autoneg_done (struct sky2_port *sky2, u16 aux)
static void sky2_phy_intr (struct sky2_hw *hw, unsigned port)
static struct io_bufferreceive_new (struct sky2_port *sky2, struct rx_ring_info *re, unsigned int length)
static struct io_buffersky2_receive (struct net_device *dev, u16 length, u32 status)
static void sky2_tx_done (struct net_device *dev, u16 last)
static void sky2_status_intr (struct sky2_hw *hw, u16 idx)
static void sky2_hw_error (struct sky2_hw *hw, unsigned port, u32 status)
static void sky2_hw_intr (struct sky2_hw *hw)
static void sky2_mac_intr (struct sky2_hw *hw, unsigned port)
static void sky2_le_error (struct sky2_hw *hw, unsigned port, u16 q, unsigned ring_size __unused)
static void sky2_err_intr (struct sky2_hw *hw, u32 status)
static void sky2_poll (struct net_device *dev)
static u32 sky2_mhz (const struct sky2_hw *hw)
static u32 sky2_us2clk (const struct sky2_hw *hw, u32 us)
static u32 sky2_clk2us (const struct sky2_hw *hw, u32 clk)
static int sky2_init (struct sky2_hw *hw)
static void sky2_reset (struct sky2_hw *hw)
static u32 sky2_supported_modes (const struct sky2_hw *hw)
static struct net_devicesky2_init_netdev (struct sky2_hw *hw, unsigned port)
static void sky2_show_addr (struct net_device *dev)
static void sky2_net_irq (struct net_device *dev, int enable)
static int sky2_probe (struct pci_device *pdev)
static void sky2_remove (struct pci_device *pdev)

Variables

static struct pci_device_id sky2_id_table []
static const unsigned txqaddr [] = { Q_XA1, Q_XA2 }
static const unsigned rxqaddr [] = { Q_R1, Q_R2 }
static const u32 portirq_msk [] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }
static const u16 copper_fc_adv []
static const u16 fiber_fc_adv []
static const u16 gm_fc_disable []
static const u32 phy_power [] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }
static const u32 coma_mode [] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA }
static struct net_device_operations sky2_operations
struct pci_driver sky2_driver __pci_driver

Define Documentation

#define DRV_NAME   "sky2"

Definition at line 44 of file sky2.c.

#define DRV_VERSION   "1.22"

Definition at line 45 of file sky2.c.

#define PFX   DRV_NAME " "
#define RX_LE_SIZE   128

Definition at line 61 of file sky2.c.

Referenced by sky2_err_intr(), sky2_next_rx(), and sky2_rx_start().

#define RX_LE_BYTES   (RX_LE_SIZE*sizeof(struct sky2_rx_le))

Definition at line 62 of file sky2.c.

Referenced by sky2_free_rings(), sky2_rx_clean(), and sky2_up().

#define RX_RING_ALIGN   4096

Definition at line 63 of file sky2.c.

Referenced by a3c90x_setup_rx_ring(), pcnet32_setup_rx_resources(), and sky2_up().

#define RX_PENDING   (RX_LE_SIZE/6 - 2)

Definition at line 64 of file sky2.c.

Referenced by sky2_receive(), sky2_rx_clean(), sky2_rx_start(), and sky2_up().

#define TX_RING_SIZE   128
#define TX_PENDING   (TX_RING_SIZE - 1)

Definition at line 67 of file sky2.c.

Referenced by tx_avail().

#define TX_RING_ALIGN   4096

Definition at line 68 of file sky2.c.

Referenced by a3c90x_setup_tx_ring(), pcnet32_setup_tx_resources(), and sky2_up().

#define MAX_SKB_TX_LE   4

Definition at line 69 of file sky2.c.

#define STATUS_RING_SIZE   512 /* 2 ports * (TX + RX) */

Definition at line 71 of file sky2.c.

Referenced by sky2_reset(), and sky2_status_intr().

#define STATUS_LE_BYTES   (STATUS_RING_SIZE*sizeof(struct sky2_status_le))

Definition at line 72 of file sky2.c.

Referenced by sky2_probe(), sky2_remove(), and sky2_reset().

#define STATUS_RING_ALIGN   4096

Definition at line 73 of file sky2.c.

Referenced by sky2_probe().

#define PHY_RETRIES   1000

Definition at line 74 of file sky2.c.

Referenced by __gm_phy_read(), and gm_phy_write().

#define SKY2_EEPROM_MAGIC   0x9955aabb

Definition at line 76 of file sky2.c.

#define RING_NEXT (   x,
 
)    (((x)+1) & ((s)-1))

Definition at line 79 of file sky2.c.

Referenced by get_tx_le(), sky2_next_rx(), sky2_status_intr(), and sky2_tx_complete().


Function Documentation

FILE_LICENCE ( GPL2_ONLY  )
static void sky2_set_multicast ( struct net_device dev) [static]

Definition at line 2153 of file sky2.c.

References filter, GM_MC_ADDR_H1, GM_MC_ADDR_H2, GM_MC_ADDR_H3, GM_MC_ADDR_H4, GM_RX_CTRL, GM_RXCR_UCF_ENA, gma_read16(), gma_write16(), sky2_port::hw, memset(), netdev_priv(), port, sky2_port::port, and reg.

Referenced by sky2_up().

{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u16 reg;
        u8 filter[8];

        reg = gma_read16(hw, port, GM_RX_CTRL);
        reg |= GM_RXCR_UCF_ENA;

        memset(filter, 0xff, sizeof(filter));

        gma_write16(hw, port, GM_MC_ADDR_H1,
                    (u16) filter[0] | ((u16) filter[1] << 8));
        gma_write16(hw, port, GM_MC_ADDR_H2,
                    (u16) filter[2] | ((u16) filter[3] << 8));
        gma_write16(hw, port, GM_MC_ADDR_H3,
                    (u16) filter[4] | ((u16) filter[5] << 8));
        gma_write16(hw, port, GM_MC_ADDR_H4,
                    (u16) filter[6] | ((u16) filter[7] << 8));

        gma_write16(hw, port, GM_RX_CTRL, reg);
}
static int gm_phy_write ( struct sky2_hw hw,
unsigned  port,
u16  reg,
u16  val 
) [static]

Definition at line 131 of file sky2.c.

References ctrl, DBG, sky2_hw::dev, EIO, ETIMEDOUT, GM_SMI_CT_BUSY, GM_SMI_CT_PHY_AD, GM_SMI_CT_REG_AD, GM_SMI_CTRL, GM_SMI_DATA, gma_read16(), gma_write16(), net_device::name, PFX, PHY_ADDR_MARV, PHY_RETRIES, and udelay().

Referenced by sky2_link_down(), sky2_link_up(), sky2_phy_init(), sky2_phy_power_down(), and sky2_phy_power_up().

{
        int i;

        gma_write16(hw, port, GM_SMI_DATA, val);
        gma_write16(hw, port, GM_SMI_CTRL,
                    GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));

        for (i = 0; i < PHY_RETRIES; i++) {
                u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
                if (ctrl == 0xffff)
                        goto io_error;

                if (!(ctrl & GM_SMI_CT_BUSY))
                        return 0;

                udelay(10);
        }

        DBG(PFX "%s: phy write timeout\n", hw->dev[port]->name);
        return -ETIMEDOUT;

io_error:
        DBG(PFX "%s: phy I/O error\n", hw->dev[port]->name);
        return -EIO;
}
static int __gm_phy_read ( struct sky2_hw hw,
unsigned  port,
u16  reg,
u16 val 
) [static]

Definition at line 158 of file sky2.c.

References ctrl, DBG, sky2_hw::dev, EIO, ETIMEDOUT, GM_SMI_CT_OP_RD, GM_SMI_CT_PHY_AD, GM_SMI_CT_RD_VAL, GM_SMI_CT_REG_AD, GM_SMI_CTRL, GM_SMI_DATA, gma_read16(), gma_write16(), net_device::name, PFX, PHY_ADDR_MARV, PHY_RETRIES, and udelay().

Referenced by gm_phy_read().

{
        int i;

        gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
                    | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);

        for (i = 0; i < PHY_RETRIES; i++) {
                u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
                if (ctrl == 0xffff)
                        goto io_error;

                if (ctrl & GM_SMI_CT_RD_VAL) {
                        *val = gma_read16(hw, port, GM_SMI_DATA);
                        return 0;
                }

                udelay(10);
        }

        DBG(PFX "%s: phy read timeout\n", hw->dev[port]->name);
        return -ETIMEDOUT;
io_error:
        DBG(PFX "%s: phy I/O error\n", hw->dev[port]->name);
        return -EIO;
}
static u16 gm_phy_read ( struct sky2_hw hw,
unsigned  port,
u16  reg 
) [inline, static]

Definition at line 185 of file sky2.c.

References __gm_phy_read().

Referenced by sky2_autoneg_done(), sky2_mac_init(), sky2_phy_init(), sky2_phy_intr(), and sky2_phy_power_down().

{
        u16 v = 0;
        __gm_phy_read(hw, port, reg, &v);
        return v;
}
static void sky2_power_on ( struct sky2_hw hw) [static]

Definition at line 193 of file sky2.c.

References B0_POWER_CTRL, B2_GP_IO, B2_Y2_CLK_CTRL, B2_Y2_CLK_GATE, sky2_hw::chip_id, CHIP_ID_YUKON_XL, sky2_hw::chip_rev, sky2_hw::flags, GLB_GPIO_STAT_RACE_DIS, P_CTL_TIM_VMAIN_AV_MSK, PC_VAUX_ENA, PC_VAUX_OFF, PC_VCC_ENA, PC_VCC_ON, PCI_CFG_REG_1, PCI_DEV_REG3, PCI_DEV_REG4, PCI_DEV_REG5, reg, SKY2_HW_ADV_POWER_CTL, sky2_pci_read32(), sky2_pci_write32(), sky2_read32(), sky2_write32(), sky2_write8(), Y2_CLK_GAT_LNK1_DIS, Y2_CLK_GAT_LNK2_DIS, Y2_COR_CLK_LNK1_DIS, Y2_COR_CLK_LNK2_DIS, Y2_PCI_CLK_LNK1_DIS, and Y2_PCI_CLK_LNK2_DIS.

Referenced by sky2_reset().

{
        /* switch power to VCC (WA for VAUX problem) */
        sky2_write8(hw, B0_POWER_CTRL,
                    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);

        /* disable Core Clock Division, */
        sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);

        if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
                /* enable bits are inverted */
                sky2_write8(hw, B2_Y2_CLK_GATE,
                            Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
                            Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
                            Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
        else
                sky2_write8(hw, B2_Y2_CLK_GATE, 0);

        if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
                u32 reg;

                sky2_pci_write32(hw, PCI_DEV_REG3, 0);

                reg = sky2_pci_read32(hw, PCI_DEV_REG4);
                /* set all bits to 0 except bits 15..12 and 8 */
                reg &= P_ASPM_CONTROL_MSK;
                sky2_pci_write32(hw, PCI_DEV_REG4, reg);

                reg = sky2_pci_read32(hw, PCI_DEV_REG5);
                /* set all bits to 0 except bits 28 & 27 */
                reg &= P_CTL_TIM_VMAIN_AV_MSK;
                sky2_pci_write32(hw, PCI_DEV_REG5, reg);

                sky2_pci_write32(hw, PCI_CFG_REG_1, 0);

                /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
                reg = sky2_read32(hw, B2_GP_IO);
                reg |= GLB_GPIO_STAT_RACE_DIS;
                sky2_write32(hw, B2_GP_IO, reg);

                sky2_read32(hw, B2_GP_IO);
        }
}
static void sky2_power_aux ( struct sky2_hw hw) [static]
static void sky2_gmac_reset ( struct sky2_hw hw,
unsigned  port 
) [static]
static void sky2_phy_init ( struct sky2_hw hw,
unsigned  port 
) [static]

Definition at line 297 of file sky2.c.

References ADVERTISED_1000baseT_Full, ADVERTISED_1000baseT_Half, ADVERTISED_100baseT_Full, ADVERTISED_100baseT_Half, ADVERTISED_10baseT_Full, ADVERTISED_10baseT_Half, sky2_port::advertising, sky2_port::autoneg, AUTONEG_DISABLE, AUTONEG_ENABLE, BLINK_84MS, sky2_hw::chip_id, CHIP_ID_YUKON_EC, CHIP_ID_YUKON_EC_U, CHIP_ID_YUKON_EX, CHIP_ID_YUKON_FE, CHIP_ID_YUKON_FE_P, CHIP_ID_YUKON_SUPR, CHIP_ID_YUKON_UL_2, CHIP_ID_YUKON_XL, sky2_hw::chip_rev, CHIP_REV_YU_FE2_A0, copper_fc_adv, ctrl, sky2_hw::dev, sky2_port::duplex, DUPLEX_FULL, FC_NONE, FC_RX, fiber_fc_adv, sky2_hw::flags, sky2_port::flow_mode, gm_fc_disable, GM_GP_CTRL, GM_GPCR_AU_ALL_DIS, GM_GPCR_DUP_FULL, GM_GPCR_SPEED_100, GM_GPCR_SPEED_1000, gm_phy_read(), gm_phy_write(), gma_write16(), GMAC_CTRL, GMC_PAUSE_OFF, GMC_PAUSE_ON, LED_PAR_CTRL_ACT_BL, LED_PAR_CTRL_LINK, LED_PAR_CTRL_SPEED, MAC_TX_CLK_25_MHZ, MO_LED_OFF, MO_LED_ON, netdev_priv(), PHY_AN_CSMA, PHY_CT_ANE, PHY_CT_DUP_MD, PHY_CT_RE_CFG, PHY_CT_RESET, PHY_CT_SP100, PHY_CT_SP1000, PHY_M_1000C_AFD, PHY_M_1000C_AHD, PHY_M_1000C_MSE, PHY_M_AN_1000X_AFD, PHY_M_AN_1000X_AHD, PHY_M_AN_100_FD, PHY_M_AN_100_HD, PHY_M_AN_10_FD, PHY_M_AN_10_HD, PHY_M_DEF_MSK, PHY_M_EC_DOWN_S_ENA, PHY_M_EC_DSC_2, PHY_M_EC_M_DSC, PHY_M_EC_M_DSC_MSK, PHY_M_EC_MAC_S, PHY_M_EC_MAC_S_MSK, PHY_M_EC_S_DSC, PHY_M_EC_S_DSC_MSK, PHY_M_FELP_LED0_CTRL, PHY_M_FELP_LED1_CTRL, PHY_M_FELP_LED1_MSK, PHY_M_FELP_LED2_CTRL, PHY_M_FESC_SEL_CL_A, PHY_M_FIB_SIGD_POL, PHY_M_IS_AN_COMPL, PHY_M_LED_BLINK_RT, PHY_M_LED_MO_100, PHY_M_LED_MO_RX, PHY_M_LED_PULS_DUR, PHY_M_LEDC_INIT_CTRL, PHY_M_LEDC_LOS_CTRL, PHY_M_LEDC_STA0_CTRL, PHY_M_LEDC_STA1_CTRL, PHY_M_LEDC_TX_CTRL, PHY_M_MAC_MD_1000BX, PHY_M_MAC_MD_MSK, PHY_M_MAC_MODE_SEL, PHY_M_PC_DIS_SCRAMB, PHY_M_PC_DOWN_S_ENA, PHY_M_PC_DSC, PHY_M_PC_DSC_MSK, PHY_M_PC_EN_DET_MSK, PHY_M_PC_ENA_AUTO, PHY_M_PC_ENA_ENE_DT, PHY_M_PC_ENA_LIP_NP, PHY_M_PC_MDI_XMODE, PHY_M_PC_MDIX_MSK, PHY_M_POLC_INIT_CTRL, PHY_M_POLC_IS0_P_MIX, PHY_M_POLC_LOS_CTRL, PHY_M_POLC_LS1_P_MIX, PHY_M_POLC_STA0_CTRL, PHY_M_POLC_STA1_CTRL, PHY_MARV_1000T_CTRL, PHY_MARV_AUNE_ADV, PHY_MARV_CTRL, PHY_MARV_EXT_ADR, PHY_MARV_EXT_CTRL, PHY_MARV_FE_LED_PAR, PHY_MARV_FE_SPEC_2, PHY_MARV_INT_MASK, PHY_MARV_LED_CTRL, PHY_MARV_LED_OVER, PHY_MARV_PAGE_ADDR, PHY_MARV_PAGE_DATA, PHY_MARV_PHY_CTRL, PHY_MARV_PHY_STAT, sky2_hw::pmd_type, PULS_170MS, reg, SK_REG, SKY2_HW_FIBRE_PHY, SKY2_HW_GIGABIT, SKY2_HW_NEWER_PHY, sky2_is_copper(), sky2_write8(), sky2_port::speed, SPEED_100, and SPEED_1000.

Referenced by sky2_link_down(), and sky2_mac_init().

{
        struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
        u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;

        if (sky2->autoneg == AUTONEG_ENABLE &&
            !(hw->flags & SKY2_HW_NEWER_PHY)) {
                u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);

                ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
                           PHY_M_EC_MAC_S_MSK);
                ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);

                /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */
                if (hw->chip_id == CHIP_ID_YUKON_EC)
                        /* set downshift counter to 3x and enable downshift */
                        ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
                else
                        /* set master & slave downshift counter to 1x */
                        ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);

                gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
        }

        ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
        if (sky2_is_copper(hw)) {
                if (!(hw->flags & SKY2_HW_GIGABIT)) {
                        /* enable automatic crossover */
                        ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;

                        if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
                            hw->chip_rev == CHIP_REV_YU_FE2_A0) {
                                u16 spec;

                                /* Enable Class A driver for FE+ A0 */
                                spec = gm_phy_read(hw, port, PHY_MARV_FE_SPEC_2);
                                spec |= PHY_M_FESC_SEL_CL_A;
                                gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
                        }
                } else {
                        /* disable energy detect */
                        ctrl &= ~PHY_M_PC_EN_DET_MSK;

                        /* enable automatic crossover */
                        ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);

                        /* downshift on PHY 88E1112 and 88E1149 is changed */
                        if (sky2->autoneg == AUTONEG_ENABLE
                            && (hw->flags & SKY2_HW_NEWER_PHY)) {
                                /* set downshift counter to 3x and enable downshift */
                                ctrl &= ~PHY_M_PC_DSC_MSK;
                                ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
                        }
                }
        } else {
                /* workaround for deviation #4.88 (CRC errors) */
                /* disable Automatic Crossover */

                ctrl &= ~PHY_M_PC_MDIX_MSK;
        }

        gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);

        /* special setup for PHY 88E1112 Fiber */
        if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) {
                pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);

                /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
                ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                ctrl &= ~PHY_M_MAC_MD_MSK;
                ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
                gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);

                if (hw->pmd_type  == 'P') {
                        /* select page 1 to access Fiber registers */
                        gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);

                        /* for SFP-module set SIGDET polarity to low */
                        ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                        ctrl |= PHY_M_FIB_SIGD_POL;
                        gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
                }

                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
        }

        ctrl = PHY_CT_RESET;
        ct1000 = 0;
        adv = PHY_AN_CSMA;
        reg = 0;

        if (sky2->autoneg == AUTONEG_ENABLE) {
                if (sky2_is_copper(hw)) {
                        if (sky2->advertising & ADVERTISED_1000baseT_Full)
                                ct1000 |= PHY_M_1000C_AFD;
                        if (sky2->advertising & ADVERTISED_1000baseT_Half)
                                ct1000 |= PHY_M_1000C_AHD;
                        if (sky2->advertising & ADVERTISED_100baseT_Full)
                                adv |= PHY_M_AN_100_FD;
                        if (sky2->advertising & ADVERTISED_100baseT_Half)
                                adv |= PHY_M_AN_100_HD;
                        if (sky2->advertising & ADVERTISED_10baseT_Full)
                                adv |= PHY_M_AN_10_FD;
                        if (sky2->advertising & ADVERTISED_10baseT_Half)
                                adv |= PHY_M_AN_10_HD;

                        adv |= copper_fc_adv[sky2->flow_mode];
                } else {        /* special defines for FIBER (88E1040S only) */
                        if (sky2->advertising & ADVERTISED_1000baseT_Full)
                                adv |= PHY_M_AN_1000X_AFD;
                        if (sky2->advertising & ADVERTISED_1000baseT_Half)
                                adv |= PHY_M_AN_1000X_AHD;

                        adv |= fiber_fc_adv[sky2->flow_mode];
                }

                /* Restart Auto-negotiation */
                ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
        } else {
                /* forced speed/duplex settings */
                ct1000 = PHY_M_1000C_MSE;

                /* Disable auto update for duplex flow control and speed */
                reg |= GM_GPCR_AU_ALL_DIS;

                switch (sky2->speed) {
                case SPEED_1000:
                        ctrl |= PHY_CT_SP1000;
                        reg |= GM_GPCR_SPEED_1000;
                        break;
                case SPEED_100:
                        ctrl |= PHY_CT_SP100;
                        reg |= GM_GPCR_SPEED_100;
                        break;
                }

                if (sky2->duplex == DUPLEX_FULL) {
                        reg |= GM_GPCR_DUP_FULL;
                        ctrl |= PHY_CT_DUP_MD;
                } else if (sky2->speed < SPEED_1000)
                        sky2->flow_mode = FC_NONE;


                reg |= gm_fc_disable[sky2->flow_mode];

                /* Forward pause packets to GMAC? */
                if (sky2->flow_mode & FC_RX)
                        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
                else
                        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
        }

        gma_write16(hw, port, GM_GP_CTRL, reg);

        if (hw->flags & SKY2_HW_GIGABIT)
                gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);

        gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
        gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);

        /* Setup Phy LED's */
        ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
        ledover = 0;

        switch (hw->chip_id) {
        case CHIP_ID_YUKON_FE:
                /* on 88E3082 these bits are at 11..9 (shifted left) */
                ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;

                ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);

                /* delete ACT LED control bits */
                ctrl &= ~PHY_M_FELP_LED1_MSK;
                /* change ACT LED control to blink mode */
                ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
                gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
                break;

        case CHIP_ID_YUKON_FE_P:
                /* Enable Link Partner Next Page */
                ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                ctrl |= PHY_M_PC_ENA_LIP_NP;

                /* disable Energy Detect and enable scrambler */
                ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
                gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);

                /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */
                ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
                        PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) |
                        PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED);

                gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
                break;

        case CHIP_ID_YUKON_XL:
                pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);

                /* select page 3 to access LED control register */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);

                /* set LED Function Control register */
                gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
                             (PHY_M_LEDC_LOS_CTRL(1) |  /* LINK/ACT */
                              PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */
                              PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
                              PHY_M_LEDC_STA0_CTRL(7)));        /* 1000 Mbps */

                /* set Polarity Control register */
                gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
                             (PHY_M_POLC_LS1_P_MIX(4) |
                              PHY_M_POLC_IS0_P_MIX(4) |
                              PHY_M_POLC_LOS_CTRL(2) |
                              PHY_M_POLC_INIT_CTRL(2) |
                              PHY_M_POLC_STA1_CTRL(2) |
                              PHY_M_POLC_STA0_CTRL(2)));

                /* restore page register */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
                break;

        case CHIP_ID_YUKON_EC_U:
        case CHIP_ID_YUKON_EX:
        case CHIP_ID_YUKON_SUPR:
                pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);

                /* select page 3 to access LED control register */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);

                /* set LED Function Control register */
                gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
                             (PHY_M_LEDC_LOS_CTRL(1) |  /* LINK/ACT */
                              PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */
                              PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
                              PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */

                /* set Blink Rate in LED Timer Control Register */
                gm_phy_write(hw, port, PHY_MARV_INT_MASK,
                             ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
                /* restore page register */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
                break;

        default:
                /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
                ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;

                /* turn off the Rx LED (LED_RX) */
                ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
        }

        if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_UL_2) {
                /* apply fixes in PHY AFE */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);

                /* increase differential signal amplitude in 10BASE-T */
                gm_phy_write(hw, port, 0x18, 0xaa99);
                gm_phy_write(hw, port, 0x17, 0x2011);

                if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
                        /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
                        gm_phy_write(hw, port, 0x18, 0xa204);
                        gm_phy_write(hw, port, 0x17, 0x2002);
                }

                /* set page register to 0 */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
        } else if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
                   hw->chip_rev == CHIP_REV_YU_FE2_A0) {
                /* apply workaround for integrated resistors calibration */
                gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
                gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
        } else if (hw->chip_id != CHIP_ID_YUKON_EX &&
                   hw->chip_id < CHIP_ID_YUKON_SUPR) {
                /* no effect on Yukon-XL */
                gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);

                if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
                        /* turn on 100 Mbps LED (LED_LINK100) */
                        ledover |= PHY_M_LED_MO_100(MO_LED_ON);
                }

                if (ledover)
                        gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);

        }

        /* Enable phy interrupt on auto-negotiation complete (or link up) */
        if (sky2->autoneg == AUTONEG_ENABLE)
                gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
        else
                gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
}
static void sky2_phy_power_up ( struct sky2_hw hw,
unsigned  port 
) [static]
static void sky2_phy_power_down ( struct sky2_hw hw,
unsigned  port 
) [static]

Definition at line 616 of file sky2.c.

References B2_TST_CTRL1, sky2_hw::chip_id, CHIP_ID_YUKON_EC, CHIP_ID_YUKON_EC_U, ctrl, sky2_hw::flags, GM_GP_CTRL, GM_GPCR_AU_ALL_DIS, GM_GPCR_FL_PASS, GM_GPCR_SPEED_100, gm_phy_read(), gm_phy_write(), gma_write16(), GMAC_CTRL, GMC_RST_CLR, GPC_RST_CLR, GPHY_CTRL, PCI_DEV_REG1, PHY_CT_PDOWN, PHY_M_MAC_GMIF_PUP, PHY_M_PC_POW_D_ENA, PHY_MARV_CTRL, PHY_MARV_EXT_ADR, PHY_MARV_PHY_CTRL, phy_power, port, SK_REG, SKY2_HW_NEWER_PHY, sky2_pci_read32(), sky2_pci_write32(), sky2_write8(), TST_CFG_WRITE_OFF, and TST_CFG_WRITE_ON.

Referenced by sky2_down().

{
        u32 reg1;
        u16 ctrl;

        /* release GPHY Control reset */
        sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);

        /* release GMAC reset */
        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);

        if (hw->flags & SKY2_HW_NEWER_PHY) {
                /* select page 2 to access MAC control register */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);

                ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                /* allow GMII Power Down */
                ctrl &= ~PHY_M_MAC_GMIF_PUP;
                gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);

                /* set page register back to 0 */
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
        }

        /* setup General Purpose Control Register */
        gma_write16(hw, port, GM_GP_CTRL,
                    GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);

        if (hw->chip_id != CHIP_ID_YUKON_EC) {
                if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
                        /* select page 2 to access MAC control register */
                        gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);

                        ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                        /* enable Power Down */
                        ctrl |= PHY_M_PC_POW_D_ENA;
                        gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);

                        /* set page register back to 0 */
                        gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
                }

                /* set IEEE compatible Power Down Mode (dev. #4.99) */
                gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
        }

        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
        reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
        reg1 |= phy_power[port];                /* set PHY to PowerDown/COMA Mode */
        sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
static void sky2_set_tx_stfwd ( struct sky2_hw hw,
unsigned  port 
) [static]
static void sky2_mac_init ( struct sky2_hw hw,
unsigned  port 
) [static]

Definition at line 683 of file sky2.c.

References addr, sky2_hw::chip_id, CHIP_ID_YUKON_EX, CHIP_ID_YUKON_FE_P, CHIP_ID_YUKON_XL, sky2_hw::chip_rev, CHIP_REV_YU_FE2_A0, DATA_BLIND_DEF, DATA_BLIND_VAL, sky2_hw::dev, sky2_hw::flags, GM_MIB_CNT_BASE, GM_MIB_CNT_END, GM_PAR_MIB_CLR, GM_PHY_ADDR, gm_phy_read(), GM_RX_CTRL, GM_RX_IRQ_MSK, GM_RXCR_CRC_DIS, GM_RXCR_MCF_ENA, GM_RXCR_UCF_ENA, GM_SERIAL_MODE, GM_SMOD_VLAN_ENA, GM_SRC_ADDR_1L, GM_SRC_ADDR_2L, GM_TR_IRQ_MSK, GM_TX_CTRL, GM_TX_FLOW_CTRL, GM_TX_IRQ_MSK, GM_TX_PARAM, gma_read16(), gma_set_addr(), gma_write16(), GMAC_CTRL, GMAC_DEF_MSK, GMAC_IRQ_MSK, GMAC_IRQ_SRC, GMC_RST_CLR, GMC_RST_SET, GMF_OPER_ON, GMF_RST_CLR, GMF_RX_F_FL_ON, GMF_RX_OVER_ON, GMR_FS_ANY_ERR, GPC_RST_CLR, GPC_RST_SET, GPHY_CTRL, IPG_DATA_DEF, IPG_DATA_VAL, net_device::ll_addr, PHY_MARV_ID0, PHY_MARV_ID0_VAL, PHY_MARV_ID1, PHY_MARV_ID1_Y2, PHY_MARV_INT_MASK, port, reg, RX_GMF_CTRL_T, RX_GMF_FL_MSK, RX_GMF_FL_THR, RX_GMF_FL_THR_DEF, RX_GMF_LP_THR, RX_GMF_UP_THR, SK_REG, SKY2_HW_RAM_BUFFER, sky2_phy_init(), sky2_phy_power_up(), sky2_read16(), sky2_set_tx_stfwd(), sky2_write16(), sky2_write32(), sky2_write8(), TX_BACK_OFF_LIM, TX_BOF_LIM_DEF, TX_COL_DEF, TX_COL_THR, TX_DYN_WM_ENA, TX_GMF_CTRL_T, TX_GMF_EA, TX_IPG_JAM_DATA, TX_IPG_JAM_DEF, TX_JAM_IPG_DEF, TX_JAM_IPG_VAL, TX_JAM_LEN_DEF, and TX_JAM_LEN_VAL.

Referenced by sky2_up().

{
        u16 reg;
        u32 rx_reg;
        int i;
        const u8 *addr = hw->dev[port]->ll_addr;

        sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
        sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);

        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);

        if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) {
                /* WA DEV_472 -- looks like crossed wires on port 2 */
                /* clear GMAC 1 Control reset */
                sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
                do {
                        sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
                        sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
                } while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
                         gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
                         gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
        }

        sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));

        /* Enable Transmit FIFO Underrun */
        sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);

        sky2_phy_power_up(hw, port);
        sky2_phy_init(hw, port);

        /* MIB clear */
        reg = gma_read16(hw, port, GM_PHY_ADDR);
        gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);

        for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
                gma_read16(hw, port, i);
        gma_write16(hw, port, GM_PHY_ADDR, reg);

        /* transmit control */
        gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));

        /* receive control reg: unicast + multicast + no FCS  */
        gma_write16(hw, port, GM_RX_CTRL,
                    GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);

        /* transmit flow control */
        gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);

        /* transmit parameter */
        gma_write16(hw, port, GM_TX_PARAM,
                    TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
                    TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
                    TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
                    TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));

        /* serial mode register */
        reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
                GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);

        gma_write16(hw, port, GM_SERIAL_MODE, reg);

        /* virtual address for data */
        gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);

        /* physical address: used for pause frames */
        gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);

        /* ignore counter overflows */
        gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
        gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
        gma_write16(hw, port, GM_TR_IRQ_MSK, 0);

        /* Configure Rx MAC FIFO */
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
        rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
        if (hw->chip_id == CHIP_ID_YUKON_EX ||
            hw->chip_id == CHIP_ID_YUKON_FE_P)
                rx_reg |= GMF_RX_OVER_ON;

        sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg);

        if (hw->chip_id == CHIP_ID_YUKON_XL) {
                /* Hardware errata - clear flush mask */
                sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), 0);
        } else {
                /* Flush Rx MAC FIFO on any flow control or error */
                sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
        }

        /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug  */
        reg = RX_GMF_FL_THR_DEF + 1;
        /* Another magic mystery workaround from sk98lin */
        if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
            hw->chip_rev == CHIP_REV_YU_FE2_A0)
                reg = 0x178;
        sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg);

        /* Configure Tx MAC FIFO */
        sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
        sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);

        /* On chips without ram buffer, pause is controlled by MAC level */
        if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
                sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
                sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);

                sky2_set_tx_stfwd(hw, port);
        }

        if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
            hw->chip_rev == CHIP_REV_YU_FE2_A0) {
                /* disable dynamic watermark */
                reg = sky2_read16(hw, SK_REG(port, TX_GMF_EA));
                reg &= ~TX_DYN_WM_ENA;
                sky2_write16(hw, SK_REG(port, TX_GMF_EA), reg);
        }
}
static void sky2_ramset ( struct sky2_hw hw,
u16  q,
u32  start,
u32  space 
) [static]

Definition at line 804 of file sky2.c.

References end, Q_R1, Q_R2, RB_ADDR, RB_CTRL, RB_ENA_OP_MD, RB_ENA_STFWD, RB_END, RB_RP, RB_RST_CLR, RB_RX_LTHP, RB_RX_LTPP, RB_RX_UTHP, RB_RX_UTPP, RB_START, RB_WP, sky2_read8(), sky2_write32(), sky2_write8(), and tp.

Referenced by sky2_up().

{
        u32 end;

        /* convert from K bytes to qwords used for hw register */
        start *= 1024/8;
        space *= 1024/8;
        end = start + space - 1;

        sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
        sky2_write32(hw, RB_ADDR(q, RB_START), start);
        sky2_write32(hw, RB_ADDR(q, RB_END), end);
        sky2_write32(hw, RB_ADDR(q, RB_WP), start);
        sky2_write32(hw, RB_ADDR(q, RB_RP), start);

        if (q == Q_R1 || q == Q_R2) {
                u32 tp = space - space/4;

                /* On receive queue's set the thresholds
                 * give receiver priority when > 3/4 full
                 * send pause when down to 2K
                 */
                sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
                sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);

                tp = space - 2048/8;
                sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
                sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
        } else {
                /* Enable store & forward on Tx queue's because
                 * Tx FIFO is only 1K on Yukon
                 */
                sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
        }

        sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
        sky2_read8(hw, RB_ADDR(q, RB_CTRL));
}
static void sky2_qset ( struct sky2_hw hw,
u16  q 
) [static]
static void sky2_prefetch_init ( struct sky2_hw hw,
u32  qaddr,
u64  addr,
u32  last 
) [static]
static struct sky2_tx_le* get_tx_le ( struct sky2_port sky2) [static, read]

Definition at line 868 of file sky2.c.

References sky2_tx_le::ctrl, RING_NEXT, sky2_port::tx_le, sky2_port::tx_prod, and TX_RING_SIZE.

Referenced by sky2_xmit_frame(), and tx_init().

{
        struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;

        sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
        le->ctrl = 0;
        return le;
}
static void tx_init ( struct sky2_port sky2) [static]

Definition at line 877 of file sky2.c.

References sky2_tx_le::addr, get_tx_le(), HW_OWNER, OP_ADDR64, sky2_tx_le::opcode, sky2_port::tx_cons, and sky2_port::tx_prod.

Referenced by sky2_up().

{
        struct sky2_tx_le *le;

        sky2->tx_prod = sky2->tx_cons = 0;

        le = get_tx_le(sky2);
        le->addr = 0;
        le->opcode = OP_ADDR64 | HW_OWNER;
}
static struct tx_ring_info* tx_le_re ( struct sky2_port sky2,
struct sky2_tx_le le 
) [static, read]

Definition at line 888 of file sky2.c.

References sky2_port::tx_le, and sky2_port::tx_ring.

Referenced by sky2_xmit_frame().

{
        return sky2->tx_ring + (le - sky2->tx_le);
}
static void sky2_put_idx ( struct sky2_hw hw,
unsigned  q,
u16  idx 
) [inline, static]

Definition at line 895 of file sky2.c.

References DBGIO, PFX, PREF_UNIT_PUT_IDX, sky2_write16(), wmb, and Y2_QADDR.

Referenced by sky2_rx_update(), and sky2_xmit_frame().

{
        /* Make sure write' to descriptors are complete before we tell hardware */
        wmb();
        sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
        DBGIO(PFX "queue %#x idx <- %d\n", q, idx);
}
static struct sky2_rx_le* sky2_next_rx ( struct sky2_port sky2) [static, read]

Definition at line 904 of file sky2.c.

References sky2_rx_le::ctrl, RING_NEXT, sky2_port::rx_le, RX_LE_SIZE, and sky2_port::rx_put.

Referenced by rx_set_checksum(), and sky2_rx_add().

{
        struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;

        sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
        le->ctrl = 0;
        return le;
}
static void sky2_rx_add ( struct sky2_port sky2,
u8  op,
u32  map,
unsigned  len 
) [static]

Definition at line 914 of file sky2.c.

References sky2_rx_le::addr, cpu_to_le16, cpu_to_le32, HW_OWNER, sky2_rx_le::length, sky2_rx_le::opcode, and sky2_next_rx().

Referenced by sky2_rx_submit().

{
        struct sky2_rx_le *le;

        le = sky2_next_rx(sky2);
        le->addr = cpu_to_le32(map);
        le->length = cpu_to_le16(len);
        le->opcode = op | HW_OWNER;
}
static void sky2_rx_submit ( struct sky2_port sky2,
const struct rx_ring_info re 
) [static]

Definition at line 926 of file sky2.c.

References rx_ring_info::data_addr, OP_PACKET, sky2_port::rx_data_size, and sky2_rx_add().

Referenced by sky2_receive(), and sky2_rx_start().

{
        sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
}
static void sky2_rx_map_iob ( struct pci_device *pdev  __unused,
struct rx_ring_info re,
unsigned size  __unused 
) [static]

Definition at line 933 of file sky2.c.

References io_buffer::data, rx_ring_info::data_addr, rx_ring_info::iob, and virt_to_bus().

Referenced by receive_new(), and sky2_rx_start().

{
        struct io_buffer *iob = re->iob;
        re->data_addr = virt_to_bus(iob->data);
}
static void rx_set_checksum ( struct sky2_port sky2) [static]
static void sky2_rx_stop ( struct sky2_port sky2) [static]

Definition at line 966 of file sky2.c.

References BMU_FIFO_RST, BMU_RST_SET, DBG, sky2_port::hw, net_device::name, sky2_port::netdev, PFX, sky2_port::port, PREF_UNIT_CTRL, PREF_UNIT_RST_SET, Q_ADDR, Q_CSR, Q_RL, Q_RSL, RB_ADDR, RB_CTRL, RB_DIS_OP_MD, rxqaddr, sky2_read8(), sky2_write32(), sky2_write8(), wmb, and Y2_QADDR.

Referenced by sky2_down().

{
        struct sky2_hw *hw = sky2->hw;
        unsigned rxq = rxqaddr[sky2->port];
        int i;

        /* disable the RAM Buffer receive queue */
        sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);

        for (i = 0; i < 0xffff; i++)
                if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
                    == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
                        goto stopped;

        DBG(PFX "%s: receiver stop failed\n", sky2->netdev->name);
stopped:
        sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);

        /* reset the Rx prefetch unit */
        sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
        wmb();
}
static void sky2_rx_clean ( struct sky2_port sky2) [static]

Definition at line 990 of file sky2.c.

References free_iob(), rx_ring_info::iob, memset(), NULL, sky2_port::rx_le, RX_LE_BYTES, RX_PENDING, and sky2_port::rx_ring.

Referenced by sky2_down(), and sky2_rx_start().

{
        unsigned i;

        memset(sky2->rx_le, 0, RX_LE_BYTES);
        for (i = 0; i < RX_PENDING; i++) {
                struct rx_ring_info *re = sky2->rx_ring + i;

                if (re->iob) {
                        free_iob(re->iob);
                        re->iob = NULL;
                }
        }
}
static struct io_buffer* sky2_rx_alloc ( struct sky2_port sky2) [static, read]

Definition at line 1008 of file sky2.c.

References alloc_iob(), ETH_DATA_ALIGN, sky2_hw::flags, sky2_port::hw, iob_reserve, NULL, sky2_port::rx_data_size, and SKY2_HW_RAM_BUFFER.

Referenced by receive_new(), and sky2_rx_start().

{
        struct io_buffer *iob;

        iob = alloc_iob(sky2->rx_data_size + ETH_DATA_ALIGN);
        if (!iob)
                return NULL;

        /*
         * Cards with a RAM buffer hang in the rx FIFO if the
         * receive buffer isn't aligned to (Linux module comments say
         * 64 bytes, Linux module code says 8 bytes). Since io_buffers
         * are always 2kb-aligned under iPXE, just leave it be
         * without ETH_DATA_ALIGN in those cases.
         *
         * XXX This causes unaligned access to the IP header,
         * which is undesirable, but it's less undesirable than the
         * card hanging.
         */
        if (!(sky2->hw->flags & SKY2_HW_RAM_BUFFER)) {
                iob_reserve(iob, ETH_DATA_ALIGN);
        }

        return iob;
}
static void sky2_rx_update ( struct sky2_port sky2,
unsigned  rxq 
) [inline, static]

Definition at line 1034 of file sky2.c.

References sky2_port::hw, sky2_port::rx_put, and sky2_put_idx().

Referenced by sky2_rx_start(), and sky2_status_intr().

{
        sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
}
static int sky2_rx_start ( struct sky2_port sky2) [static]

Definition at line 1045 of file sky2.c.

References BMU_WM_PEX, sky2_hw::chip_id, CHIP_ID_YUKON_EC_U, sky2_hw::chip_rev, CHIP_REV_YU_EC_U_A1, CHIP_REV_YU_EC_U_B0, ENOMEM, ETH_FRAME_LEN, F_M_RX_RAM_DIS, sky2_hw::flags, sky2_port::hw, rx_ring_info::iob, PCI_CAP_ID_EXP, pci_find_capability(), sky2_hw::pdev, sky2_port::port, Q_ADDR, Q_TEST, Q_WM, sky2_port::rx_data_size, RX_GMF_CTRL_T, RX_GMF_TR_THR, sky2_port::rx_le_map, RX_LE_SIZE, sky2_port::rx_next, RX_PENDING, sky2_port::rx_put, sky2_port::rx_ring, rx_set_checksum(), RX_TRUNC_OFF, RX_TRUNC_ON, rxqaddr, size, SK_REG, SKY2_HW_NEW_LE, sky2_prefetch_init(), sky2_qset(), sky2_rx_alloc(), sky2_rx_clean(), sky2_rx_map_iob(), sky2_rx_submit(), sky2_rx_update(), sky2_write16(), and sky2_write32().

Referenced by sky2_up().

{
        struct sky2_hw *hw = sky2->hw;
        struct rx_ring_info *re;
        unsigned rxq = rxqaddr[sky2->port];
        unsigned i, size, thresh;

        sky2->rx_put = sky2->rx_next = 0;
        sky2_qset(hw, rxq);

        /* On PCI express lowering the watermark gives better performance */
        if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
                sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX);

        /* These chips have no ram buffer?
         * MAC Rx RAM Read is controlled by hardware */
        if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
            (hw->chip_rev == CHIP_REV_YU_EC_U_A1
             || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
                sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);

        sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);

        if (!(hw->flags & SKY2_HW_NEW_LE))
                rx_set_checksum(sky2);

        /* Space needed for frame data + headers rounded up */
        size = (ETH_FRAME_LEN + 8) & ~7;

        /* Stopping point for hardware truncation */
        thresh = (size - 8) / sizeof(u32);

        sky2->rx_data_size = size;

        /* Fill Rx ring */
        for (i = 0; i < RX_PENDING; i++) {
                re = sky2->rx_ring + i;

                re->iob = sky2_rx_alloc(sky2);
                if (!re->iob)
                        goto nomem;

                sky2_rx_map_iob(hw->pdev, re, sky2->rx_data_size);
                sky2_rx_submit(sky2, re);
        }

        /*
         * The receiver hangs if it receives frames larger than the
         * packet buffer. As a workaround, truncate oversize frames, but
         * the register is limited to 9 bits, so if you do frames > 2052
         * you better get the MTU right!
         */
        if (thresh > 0x1ff)
                sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
        else {
                sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh);
                sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
        }

        /* Tell chip about available buffers */
        sky2_rx_update(sky2, rxq);
        return 0;
nomem:
        sky2_rx_clean(sky2);
        return -ENOMEM;
}
static void sky2_free_rings ( struct sky2_port sky2) [static]

Definition at line 1113 of file sky2.c.

References free, free_dma(), NULL, sky2_port::rx_le, RX_LE_BYTES, sky2_port::rx_ring, sky2_port::tx_le, sky2_port::tx_ring, and TX_RING_SIZE.

Referenced by sky2_down(), and sky2_up().

{
        free_dma(sky2->rx_le, RX_LE_BYTES);
        free(sky2->rx_ring);

        free_dma(sky2->tx_le, TX_RING_SIZE * sizeof(struct sky2_tx_le));
        free(sky2->tx_ring);

        sky2->tx_le = NULL;
        sky2->rx_le = NULL;

        sky2->rx_ring = NULL;
        sky2->tx_ring = NULL;
}
static int sky2_up ( struct net_device dev) [static]

Definition at line 1129 of file sky2.c.

References B0_IMSK, B2_E_0, sky2_hw::chip_id, CHIP_ID_YUKON_EC_U, CHIP_ID_YUKON_EX, sky2_hw::chip_rev, CHIP_REV_YU_EC_U_A0, CHIP_REV_YU_EX_B0, DBG2, DBGIO, ECU_TXFF_LEV, ENOMEM, F_TX_CHK_AUTO_OFF, sky2_hw::flags, sky2_port::hw, malloc_dma(), memset(), net_device::name, netdev_link_down(), netdev_priv(), PFX, port, sky2_port::port, portirq_msk, Q_ADDR, Q_AL, Q_TEST, Q_XS1, Q_XS2, RB_ADDR, RB_CTRL, RB_RST_SET, sky2_port::rx_le, RX_LE_BYTES, sky2_port::rx_le_map, RX_PENDING, sky2_port::rx_ring, RX_RING_ALIGN, rxqaddr, sky2_free_rings(), SKY2_HW_RAM_BUFFER, sky2_mac_init(), sky2_prefetch_init(), sky2_qset(), sky2_ramset(), sky2_read32(), sky2_read8(), sky2_rx_start(), sky2_set_multicast(), sky2_write16(), sky2_write32(), sky2_write8(), sky2_hw::st_dma, sky2_hw::st_le, tx_init(), sky2_port::tx_le, sky2_port::tx_le_map, sky2_port::tx_ring, TX_RING_ALIGN, TX_RING_SIZE, txqaddr, virt_to_bus(), and zalloc().

{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u32 imask, ramsize;
        int err = -ENOMEM;

        netdev_link_down(dev);

        /* must be power of 2 */
        sky2->tx_le = malloc_dma(TX_RING_SIZE * sizeof(struct sky2_tx_le), TX_RING_ALIGN);
        sky2->tx_le_map = virt_to_bus(sky2->tx_le);
        if (!sky2->tx_le)
                goto err_out;
        memset(sky2->tx_le, 0, TX_RING_SIZE * sizeof(struct sky2_tx_le));

        sky2->tx_ring = zalloc(TX_RING_SIZE * sizeof(struct tx_ring_info));
        if (!sky2->tx_ring)
                goto err_out;

        tx_init(sky2);

        sky2->rx_le = malloc_dma(RX_LE_BYTES, RX_RING_ALIGN);
        sky2->rx_le_map = virt_to_bus(sky2->rx_le);
        if (!sky2->rx_le)
                goto err_out;
        memset(sky2->rx_le, 0, RX_LE_BYTES);

        sky2->rx_ring = zalloc(RX_PENDING * sizeof(struct rx_ring_info));
        if (!sky2->rx_ring)
                goto err_out;

        sky2_mac_init(hw, port);

        /* Register is number of 4K blocks on internal RAM buffer. */
        ramsize = sky2_read8(hw, B2_E_0) * 4;
        if (ramsize > 0) {
                u32 rxspace;

                hw->flags |= SKY2_HW_RAM_BUFFER;
                DBG2(PFX "%s: ram buffer %dK\n", dev->name, ramsize);
                if (ramsize < 16)
                        rxspace = ramsize / 2;
                else
                        rxspace = 8 + (2*(ramsize - 16))/3;

                sky2_ramset(hw, rxqaddr[port], 0, rxspace);
                sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);

                /* Make sure SyncQ is disabled */
                sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
                            RB_RST_SET);
        }

        sky2_qset(hw, txqaddr[port]);

        /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */
        if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
                sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);

        /* Set almost empty threshold */
        if (hw->chip_id == CHIP_ID_YUKON_EC_U
            && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
                sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);

        sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
                           TX_RING_SIZE - 1);

        err = sky2_rx_start(sky2);
        if (err)
                goto err_out;

        /* Enable interrupts from phy/mac for port */
        imask = sky2_read32(hw, B0_IMSK);
        imask |= portirq_msk[port];
        sky2_write32(hw, B0_IMSK, imask);

        DBGIO(PFX "%s: le bases: st %p [%x], rx %p [%x], tx %p [%x]\n",
              dev->name, hw->st_le, hw->st_dma, sky2->rx_le, sky2->rx_le_map,
              sky2->tx_le, sky2->tx_le_map);

        sky2_set_multicast(dev);
        return 0;

err_out:
        sky2_free_rings(sky2);
        return err;
}
static int tx_dist ( unsigned  tail,
unsigned  head 
) [inline, static]

Definition at line 1220 of file sky2.c.

References TX_RING_SIZE.

Referenced by tx_avail().

{
        return (head - tail) & (TX_RING_SIZE - 1);
}
static int tx_avail ( const struct sky2_port sky2) [inline, static]

Definition at line 1226 of file sky2.c.

References sky2_port::tx_cons, tx_dist(), TX_PENDING, and sky2_port::tx_prod.

Referenced by sky2_xmit_frame().

{
        return TX_PENDING - tx_dist(sky2->tx_cons, sky2->tx_prod);
}
static int sky2_xmit_frame ( struct net_device dev,
struct io_buffer iob 
) [static]

Definition at line 1238 of file sky2.c.

References sky2_tx_le::addr, cpu_to_le16, cpu_to_le32, ctrl, sky2_tx_le::ctrl, io_buffer::data, DBGIO, EBUSY, EOP, get_tx_le(), sky2_port::hw, HW_OWNER, tx_ring_info::iob, iob_len(), len, sky2_tx_le::length, net_device::name, netdev_priv(), NULL, OP_PACKET, sky2_tx_le::opcode, PFX, sky2_port::port, sky2_put_idx(), tx_avail(), tx_le_re(), sky2_port::tx_prod, txqaddr, and virt_to_bus().

{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
        struct sky2_tx_le *le = NULL;
        struct tx_ring_info *re;
        unsigned len;
        u32 mapping;
        u8 ctrl;

        if (tx_avail(sky2) < 1)
                return -EBUSY;

        len = iob_len(iob);
        mapping = virt_to_bus(iob->data);

        DBGIO(PFX "%s: tx queued, slot %d, len %d\n", dev->name,
              sky2->tx_prod, len);

        ctrl = 0;

        le = get_tx_le(sky2);
        le->addr = cpu_to_le32((u32) mapping);
        le->length = cpu_to_le16(len);
        le->ctrl = ctrl;
        le->opcode = (OP_PACKET | HW_OWNER);

        re = tx_le_re(sky2, le);
        re->iob = iob;

        le->ctrl |= EOP;

        sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);

        return 0;
}
static void sky2_tx_complete ( struct sky2_port sky2,
u16  done 
) [static]

Definition at line 1281 of file sky2.c.

References assert, sky2_tx_le::ctrl, DBGIO, net_device::dev, EOP, tx_ring_info::iob, mb(), net_device::name, sky2_port::netdev, netdev_tx_complete(), PFX, RING_NEXT, sky2_port::tx_cons, sky2_port::tx_le, sky2_port::tx_ring, and TX_RING_SIZE.

Referenced by sky2_tx_clean(), and sky2_tx_done().

{
        struct net_device *dev = sky2->netdev;
        unsigned idx;

        assert(done < TX_RING_SIZE);

        for (idx = sky2->tx_cons; idx != done;
             idx = RING_NEXT(idx, TX_RING_SIZE)) {
                struct sky2_tx_le *le = sky2->tx_le + idx;
                struct tx_ring_info *re = sky2->tx_ring + idx;

                if (le->ctrl & EOP) {
                        DBGIO(PFX "%s: tx done %d\n", dev->name, idx);
                        netdev_tx_complete(dev, re->iob);
                }
        }

        sky2->tx_cons = idx;
        mb();
}
static void sky2_tx_clean ( struct net_device dev) [static]

Definition at line 1304 of file sky2.c.

References netdev_priv(), sky2_tx_complete(), and sky2_port::tx_prod.

Referenced by sky2_down().

{
        struct sky2_port *sky2 = netdev_priv(dev);

        sky2_tx_complete(sky2, sky2->tx_prod);
}
static void sky2_down ( struct net_device dev) [static]

Definition at line 1312 of file sky2.c.

References B0_IMSK, B0_Y2LED, BMU_FIFO_RST, BMU_RST_SET, BMU_STOP, sky2_hw::chip_id, CHIP_ID_YUKON_XL, sky2_hw::chip_rev, ctrl, DBG2, sky2_hw::dev, GM_GP_CTRL, GM_GPCR_RX_ENA, GM_GPCR_TX_ENA, gma_read16(), gma_write16(), GMAC_CTRL, GMC_RST_SET, GMF_RST_SET, GPC_RST_SET, GPHY_CTRL, sky2_port::hw, LED_STAT_OFF, net_device::name, netdev_priv(), PFX, port, sky2_port::port, portirq_msk, PREF_UNIT_CTRL, PREF_UNIT_RST_SET, Q_ADDR, Q_CSR, RB_ADDR, RB_CTRL, RB_DIS_OP_MD, RB_RST_SET, RX_GMF_CTRL_T, SK_REG, sky2_free_rings(), sky2_gmac_reset(), sky2_phy_power_down(), sky2_read32(), sky2_rx_clean(), sky2_rx_stop(), sky2_tx_clean(), sky2_write16(), sky2_write32(), sky2_write8(), TX_GMF_CTRL_T, sky2_port::tx_le, TXA_CTRL, TXA_DIS_ALLOC, TXA_DIS_FSYNC, TXA_ITI_INI, TXA_LIM_INI, TXA_STOP_RC, txqaddr, and Y2_QADDR.

{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u16 ctrl;
        u32 imask;

        /* Never really got started! */
        if (!sky2->tx_le)
                return;

        DBG2(PFX "%s: disabling interface\n", dev->name);

        /* Disable port IRQ */
        imask = sky2_read32(hw, B0_IMSK);
        imask &= ~portirq_msk[port];
        sky2_write32(hw, B0_IMSK, imask);

        sky2_gmac_reset(hw, port);

        /* Stop transmitter */
        sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
        sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));

        sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
                     RB_RST_SET | RB_DIS_OP_MD);

        ctrl = gma_read16(hw, port, GM_GP_CTRL);
        ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
        gma_write16(hw, port, GM_GP_CTRL, ctrl);

        sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);

        /* Workaround shared GMAC reset */
        if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
              && port == 0 && hw->dev[1]))
                sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);

        /* Disable Force Sync bit and Enable Alloc bit */
        sky2_write8(hw, SK_REG(port, TXA_CTRL),
                    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);

        /* Stop Interval Timer and Limit Counter of Tx Arbiter */
        sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
        sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);

        /* Reset the PCI FIFO of the async Tx queue */
        sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
                     BMU_RST_SET | BMU_FIFO_RST);

        /* Reset the Tx prefetch units */
        sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
                     PREF_UNIT_RST_SET);

        sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);

        sky2_rx_stop(sky2);

        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
        sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);

        sky2_phy_power_down(hw, port);

        /* turn off LED's */
        sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);

        sky2_tx_clean(dev);
        sky2_rx_clean(sky2);

        sky2_free_rings(sky2);

        return;
}
static u16 sky2_phy_speed ( const struct sky2_hw hw,
u16  aux 
) [static]

Definition at line 1387 of file sky2.c.

References sky2_hw::flags, PHY_M_PS_SPEED_100, PHY_M_PS_SPEED_1000, PHY_M_PS_SPEED_MSK, SKY2_HW_FIBRE_PHY, SKY2_HW_GIGABIT, SPEED_10, SPEED_100, and SPEED_1000.

Referenced by sky2_autoneg_done(), and sky2_phy_intr().

{
        if (hw->flags & SKY2_HW_FIBRE_PHY)
                return SPEED_1000;

        if (!(hw->flags & SKY2_HW_GIGABIT)) {
                if (aux & PHY_M_PS_SPEED_100)
                        return SPEED_100;
                else
                        return SPEED_10;
        }

        switch (aux & PHY_M_PS_SPEED_MSK) {
        case PHY_M_PS_SPEED_1000:
                return SPEED_1000;
        case PHY_M_PS_SPEED_100:
                return SPEED_100;
        default:
                return SPEED_10;
        }
}
static void sky2_link_up ( struct sky2_port sky2) [static]

Definition at line 1409 of file sky2.c.

References DBG, sky2_port::duplex, DUPLEX_FULL, FC_BOTH, FC_NONE, FC_RX, FC_TX, sky2_port::flow_status, GM_GP_CTRL, GM_GPCR_RX_ENA, GM_GPCR_TX_ENA, gm_phy_write(), gma_read16(), gma_write16(), sky2_port::hw, LINKLED_BLINK_OFF, LINKLED_LINKSYNC_OFF, LINKLED_ON, LNK_LED_REG, net_device::name, sky2_port::netdev, netdev_link_up(), PFX, PHY_M_DEF_MSK, PHY_MARV_INT_MASK, port, sky2_port::port, reg, SK_REG, sky2_write8(), and sky2_port::speed.

Referenced by sky2_phy_intr().

{
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u16 reg;
        static const char *fc_name[] = {
                [FC_NONE]       = "none",
                [FC_TX]         = "tx",
                [FC_RX]         = "rx",
                [FC_BOTH]       = "both",
        };

        /* enable Rx/Tx */
        reg = gma_read16(hw, port, GM_GP_CTRL);
        reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
        gma_write16(hw, port, GM_GP_CTRL, reg);

        gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);

        netdev_link_up(sky2->netdev);

        /* Turn on link LED */
        sky2_write8(hw, SK_REG(port, LNK_LED_REG),
                    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);

        DBG(PFX "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
            sky2->netdev->name, sky2->speed,
            sky2->duplex == DUPLEX_FULL ? "full" : "half",
            fc_name[sky2->flow_status]);
}
static void sky2_link_down ( struct sky2_port sky2) [static]

Definition at line 1440 of file sky2.c.

References DBG, GM_GP_CTRL, GM_GPCR_RX_ENA, GM_GPCR_TX_ENA, gm_phy_write(), gma_read16(), gma_write16(), sky2_port::hw, LINKLED_OFF, LNK_LED_REG, net_device::name, sky2_port::netdev, netdev_link_down(), PFX, PHY_MARV_INT_MASK, port, sky2_port::port, reg, SK_REG, sky2_phy_init(), and sky2_write8().

Referenced by sky2_phy_intr().

{
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u16 reg;

        gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);

        reg = gma_read16(hw, port, GM_GP_CTRL);
        reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
        gma_write16(hw, port, GM_GP_CTRL, reg);

        netdev_link_down(sky2->netdev);

        /* Turn on link LED */
        sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);

        DBG(PFX "%s: Link is down.\n", sky2->netdev->name);

        sky2_phy_init(hw, port);
}
static int sky2_autoneg_done ( struct sky2_port sky2,
u16  aux 
) [static]

Definition at line 1462 of file sky2.c.

References ADVERTISE_PAUSE_ASYM, ADVERTISE_PAUSE_CAP, sky2_hw::chip_id, CHIP_ID_YUKON_EC_U, CHIP_ID_YUKON_EX, DBG, sky2_port::duplex, DUPLEX_FULL, DUPLEX_HALF, FC_BOTH, FC_NONE, FC_RX, FC_TX, sky2_port::flow_status, gm_phy_read(), GMAC_CTRL, GMC_PAUSE_OFF, GMC_PAUSE_ON, sky2_port::hw, LPA_PAUSE_ASYM, LPA_PAUSE_CAP, net_device::name, sky2_port::netdev, PFX, PHY_M_AN_RF, PHY_M_PS_FULL_DUP, PHY_M_PS_SPDUP_RES, PHY_MARV_AUNE_ADV, PHY_MARV_AUNE_LP, port, sky2_port::port, SK_REG, sky2_phy_speed(), sky2_write8(), sky2_port::speed, and SPEED_1000.

Referenced by sky2_phy_intr().

{
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u16 advert, lpa;

        advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
        lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
        if (lpa & PHY_M_AN_RF) {
                DBG(PFX "%s: remote fault\n", sky2->netdev->name);
                return -1;
        }

        if (!(aux & PHY_M_PS_SPDUP_RES)) {
                DBG(PFX "%s: speed/duplex mismatch\n", sky2->netdev->name);
                return -1;
        }

        sky2->speed = sky2_phy_speed(hw, aux);
        sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;

        /* Since the pause result bits seem to in different positions on
         * different chips. look at registers.
         */

        sky2->flow_status = FC_NONE;
        if (advert & ADVERTISE_PAUSE_CAP) {
                if (lpa & LPA_PAUSE_CAP)
                        sky2->flow_status = FC_BOTH;
                else if (advert & ADVERTISE_PAUSE_ASYM)
                        sky2->flow_status = FC_RX;
        } else if (advert & ADVERTISE_PAUSE_ASYM) {
                if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM))
                        sky2->flow_status = FC_TX;
        }

        if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
            && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
                sky2->flow_status = FC_NONE;

        if (sky2->flow_status & FC_TX)
                sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
        else
                sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);

        return 0;
}
static void sky2_phy_intr ( struct sky2_hw hw,
unsigned  port 
) [static]

Definition at line 1511 of file sky2.c.

References sky2_port::autoneg, AUTONEG_ENABLE, DBGIO, net_device::dev, sky2_hw::dev, sky2_port::duplex, DUPLEX_FULL, DUPLEX_HALF, gm_phy_read(), net_device::name, sky2_port::netdev, netdev_priv(), PFX, PHY_M_IS_AN_COMPL, PHY_M_IS_DUP_CHANGE, PHY_M_IS_LSP_CHANGE, PHY_M_IS_LST_CHANGE, PHY_M_PS_FULL_DUP, PHY_M_PS_LINK_UP, PHY_MARV_INT_STAT, PHY_MARV_PHY_STAT, port, sky2_autoneg_done(), sky2_link_down(), sky2_link_up(), sky2_phy_speed(), and sky2_port::speed.

Referenced by sky2_poll().

{
        struct net_device *dev = hw->dev[port];
        struct sky2_port *sky2 = netdev_priv(dev);
        u16 istatus, phystat;

        istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
        phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);

        DBGIO(PFX "%s: phy interrupt status 0x%x 0x%x\n",
              sky2->netdev->name, istatus, phystat);

        if (sky2->autoneg == AUTONEG_ENABLE && (istatus & PHY_M_IS_AN_COMPL)) {
                if (sky2_autoneg_done(sky2, phystat) == 0)
                        sky2_link_up(sky2);
                return;
        }

        if (istatus & PHY_M_IS_LSP_CHANGE)
                sky2->speed = sky2_phy_speed(hw, phystat);

        if (istatus & PHY_M_IS_DUP_CHANGE)
                sky2->duplex =
                    (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;

        if (istatus & PHY_M_IS_LST_CHANGE) {
                if (phystat & PHY_M_PS_LINK_UP)
                        sky2_link_up(sky2);
                else
                        sky2_link_down(sky2);
        }
}
static struct io_buffer* receive_new ( struct sky2_port sky2,
struct rx_ring_info re,
unsigned int  length 
) [static, read]

Definition at line 1545 of file sky2.c.

References sky2_port::hw, rx_ring_info::iob, iob_put, NULL, sky2_hw::pdev, sky2_port::rx_data_size, sky2_rx_alloc(), and sky2_rx_map_iob().

Referenced by sky2_receive().

{
        struct io_buffer *iob, *niob;
        unsigned hdr_space = sky2->rx_data_size;

        /* Don't be tricky about reusing pages (yet) */
        niob = sky2_rx_alloc(sky2);
        if (!niob)
                return NULL;

        iob = re->iob;

        re->iob = niob;
        sky2_rx_map_iob(sky2->hw->pdev, re, hdr_space);

        iob_put(iob, length);
        return iob;
}
static struct io_buffer* sky2_receive ( struct net_device dev,
u16  length,
u32  status 
) [static, read]

Definition at line 1570 of file sky2.c.

References sky2_hw::chip_id, CHIP_ID_YUKON_FE_P, sky2_hw::chip_rev, CHIP_REV_YU_FE2_A0, count, DBG2, DBGIO, EBUSY, EINVAL, EIO, error, GMR_FS_ANY_ERR, GMR_FS_LEN, GMR_FS_RX_FF_OV, GMR_FS_RX_OK, sky2_port::hw, net_device::name, netdev_priv(), netdev_rx_err(), NULL, PFX, receive_new(), sky2_port::rx_next, RX_PENDING, sky2_port::rx_ring, and sky2_rx_submit().

Referenced by sky2_status_intr().

{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
        struct io_buffer *iob = NULL;
        u16 count = (status & GMR_FS_LEN) >> 16;

        DBGIO(PFX "%s: rx slot %d status 0x%x len %d\n",
              dev->name, sky2->rx_next, status, length);

        sky2->rx_next = (sky2->rx_next + 1) % RX_PENDING;

        /* This chip has hardware problems that generates bogus status.
         * So do only marginal checking and expect higher level protocols
         * to handle crap frames.
         */
        if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
            sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 &&
            length == count)
                goto okay;

        if (status & GMR_FS_ANY_ERR)
                goto error;

        if (!(status & GMR_FS_RX_OK))
                goto resubmit;

        /* if length reported by DMA does not match PHY, packet was truncated */
        if (length != count)
                goto len_error;

okay:
        iob = receive_new(sky2, re, length);
resubmit:
        sky2_rx_submit(sky2, re);

        return iob;

len_error:
        /* Truncation of overlength packets
           causes PHY length to not match MAC length */
        DBG2(PFX "%s: rx length error: status %#x length %d\n",
             dev->name, status, length);

        /* Pass NULL as iob because we want to keep our iob in the
           ring for the next packet. */
        netdev_rx_err(dev, NULL, -EINVAL);
        goto resubmit;

error:
        if (status & GMR_FS_RX_FF_OV) {
                DBG2(PFX "%s: FIFO overflow error\n", dev->name);
                netdev_rx_err(dev, NULL, -EBUSY);
                goto resubmit;
        }

        DBG2(PFX "%s: rx error, status 0x%x length %d\n",
             dev->name, status, length);
        netdev_rx_err(dev, NULL, -EIO);

        goto resubmit;
}
static void sky2_tx_done ( struct net_device dev,
u16  last 
) [inline, static]

Definition at line 1635 of file sky2.c.

References netdev_priv(), and sky2_tx_complete().

Referenced by sky2_status_intr().

{
        struct sky2_port *sky2 = netdev_priv(dev);

        sky2_tx_complete(sky2, last);
}
static void sky2_status_intr ( struct sky2_hw hw,
u16  idx 
) [static]

Definition at line 1643 of file sky2.c.

References assert, sky2_status_le::css, CSS_LINK_BIT, DBG, DBG2, net_device::dev, sky2_hw::dev, ENOMEM, HW_OWNER, le16_to_cpu, le32_to_cpu, length, sky2_status_le::length, netdev_priv(), netdev_rx(), netdev_rx_err(), NULL, OP_RXCHKS, OP_RXSTAT, OP_TXINDEXLE, opcode, sky2_status_le::opcode, PFX, port, Q_R1, Q_R2, RING_NEXT, rmb, rx, SC_STAT_CLR_IRQ, sky2_receive(), sky2_rx_update(), sky2_tx_done(), sky2_write32(), sky2_hw::st_idx, sky2_hw::st_le, STAT_CTRL, status, sky2_status_le::status, STATUS_RING_SIZE, and TX_RING_SIZE.

Referenced by sky2_poll().

{
        unsigned rx[2] = { 0, 0 };

        rmb();
        do {
                struct sky2_status_le *le  = hw->st_le + hw->st_idx;
                unsigned port;
                struct net_device *dev;
                struct io_buffer *iob;
                u32 status;
                u16 length;
                u8 opcode = le->opcode;

                if (!(opcode & HW_OWNER))
                        break;

                port = le->css & CSS_LINK_BIT;
                dev = hw->dev[port];
                length = le16_to_cpu(le->length);
                status = le32_to_cpu(le->status);

                hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);

                le->opcode = 0;
                switch (opcode & ~HW_OWNER) {
                case OP_RXSTAT:
                        ++rx[port];
                        iob = sky2_receive(dev, length, status);
                        if (!iob) {
                                netdev_rx_err(dev, NULL, -ENOMEM);
                                break;
                        }

                        netdev_rx(dev, iob);
                        break;

                case OP_RXCHKS:
                        DBG2(PFX "status OP_RXCHKS but checksum offloading disabled\n");
                        break;

                case OP_TXINDEXLE:
                        /* TX index reports status for both ports */
                        assert(TX_RING_SIZE <= 0x1000);
                        sky2_tx_done(hw->dev[0], status & 0xfff);
                        if (hw->dev[1])
                                sky2_tx_done(hw->dev[1],
                                     ((status >> 24) & 0xff)
                                             | (u16)(length & 0xf) << 8);
                        break;

                default:
                        DBG(PFX "unknown status opcode 0x%x\n", opcode);
                }
        } while (hw->st_idx != idx);

        /* Fully processed status ring so clear irq */
        sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);

        if (rx[0])
                sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1);

        if (rx[1])
                sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2);
}
static void sky2_hw_error ( struct sky2_hw hw,
unsigned  port,
u32  status 
) [static]

Definition at line 1709 of file sky2.c.

References B3_RI_CTRL, BMU_CLR_IRQ_PAR, BMU_CLR_IRQ_TCP, DBG, DBGIO, net_device::dev, sky2_hw::dev, GMF_CLI_TX_PE, net_device::name, PFX, port, Q_ADDR, Q_CSR, RAM_BUFFER, RI_CLR_RD_PERR, RI_CLR_WR_PERR, rxqaddr, SK_REG, sky2_write16(), sky2_write32(), sky2_write8(), TX_GMF_CTRL_T, txqaddr, Y2_IS_PAR_MAC1, Y2_IS_PAR_RD1, Y2_IS_PAR_RX1, Y2_IS_PAR_WR1, and Y2_IS_TCP_TXA1.

Referenced by sky2_hw_intr().

{
        struct net_device *dev = hw->dev[port];

        DBGIO(PFX "%s: hw error interrupt status 0x%x\n", dev->name, status);

        if (status & Y2_IS_PAR_RD1) {
                DBG(PFX "%s: ram data read parity error\n", dev->name);
                /* Clear IRQ */
                sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
        }

        if (status & Y2_IS_PAR_WR1) {
                DBG(PFX "%s: ram data write parity error\n", dev->name);
                sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
        }

        if (status & Y2_IS_PAR_MAC1) {
                DBG(PFX "%s: MAC parity error\n", dev->name);
                sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
        }

        if (status & Y2_IS_PAR_RX1) {
                DBG(PFX "%s: RX parity error\n", dev->name);
                sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
        }

        if (status & Y2_IS_TCP_TXA1) {
                DBG(PFX "%s: TCP segmentation error\n", dev->name);
                sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
        }
}
static void sky2_hw_intr ( struct sky2_hw hw) [static]

Definition at line 1742 of file sky2.c.

References B0_HWE_IMSK, B0_HWE_ISRC, B2_TST_CTRL1, DBG, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ, PCI_ERR_UNCOR_STATUS, PCI_STATUS, PCI_STATUS_ERROR_BITS, PFX, sky2_hw_error(), sky2_pci_read16(), sky2_pci_write16(), sky2_read32(), sky2_write32(), sky2_write8(), status, TST_CFG_WRITE_OFF, TST_CFG_WRITE_ON, Y2_HWE_L1_MASK, Y2_IS_IRQ_STAT, Y2_IS_MST_ERR, Y2_IS_PCI_EXP, and Y2_IS_TIST_OV.

Referenced by sky2_err_intr().

{
        u32 status = sky2_read32(hw, B0_HWE_ISRC);
        u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);

        status &= hwmsk;

        if (status & Y2_IS_TIST_OV)
                sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);

        if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
                u16 pci_err;

                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                pci_err = sky2_pci_read16(hw, PCI_STATUS);
                DBG(PFX "PCI hardware error (0x%x)\n", pci_err);

                sky2_pci_write16(hw, PCI_STATUS,
                                 pci_err | PCI_STATUS_ERROR_BITS);
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        }

        if (status & Y2_IS_PCI_EXP) {
                /* PCI-Express uncorrectable Error occurred */
                u32 err;

                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
                sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
                             0xfffffffful);
                DBG(PFX "PCI-Express error (0x%x)\n", err);

                sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        }

        if (status & Y2_HWE_L1_MASK)
                sky2_hw_error(hw, 0, status);
        status >>= 8;
        if (status & Y2_HWE_L1_MASK)
                sky2_hw_error(hw, 1, status);
}
static void sky2_mac_intr ( struct sky2_hw hw,
unsigned  port 
) [static]
static void sky2_le_error ( struct sky2_hw hw,
unsigned  port,
u16  q,
unsigned ring_size  __unused 
) [static]

Definition at line 1808 of file sky2.c.

References BMU_CLR_IRQ_CHK, DBG, net_device::dev, sky2_hw::dev, net_device::name, netdev_priv(), PFX, port, PREF_UNIT_GET_IDX, PREF_UNIT_LAST_IDX, PREF_UNIT_PUT_IDX, Q_ADDR, Q_CSR, Q_R1, Q_R2, sky2_port::rx_le, sky2_port::rx_put, sky2_read16(), sky2_write32(), sky2_port::tx_le, sky2_port::tx_prod, and Y2_QADDR.

Referenced by sky2_err_intr().

{
        struct net_device *dev = hw->dev[port];
        struct sky2_port *sky2 = netdev_priv(dev);
        int idx;
        const u64 *le = (q == Q_R1 || q == Q_R2)
                ? (u64 *) sky2->rx_le : (u64 *) sky2->tx_le;

        idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
        DBG(PFX "%s: descriptor error q=%#x get=%d [%llx] last=%d put=%d should be %d\n",
            dev->name, (unsigned) q, idx, (unsigned long long) le[idx],
            (int) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_LAST_IDX)),
            (int) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)),
            le == (u64 *)sky2->rx_le? sky2->rx_put : sky2->tx_prod);

        sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
}
static void sky2_err_intr ( struct sky2_hw hw,
u32  status 
) [static]
static void sky2_poll ( struct net_device dev) [static]
static u32 sky2_mhz ( const struct sky2_hw hw) [static]

Definition at line 1885 of file sky2.c.

References sky2_hw::chip_id, CHIP_ID_YUKON_EC, CHIP_ID_YUKON_EC_U, CHIP_ID_YUKON_EX, CHIP_ID_YUKON_FE, CHIP_ID_YUKON_FE_P, CHIP_ID_YUKON_SUPR, CHIP_ID_YUKON_UL_2, CHIP_ID_YUKON_XL, DBG, and PFX.

Referenced by sky2_clk2us(), and sky2_us2clk().

{
        switch (hw->chip_id) {
        case CHIP_ID_YUKON_EC:
        case CHIP_ID_YUKON_EC_U:
        case CHIP_ID_YUKON_EX:
        case CHIP_ID_YUKON_SUPR:
        case CHIP_ID_YUKON_UL_2:
                return 125;

        case CHIP_ID_YUKON_FE:
                return 100;

        case CHIP_ID_YUKON_FE_P:
                return 50;

        case CHIP_ID_YUKON_XL:
                return 156;

        default:
                DBG(PFX "unknown chip ID!\n");
                return 100;     /* bogus */
        }
}
static u32 sky2_us2clk ( const struct sky2_hw hw,
u32  us 
) [inline, static]

Definition at line 1910 of file sky2.c.

References sky2_mhz().

Referenced by sky2_reset().

{
        return sky2_mhz(hw) * us;
}
static u32 sky2_clk2us ( const struct sky2_hw hw,
u32  clk 
) [inline, static]

Definition at line 1915 of file sky2.c.

References sky2_mhz().

{
        return clk / sky2_mhz(hw);
}
static int sky2_init ( struct sky2_hw hw) [static]

Definition at line 1920 of file sky2.c.

References B0_CTST, B2_CHIP_ID, B2_MAC_CFG, B2_PMD_TYP, B2_Y2_CLK_GATE, B2_Y2_HW_RES, CFG_CHIP_R_MSK, CFG_DUAL_MAC_MSK, sky2_hw::chip_id, CHIP_ID_YUKON_EC, CHIP_ID_YUKON_EC_U, CHIP_ID_YUKON_EX, CHIP_ID_YUKON_FE, CHIP_ID_YUKON_FE_P, CHIP_ID_YUKON_SUPR, CHIP_ID_YUKON_UL_2, CHIP_ID_YUKON_XL, sky2_hw::chip_rev, CHIP_REV_YU_EC_A1, CS_RST_CLR, DBG, EOPNOTSUPP, sky2_hw::flags, PCI_DEV_REG3, PFX, sky2_hw::pmd_type, sky2_hw::ports, SKY2_HW_ADV_POWER_CTL, SKY2_HW_AUTO_TX_SUM, SKY2_HW_FIBRE_PHY, SKY2_HW_GIGABIT, SKY2_HW_NEW_LE, SKY2_HW_NEWER_PHY, sky2_pci_write32(), sky2_read8(), sky2_write8(), and Y2_STATUS_LNK2_INAC.

Referenced by sky2_probe().

{
        u8 t8;

        /* Enable all clocks and check for bad PCI access */
        sky2_pci_write32(hw, PCI_DEV_REG3, 0);

        sky2_write8(hw, B0_CTST, CS_RST_CLR);

        hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
        hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;

        switch(hw->chip_id) {
        case CHIP_ID_YUKON_XL:
                hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY;
                break;

        case CHIP_ID_YUKON_EC_U:
                hw->flags = SKY2_HW_GIGABIT
                        | SKY2_HW_NEWER_PHY
                        | SKY2_HW_ADV_POWER_CTL;
                break;

        case CHIP_ID_YUKON_EX:
                hw->flags = SKY2_HW_GIGABIT
                        | SKY2_HW_NEWER_PHY
                        | SKY2_HW_NEW_LE
                        | SKY2_HW_ADV_POWER_CTL;
                break;

        case CHIP_ID_YUKON_EC:
                /* This rev is really old, and requires untested workarounds */
                if (hw->chip_rev == CHIP_REV_YU_EC_A1) {
                        DBG(PFX "unsupported revision Yukon-EC rev A1\n");
                        return -EOPNOTSUPP;
                }
                hw->flags = SKY2_HW_GIGABIT;
                break;

        case CHIP_ID_YUKON_FE:
                break;

        case CHIP_ID_YUKON_FE_P:
                hw->flags = SKY2_HW_NEWER_PHY
                        | SKY2_HW_NEW_LE
                        | SKY2_HW_AUTO_TX_SUM
                        | SKY2_HW_ADV_POWER_CTL;
                break;

        case CHIP_ID_YUKON_SUPR:
                hw->flags = SKY2_HW_GIGABIT
                        | SKY2_HW_NEWER_PHY
                        | SKY2_HW_NEW_LE
                        | SKY2_HW_AUTO_TX_SUM
                        | SKY2_HW_ADV_POWER_CTL;
                break;

        case CHIP_ID_YUKON_UL_2:
                hw->flags = SKY2_HW_GIGABIT
                        | SKY2_HW_ADV_POWER_CTL;
                break;

        default:
                DBG(PFX "unsupported chip type 0x%x\n", hw->chip_id);
                return -EOPNOTSUPP;
        }

        hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
        if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
                hw->flags |= SKY2_HW_FIBRE_PHY;

        hw->ports = 1;
        t8 = sky2_read8(hw, B2_Y2_HW_RES);
        if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
                if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
                        ++hw->ports;
        }

        return 0;
}
static void sky2_reset ( struct sky2_hw hw) [static]

Definition at line 2001 of file sky2.c.

References B0_CTST, B0_HWE_IMSK, B0_HWE_ISRC, B0_Y2LED, B28_DPT_CTRL, B28_Y2_ASF_STAT_CMD, B2_I2C_IRQ, B2_TI_CTRL, B2_TST_CTRL1, B3_RI_CTRL, B3_RI_RTO_R1, B3_RI_RTO_R2, B3_RI_RTO_XA1, B3_RI_RTO_XA2, B3_RI_RTO_XS1, B3_RI_RTO_XS2, B3_RI_WTO_R1, B3_RI_WTO_R2, B3_RI_WTO_XA1, B3_RI_WTO_XA2, B3_RI_WTO_XS1, B3_RI_WTO_XS2, sky2_hw::chip_id, CHIP_ID_YUKON_EX, CHIP_ID_YUKON_SUPR, CHIP_ID_YUKON_XL, sky2_hw::chip_rev, CS_MRST_CLR, CS_RST_CLR, CS_RST_SET, DBG, DPT_STOP, GMAC_CTRL, GMAC_LINK_CTRL, GMAC_TI_ST_CTRL, GMC_BYP_MACSECRX_ON, GMC_BYP_MACSECTX_ON, GMC_BYP_RETR_ON, GMLC_RST_CLR, GMLC_RST_SET, GMT_ST_CLR_IRQ, GMT_ST_STOP, HCU_CCSR, HCU_CCSR_AHB_RST, HCU_CCSR_CPU_RST_MODE, HCU_CCSR_UC_STATE_MSK, LED_STAT_ON, memset(), PCI_CAP_ID_EXP, PCI_ERR_UNCOR_STATUS, pci_find_capability(), PCI_STATUS, PCI_STATUS_ERROR_BITS, sky2_hw::pdev, PFX, sky2_hw::ports, RAM_BUFFER, RI_RST_CLR, SC_STAT_OP_ON, SC_STAT_RST_CLR, SC_STAT_RST_SET, SK_REG, SK_RI_TO_53, sky2_gmac_reset(), sky2_pci_read16(), sky2_pci_write16(), sky2_power_on(), sky2_read16(), sky2_read32(), sky2_us2clk(), sky2_write16(), sky2_write32(), sky2_write8(), sky2_hw::st_dma, sky2_hw::st_idx, sky2_hw::st_le, STAT_CTRL, STAT_FIFO_ISR_WM, STAT_FIFO_WM, STAT_ISR_TIMER_CTRL, STAT_ISR_TIMER_INI, STAT_LAST_IDX, STAT_LEV_TIMER_CTRL, STAT_LEV_TIMER_INI, STAT_LIST_ADDR_HI, STAT_LIST_ADDR_LO, STAT_TX_IDX_TH, STAT_TX_TIMER_CTRL, STAT_TX_TIMER_INI, status, STATUS_LE_BYTES, STATUS_RING_SIZE, TIM_CLR_IRQ, TIM_START, TIM_STOP, TST_CFG_WRITE_OFF, TST_CFG_WRITE_ON, TXA_CTRL, TXA_ENA_ARB, Y2_ASF_DISABLE, Y2_ASF_RESET, Y2_HWE_ALL_MASK, and Y2_IS_PCI_EXP.

Referenced by sky2_probe().

{
        u16 status;
        int i, cap;
        u32 hwe_mask = Y2_HWE_ALL_MASK;

        /* disable ASF */
        if (hw->chip_id == CHIP_ID_YUKON_EX) {
                status = sky2_read16(hw, HCU_CCSR);
                status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
                            HCU_CCSR_UC_STATE_MSK);
                sky2_write16(hw, HCU_CCSR, status);
        } else
                sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
        sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);

        /* do a SW reset */
        sky2_write8(hw, B0_CTST, CS_RST_SET);
        sky2_write8(hw, B0_CTST, CS_RST_CLR);

        /* allow writes to PCI config */
        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);

        /* clear PCI errors, if any */
        status = sky2_pci_read16(hw, PCI_STATUS);
        status |= PCI_STATUS_ERROR_BITS;
        sky2_pci_write16(hw, PCI_STATUS, status);

        sky2_write8(hw, B0_CTST, CS_MRST_CLR);

        cap = pci_find_capability(hw->pdev, PCI_CAP_ID_EXP);
        if (cap) {
                sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
                             0xfffffffful);

                /* If an error bit is stuck on ignore it */
                if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
                        DBG(PFX "ignoring stuck error report bit\n");
                else
                        hwe_mask |= Y2_IS_PCI_EXP;
        }

        sky2_power_on(hw);
        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);

        for (i = 0; i < hw->ports; i++) {
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);

                if (hw->chip_id == CHIP_ID_YUKON_EX ||
                    hw->chip_id == CHIP_ID_YUKON_SUPR)
                        sky2_write16(hw, SK_REG(i, GMAC_CTRL),
                                     GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
                                     | GMC_BYP_RETR_ON);
        }

        /* Clear I2C IRQ noise */
        sky2_write32(hw, B2_I2C_IRQ, 1);

        /* turn off hardware timer (unused) */
        sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
        sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);

        sky2_write8(hw, B0_Y2LED, LED_STAT_ON);

        /* Turn off descriptor polling */
        sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);

        /* Turn off receive timestamp */
        sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
        sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);

        /* enable the Tx Arbiters */
        for (i = 0; i < hw->ports; i++)
                sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);

        /* Initialize ram interface */
        for (i = 0; i < hw->ports; i++) {
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);

                sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
        }

        sky2_write32(hw, B0_HWE_IMSK, hwe_mask);

        for (i = 0; i < hw->ports; i++)
                sky2_gmac_reset(hw, i);

        memset(hw->st_le, 0, STATUS_LE_BYTES);
        hw->st_idx = 0;

        sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
        sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);

        sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
        sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);

        /* Set the list last index */
        sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);

        sky2_write16(hw, STAT_TX_IDX_TH, 10);
        sky2_write8(hw, STAT_FIFO_WM, 16);

        /* set Status-FIFO ISR watermark */
        if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
                sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
        else
                sky2_write8(hw, STAT_FIFO_ISR_WM, 16);

        sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
        sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
        sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));

        /* enable status unit */
        sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);

        sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
        sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
        sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
}
static u32 sky2_supported_modes ( const struct sky2_hw hw) [static]
static struct net_device* sky2_init_netdev ( struct sky2_hw hw,
unsigned  port 
) [static, read]

Definition at line 2179 of file sky2.c.

References sky2_port::advertising, alloc_etherdev(), sky2_port::autoneg, AUTONEG_ENABLE, B2_MAC_1, DBG, pci_device::dev, net_device::dev, sky2_hw::dev, sky2_port::duplex, ETH_ALEN, FC_BOTH, sky2_port::flow_mode, sky2_port::hw, net_device::hw_addr, memcpy(), sky2_port::netdev, netdev_priv(), NULL, sky2_hw::pdev, PFX, port, sky2_port::port, sky2_hw::regs, sky2_supported_modes(), and sky2_port::speed.

Referenced by sky2_probe().

{
        struct sky2_port *sky2;
        struct net_device *dev = alloc_etherdev(sizeof(*sky2));

        if (!dev) {
                DBG(PFX "etherdev alloc failed\n");
                return NULL;
        }

        dev->dev = &hw->pdev->dev;

        sky2 = netdev_priv(dev);
        sky2->netdev = dev;
        sky2->hw = hw;

        /* Auto speed and flow control */
        sky2->autoneg = AUTONEG_ENABLE;
        sky2->flow_mode = FC_BOTH;

        sky2->duplex = -1;
        sky2->speed = -1;
        sky2->advertising = sky2_supported_modes(hw);

        hw->dev[port] = dev;

        sky2->port = port;

        /* read the mac address */
        memcpy(dev->hw_addr, (void *)(hw->regs + B2_MAC_1 + port * 8), ETH_ALEN);

        return dev;
}
static void sky2_show_addr ( struct net_device dev) [static]

Definition at line 2214 of file sky2.c.

References DBG2, net_device::name, netdev_addr(), and PFX.

Referenced by sky2_probe().

{
        DBG2(PFX "%s: addr %s\n", dev->name, netdev_addr(dev));
}
static void sky2_net_irq ( struct net_device dev,
int  enable 
) [static]

Definition at line 2242 of file sky2.c.

References B0_IMSK, sky2_port::hw, netdev_priv(), sky2_port::port, portirq_msk, sky2_read32(), and sky2_write32().

{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;

        u32 imask = sky2_read32(hw, B0_IMSK);
        if (enable)
                imask |= portirq_msk[sky2->port];
        else
                imask &= ~portirq_msk[sky2->port];
        sky2_write32(hw, B0_IMSK, imask);
}
static int sky2_probe ( struct pci_device pdev) [static]

Definition at line 2263 of file sky2.c.

References __unused, adjust_pci_device(), B0_CTST, B0_IMSK, sky2_hw::chip_id, sky2_hw::chip_rev, CS_RST_SET, DBG, DBG2, net_device::dev, sky2_hw::dev, ENOMEM, free, free_dma(), ioremap(), iounmap(), malloc_dma(), memset(), netdev_init(), netdev_nullify(), netdev_put(), NULL, pci_bar_start(), PCI_BASE_ADDRESS_0, pci_set_drvdata(), sky2_hw::pdev, PFX, sky2_hw::ports, register_netdev(), sky2_hw::regs, sky2_init(), sky2_init_netdev(), sky2_reset(), sky2_show_addr(), sky2_write32(), sky2_write8(), sky2_hw::st_dma, sky2_hw::st_le, STATUS_LE_BYTES, STATUS_RING_ALIGN, virt_to_bus(), Y2_IS_BASE, and zalloc().

{
        struct net_device *dev;
        struct sky2_hw *hw;
        int err;
        char buf1[16] __unused; /* only for debugging */

        adjust_pci_device(pdev);

        err = -ENOMEM;
        hw = zalloc(sizeof(*hw));
        if (!hw) {
                DBG(PFX "cannot allocate hardware struct\n");
                goto err_out;
        }

        hw->pdev = pdev;

        hw->regs = (unsigned long)ioremap(pci_bar_start(pdev, PCI_BASE_ADDRESS_0), 0x4000);
        if (!hw->regs) {
                DBG(PFX "cannot map device registers\n");
                goto err_out_free_hw;
        }

        /* ring for status responses */
        hw->st_le = malloc_dma(STATUS_LE_BYTES, STATUS_RING_ALIGN);
        if (!hw->st_le)
                goto err_out_iounmap;
        hw->st_dma = virt_to_bus(hw->st_le);
        memset(hw->st_le, 0, STATUS_LE_BYTES);

        err = sky2_init(hw);
        if (err)
                goto err_out_iounmap;

#if DBGLVL_MAX
        DBG2(PFX "Yukon-2 %s chip revision %d\n",
             sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
#endif

        sky2_reset(hw);

        dev = sky2_init_netdev(hw, 0);
        if (!dev) {
                err = -ENOMEM;
                goto err_out_free_pci;
        }

        netdev_init(dev, &sky2_operations);

        err = register_netdev(dev);
        if (err) {
                DBG(PFX "cannot register net device\n");
                goto err_out_free_netdev;
        }

        sky2_write32(hw, B0_IMSK, Y2_IS_BASE);

        sky2_show_addr(dev);

        if (hw->ports > 1) {
                struct net_device *dev1;

                dev1 = sky2_init_netdev(hw, 1);
                if (!dev1)
                        DBG(PFX "allocation for second device failed\n");
                else if ((err = register_netdev(dev1))) {
                        DBG(PFX "register of second port failed (%d)\n", err);
                        hw->dev[1] = NULL;
                        netdev_nullify(dev1);
                        netdev_put(dev1);
                } else
                        sky2_show_addr(dev1);
        }

        pci_set_drvdata(pdev, hw);

        return 0;

err_out_free_netdev:
        netdev_nullify(dev);
        netdev_put(dev);
err_out_free_pci:
        sky2_write8(hw, B0_CTST, CS_RST_SET);
        free_dma(hw->st_le, STATUS_LE_BYTES);
err_out_iounmap:
        iounmap((void *)hw->regs);
err_out_free_hw:
        free(hw);
err_out:
        pci_set_drvdata(pdev, NULL);
        return err;
}
static void sky2_remove ( struct pci_device pdev) [static]

Variable Documentation

struct pci_device_id sky2_id_table[] [static]

Definition at line 81 of file sky2.c.

const unsigned txqaddr[] = { Q_XA1, Q_XA2 } [static]

Definition at line 124 of file sky2.c.

Referenced by sky2_down(), sky2_hw_error(), sky2_up(), and sky2_xmit_frame().

const unsigned rxqaddr[] = { Q_R1, Q_R2 } [static]

Definition at line 125 of file sky2.c.

Referenced by rx_set_checksum(), sky2_hw_error(), sky2_rx_start(), sky2_rx_stop(), and sky2_up().

const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 } [static]

Definition at line 126 of file sky2.c.

Referenced by sky2_down(), sky2_net_irq(), and sky2_up().

const u16 copper_fc_adv[] [static]
Initial value:

Definition at line 273 of file sky2.c.

Referenced by sky2_phy_init().

const u16 fiber_fc_adv[] [static]
Initial value:

Definition at line 281 of file sky2.c.

Referenced by sky2_phy_init().

const u16 gm_fc_disable[] [static]
Initial value:

Definition at line 289 of file sky2.c.

Referenced by sky2_phy_init().

Definition at line 592 of file sky2.c.

Referenced by sky2_phy_power_down(), and sky2_phy_power_up().

Definition at line 593 of file sky2.c.

Referenced by sky2_phy_power_up().

Initial value:
 {
        .open     = sky2_up,
        .close    = sky2_down,
        .transmit = sky2_xmit_frame,
        .poll     = sky2_poll,
        .irq      = sky2_net_irq
}

Definition at line 2255 of file sky2.c.

struct pci_driver sky2_driver __pci_driver
Initial value:
 {
        .ids      = sky2_id_table,
        .id_count = (sizeof (sky2_id_table) / sizeof (sky2_id_table[0])),
        .probe    = sky2_probe,
        .remove   = sky2_remove
}

Definition at line 2389 of file sky2.c.