示例#1
0
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);
}
示例#3
0
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;
}