static void xgene_sgmac_init(struct xgene_enet_pdata *p) { u32 data, loop = 10; xgene_sgmac_reset(p); /* Enable auto-negotiation */ xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x1000); xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0); while (loop--) { data = xgene_mii_phy_read(p, INT_PHY_ADDR, SGMII_STATUS_ADDR >> 2); if ((data & AUTO_NEG_COMPLETE) && (data & LINK_STATUS)) break; usleep_range(10, 20); } if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS)) netdev_err(p->ndev, "Auto-negotiation failed\n"); data = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR); ENET_INTERFACE_MODE2_SET(&data, 2); xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2); xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE); data = xgene_enet_rd_csr(p, ENET_SPARE_CFG_REG_ADDR); data |= MPA_IDLE_WITH_QMI_EMPTY; xgene_enet_wr_csr(p, ENET_SPARE_CFG_REG_ADDR, data); xgene_sgmac_set_mac_addr(p); data = xgene_enet_rd_csr(p, DEBUG_REG_ADDR); data |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; xgene_enet_wr_csr(p, DEBUG_REG_ADDR, data); /* Adjust MDC clock frequency */ data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR); MGMT_CLOCK_SEL_SET(&data, 7); xgene_enet_wr_mac(p, MII_MGMT_CONFIG_ADDR, data); /* Enable drop if bufpool not available */ data = xgene_enet_rd_csr(p, RSIF_CONFIG_REG_ADDR); data |= CFG_RSIF_FPBUFF_TIMEOUT_EN; xgene_enet_wr_csr(p, RSIF_CONFIG_REG_ADDR, data); /* Rtype should be copied from FP */ xgene_enet_wr_csr(p, RSIF_RAM_DBG_REG0_ADDR, 0); /* Bypass traffic gating */ xgene_enet_wr_csr(p, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); xgene_enet_wr_csr(p, CFG_BYPASS_ADDR, RESUME_TX); xgene_enet_wr_csr(p, SG_RX_DV_GATE_REG_0_ADDR, RESUME_RX0); }
static void xgene_gport_reset(struct xgene_enet_priv *priv) { u32 val; xgene_enet_clkrst_cfg(priv); xgene_enet_config_qmi_assoc(priv); /* Enable auto-incr for scanning */ xgene_enet_rd(priv, BLOCK_MCX_MAC, MII_MGMT_CONFIG_ADDR, &val); val |= SCAN_AUTO_INCR_MASK; val = MGMT_CLOCK_SEL_SET(val, 1); xgene_enet_wr(priv, BLOCK_MCX_MAC, MII_MGMT_CONFIG_ADDR, val); xgene_gmac_phy_enable_scan_cycle(priv, 1); }
static void xgene_sgmac_init(struct xgene_enet_pdata *p) { u32 data, loop = 10; u32 offset = p->port_id * 4; u32 enet_spare_cfg_reg, rsif_config_reg; u32 cfg_bypass_reg, rx_dv_gate_reg; xgene_sgmac_reset(p); /* Enable auto-negotiation */ xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x1000); xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0); while (loop--) { data = xgene_mii_phy_read(p, INT_PHY_ADDR, SGMII_STATUS_ADDR >> 2); if ((data & AUTO_NEG_COMPLETE) && (data & LINK_STATUS)) break; usleep_range(1000, 2000); } if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS)) netdev_err(p->ndev, "Auto-negotiation failed\n"); data = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR); ENET_INTERFACE_MODE2_SET(&data, 2); xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2); xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE); if (p->enet_id == XGENE_ENET1) { enet_spare_cfg_reg = ENET_SPARE_CFG_REG_ADDR; rsif_config_reg = RSIF_CONFIG_REG_ADDR; cfg_bypass_reg = CFG_BYPASS_ADDR; rx_dv_gate_reg = SG_RX_DV_GATE_REG_0_ADDR; } else { enet_spare_cfg_reg = XG_ENET_SPARE_CFG_REG_ADDR; rsif_config_reg = XG_RSIF_CONFIG_REG_ADDR; cfg_bypass_reg = XG_CFG_BYPASS_ADDR; rx_dv_gate_reg = XG_MCX_RX_DV_GATE_REG_0_ADDR; } data = xgene_enet_rd_csr(p, enet_spare_cfg_reg); data |= MPA_IDLE_WITH_QMI_EMPTY; xgene_enet_wr_csr(p, enet_spare_cfg_reg, data); xgene_sgmac_set_mac_addr(p); /* Adjust MDC clock frequency */ data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR); MGMT_CLOCK_SEL_SET(&data, 7); xgene_enet_wr_mac(p, MII_MGMT_CONFIG_ADDR, data); /* Enable drop if bufpool not available */ data = xgene_enet_rd_csr(p, rsif_config_reg); data |= CFG_RSIF_FPBUFF_TIMEOUT_EN; xgene_enet_wr_csr(p, rsif_config_reg, data); /* Bypass traffic gating */ xgene_enet_wr_csr(p, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x84); xgene_enet_wr_csr(p, cfg_bypass_reg, RESUME_TX); xgene_enet_wr_mcx_csr(p, rx_dv_gate_reg + offset, RESUME_RX0); }
int xgene_gmac_init(struct xgene_enet_priv *priv, unsigned char *dev_addr, int speed, int mtu, int crc) { u32 value, temp; u32 addr_hi, addr_lo; u32 interface_control; u32 mac_config_2; u32 rgmii; u32 icm_config0 = 0x0008503f; u32 icm_config2 = 0x0010000f; u32 ecm_config0 = 0x00000032; u32 enet_spare_cfg = 0x00006040; /* Reset subsystem */ value = RESET_TX_FUN1_WR(1) | RESET_RX_FUN1_WR(1) | RESET_TX_MC1_WR(1) | RESET_RX_MC1_WR(1) | SIM_RESET1_WR(1) | SOFT_RESET1_WR(1); xgene_enet_wr(priv, BLOCK_MCX_MAC, MAC_CONFIG_1_ADDR, value); xgene_enet_rd(priv, BLOCK_MCX_MAC, MAC_CONFIG_1_ADDR, &temp); xgene_enet_wr(priv, BLOCK_MCX_MAC, MAC_CONFIG_1_ADDR, 0); xgene_enet_rd(priv, BLOCK_MCX_MAC, MAC_CONFIG_1_ADDR, &temp); value = TX_EN1_WR(1) | RX_EN1_WR(1) | TX_FLOW_EN1_WR(0) | LOOP_BACK1_WR(0) | RX_FLOW_EN1_WR(0); xgene_enet_wr(priv, BLOCK_MCX_MAC, MAC_CONFIG_1_ADDR, value); xgene_enet_rd(priv, BLOCK_ETH_CSR, ENET_SPARE_CFG_REG_ADDR, &enet_spare_cfg); if (speed == XGENE_ENET_SPEED_10) { interface_control = ENET_LHD_MODE_WR(0) | ENET_GHD_MODE_WR(0); mac_config_2 = FULL_DUPLEX2_WR(1) | LENGTH_CHECK2_WR(0) | HUGE_FRAME_EN2_WR(0) | ENET_INTERFACE_MODE2_WR(1) /* 10Mbps */ |PAD_CRC2_WR(crc) | CRC_EN2_WR(crc) | PREAMBLE_LENGTH2_WR(7); rgmii = 0; icm_config0 = 0x0000503f; icm_config2 = 0x000101f4; ecm_config0 = 0x600032; enet_spare_cfg = enet_spare_cfg | (0x0000c040); } else if (speed == XGENE_ENET_SPEED_100) { interface_control = ENET_LHD_MODE_WR(1); mac_config_2 = FULL_DUPLEX2_WR(1) | LENGTH_CHECK2_WR(0) | HUGE_FRAME_EN2_WR(0) | ENET_INTERFACE_MODE2_WR(1) /* 100Mbps */ |PAD_CRC2_WR(crc) | CRC_EN2_WR(crc) | PREAMBLE_LENGTH2_WR(7); rgmii = 0; icm_config0 = 0x0004503f; icm_config2 = 0x00010050; ecm_config0 = 0x600032; enet_spare_cfg = enet_spare_cfg | (0x0000c040); } else { interface_control = ENET_GHD_MODE_WR(1); mac_config_2 = FULL_DUPLEX2_WR(1) | LENGTH_CHECK2_WR(0) | HUGE_FRAME_EN2_WR(0) | ENET_INTERFACE_MODE2_WR(2) /* 1Gbps */ |PAD_CRC2_WR(crc) | CRC_EN2_WR(crc) | PREAMBLE_LENGTH2_WR(7); rgmii = CFG_SPEED_1250_WR(1) | CFG_TXCLK_MUXSEL0_WR(4); icm_config0 = 0x0008503f; icm_config2 = 0x0001000f; ecm_config0 = 0x32; enet_spare_cfg = (enet_spare_cfg & ~0x0000c000) | (0x00000040); } enet_spare_cfg |= 0x00006040; xgene_enet_wr(priv, BLOCK_MCX_MAC, MAC_CONFIG_2_ADDR, mac_config_2); xgene_enet_wr(priv, BLOCK_MCX_MAC, INTERFACE_CONTROL_ADDR, interface_control); value = MAX_FRAME_LEN_WR(0x0600); xgene_enet_wr(priv, BLOCK_MCX_MAC, MAX_FRAME_LEN_ADDR, value); /* Program the station MAC address */ addr_hi = *(u32 *) &dev_addr[0]; addr_lo = *(u16 *) &dev_addr[4]; addr_lo <<= 16; addr_lo |= (priv->phy_addr & 0xFFFF); xgene_enet_wr(priv, BLOCK_MCX_MAC, STATION_ADDR0_ADDR, addr_hi); xgene_enet_wr(priv, BLOCK_MCX_MAC, STATION_ADDR1_ADDR, addr_lo); /* Adjust MDC clock frequency */ xgene_enet_rd(priv, BLOCK_MCX_MAC, MII_MGMT_CONFIG_ADDR, &value); value = MGMT_CLOCK_SEL_SET(value, 7); xgene_enet_wr(priv, BLOCK_MCX_MAC, MII_MGMT_CONFIG_ADDR, value); /* Enable drop if FP not available */ xgene_enet_rd(priv, BLOCK_ETH_CSR, RSIF_CONFIG_REG_ADDR, &value); value |= CFG_RSIF_FPBUFF_TIMEOUT_EN_WR(1); xgene_enet_wr(priv, BLOCK_ETH_CSR, RSIF_CONFIG_REG_ADDR, value); /* Rtype should be copied from FP */ value = 0; xgene_enet_wr(priv, BLOCK_ETH_CSR, RSIF_RAM_DBG_REG0_ADDR, value); /* Initialize RGMII PHY */ if (priv->phy_mode == PHY_MODE_RGMII) xgene_enet_wr(priv, BLOCK_ETH_CSR, RGMII_REG_0_ADDR, rgmii); xgene_enet_wr(priv, BLOCK_MCX_MAC_CSR, ICM_CONFIG0_REG_0_ADDR, icm_config0); xgene_enet_wr(priv, BLOCK_MCX_MAC_CSR, ICM_CONFIG2_REG_0_ADDR, icm_config2); xgene_enet_wr(priv, BLOCK_MCX_MAC_CSR, ECM_CONFIG0_REG_0_ADDR, ecm_config0); xgene_enet_wr(priv, BLOCK_ETH_CSR, ENET_SPARE_CFG_REG_ADDR, enet_spare_cfg); /* Rx-Tx traffic resume */ xgene_enet_wr(priv, BLOCK_ETH_CSR, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0_WR(0x1)); if (speed != XGENE_ENET_SPEED_10 && speed != XGENE_ENET_SPEED_100) { xgene_enet_rd(priv, BLOCK_ETH_CSR, DEBUG_REG_ADDR, &value); value |= CFG_BYPASS_UNISEC_TX_WR(1) | CFG_BYPASS_UNISEC_RX_WR(1); xgene_enet_wr(priv, BLOCK_ETH_CSR, DEBUG_REG_ADDR, value); } xgene_enet_rd(priv, BLOCK_MCX_MAC_CSR, RX_DV_GATE_REG_0_ADDR, &value); value = TX_DV_GATE_EN0_SET(value, 0); value = RX_DV_GATE_EN0_SET(value, 0); value = RESUME_RX0_SET(value, 1); xgene_enet_wr(priv, BLOCK_MCX_MAC_CSR, RX_DV_GATE_REG_0_ADDR, value); xgene_enet_wr(priv, BLOCK_ETH_CSR, CFG_BYPASS_ADDR, RESUME_TX_WR(1)); return 0; }