Example #1
0
/*
 *  nae_gmac_mdio_write -Write sgmac mii PHY register.
 *
 *  Input parameters:
 *         bus          - bus number, nae has two external gmac bus: 0 and 1
 *         phyaddr      - PHY to use
 *         regidx       - register within the PHY
 *         val          - data to write to register
 *
 *  Return value:
 *         0 - success
 */
int
nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
    int intf_type, int phyaddr, int regidx, uint16_t val)
{
	uint32_t mdio_ld_cmd;
	uint32_t ctrlval;

	mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
	    (EXT_G0_MDIO_CTRL + bus * 4)));
	if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
		    (mdio_ld_cmd & ~EXT_G_MDIO_CMD_LCD));
		while(nlm_read_nae_reg(nae_base,
		    NAE_REG(block, intf_type,
		    (EXT_G0_MDIO_RD_STAT + bus * 4))) &
		    EXT_G_MDIO_STAT_MBSY);
	}

	/* load data into ctrl data reg */
	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL_DATA+bus*4)), 
	    val);

	ctrlval = EXT_G_MDIO_CMD_SP		|
	    (phyaddr << EXT_G_MDIO_PHYADDR_POS)	|
	    (regidx << EXT_G_MDIO_REGADDR_POS);
	if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
	    	ctrlval |= EXT_G_MDIO_DIV;
	else
		ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
	    ctrlval);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
	    ctrlval | EXT_G_MDIO_CMD_LCD);
	DELAY(1000);

	/* poll master busy bit until it is not busy */
	while(nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type,
	    (EXT_G0_MDIO_RD_STAT + bus * 4))) & EXT_G_MDIO_STAT_MBSY);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
	    ctrlval);

	return (0);
}
Example #2
0
/* Internal MDIO WRITE Routines */
int
nlm_int_gmac_mdio_write(uint64_t nae_base, int bus, int block,
    int intf_type, int phyaddr, int regidx, uint16_t val)
{
	uint32_t mdio_ld_cmd;
	uint32_t ctrlval;

	ctrlval = INT_MDIO_CTRL_SMP		|
	    (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
	    (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
	    (1 << INT_MDIO_CTRL_OP_POS)		|
	    (1 << INT_MDIO_CTRL_ST_POS)		|
	    (7 << INT_MDIO_CTRL_XDIV_POS)	|
	    (2 << INT_MDIO_CTRL_TA_POS)		|
	    (1 << INT_MDIO_CTRL_MIIM_POS)	|
	    (1 << INT_MDIO_CTRL_MCDIV_POS);

	mdio_ld_cmd = nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
	if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
		    (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
	}

	/* load data into ctrl data reg */
	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL_DATA + bus * 4)),
	    val);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));

	/* poll master busy bit until it is not busy */
	while(nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
	    INT_MDIO_STAT_MBSY) {
	}

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	return (0);
}
Example #3
0
/* Internal MDIO READ/WRITE Routines */
int
nlm_int_gmac_mdio_read(uint64_t nae_base, int bus, int block,
    int intf_type, int phyaddr, int regidx)
{
	uint32_t mdio_ld_cmd;
	uint32_t ctrlval;

	ctrlval = INT_MDIO_CTRL_SMP 		|
	    (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
	    (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
	    (2 << INT_MDIO_CTRL_OP_POS)		|
	    (1 << INT_MDIO_CTRL_ST_POS)		|
	    (7 << INT_MDIO_CTRL_XDIV_POS) 	|
	    (2 << INT_MDIO_CTRL_TA_POS)		|
	    (2 << INT_MDIO_CTRL_MIIM_POS) 	|
	    (1 << INT_MDIO_CTRL_MCDIV_POS);

	mdio_ld_cmd = nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
	if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
		    (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
	}

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	/* Toggle Load Cmd Bit */
	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));

	/* poll master busy bit until it is not busy */
	while(nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
	    INT_MDIO_STAT_MBSY) {
	}

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	/* Read the data back */
	return nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4)));
}
Example #4
0
void
nlm_nae_setup_rx_mode_sgmii(uint64_t base, int nblock, int iface, int port_type,
    int broadcast_en, int multicast_en, int pause_en, int promisc_en)
{
	uint32_t val;

	/* bit[17] of vlan_typefilter - allows packet matching in MAC.
	 * When DA filtering is disabled, this bit and bit[16] should
	 * be zero.
	 * bit[16] of vlan_typefilter - Allows hash matching to be used
	 * for DA filtering. When DA filtering is disabled, this bit and
	 * bit[17] should be zero.
	 * Both bits have to be set only if you want to turn on both
	 * features / modes.
	 */
	if (promisc_en == 1) {
		val = nlm_read_nae_reg(base,
		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface));
		val &= (~(0x3 << 16));
		nlm_write_nae_reg(base,
		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface), val);
	} else {
		val = nlm_read_nae_reg(base,
		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface));
		val |= (0x1 << 17);
		nlm_write_nae_reg(base,
		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface), val);
	}

	val = ((broadcast_en & 0x1) << 10)  |
	    ((pause_en & 0x1) << 9)     |
	    ((multicast_en & 0x1) << 8) |
	    ((promisc_en & 0x1) << 7)   | /* unicast_enable - enables promisc mode */
	    1; /* MAC address is always valid */

	nlm_write_nae_reg(base, SGMII_MAC_FILTER_CONFIG(nblock, iface), val);

}
Example #5
0
void
nlm_xaui_pcs_init(uint64_t nae_base, int xaui_cplx_mask)
{
	int block, lane_ctrl, reg;
	int cplx_lane_enable;
	int lane_enable = 0;
	uint32_t regval;

	cplx_lane_enable = LM_XAUI |
	    (LM_XAUI << 4) |
	    (LM_XAUI << 8) |
	    (LM_XAUI << 12);

	if (xaui_cplx_mask == 0)
		return;

	/* write 0x2 to enable SGMII for all lane */
	block = 7;

	if (xaui_cplx_mask & 0x3) { /* Complexes 0, 1 */
		lane_enable = nlm_read_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1));
		if (xaui_cplx_mask & 0x1) { /* Complex 0 */
			lane_enable &= ~(0xFFFF);
			lane_enable |= cplx_lane_enable;
		}
		if (xaui_cplx_mask & 0x2) { /* Complex 1 */
			lane_enable &= ~(0xFFFF<<16);
			lane_enable |= (cplx_lane_enable << 16);
		}
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1),
		    lane_enable);
	}
	lane_enable = 0;
	if (xaui_cplx_mask & 0xc) { /* Complexes 2, 3 */
		lane_enable = nlm_read_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3));
		if (xaui_cplx_mask & 0x4) { /* Complex 2 */
			lane_enable &= ~(0xFFFF);
			lane_enable |= cplx_lane_enable;
		}
		if (xaui_cplx_mask & 0x8) { /* Complex 3 */
			lane_enable &= ~(0xFFFF<<16);
			lane_enable |= (cplx_lane_enable << 16);
		}
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3),
		    lane_enable);
	}

	/* Bring txpll out of reset */
	for (block = 0; block < 4; block++) {
		if ((xaui_cplx_mask & (1 << block)) == 0)
			continue;

		for (lane_ctrl = PHY_LANE_0_CTRL;
		    lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
			if (!nlm_is_xlp8xx_ax())
				xlp_nae_lane_reset_txpll(nae_base,
				    block, lane_ctrl, PHYMODE_XAUI);
			else
				xlp_ax_nae_lane_reset_txpll(nae_base, block,
				    lane_ctrl, PHYMODE_XAUI);
		}
	}

	/* Wait for Rx & TX clock stable */
	for (block = 0; block < 4; block++) {
		if ((xaui_cplx_mask & (1 << block)) == 0)
			continue;

		for (lane_ctrl = PHY_LANE_0_CTRL;
		    lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {

			reg = NAE_REG(block, PHY, lane_ctrl - 4);
			/* Wait for TX clock to be set */
			do {
				regval = nlm_read_nae_reg(nae_base, reg);
			} while ((regval & LANE_TX_CLK) == 0);

			/* Wait for RX clock to be set */
			do {
				regval = nlm_read_nae_reg(nae_base, reg);
			} while ((regval & LANE_RX_CLK) == 0);

			/* Wait for XAUI Lane fault to be cleared */
			do {
				regval = nlm_read_nae_reg(nae_base, reg);
			} while ((regval & XAUI_LANE_FAULT) != 0);
		}
	}
}
Example #6
0
void
nlm_nae_setup_mac(uint64_t nae_base, int nblock, int iface, int reset,
    int rx_en, int tx_en, int speed, int duplex)
{
	uint32_t mac_cfg1, mac_cfg2, netwk_inf;

	mac_cfg1 = nlm_read_nae_reg(nae_base,
	    SGMII_MAC_CONF1(nblock,iface));
	mac_cfg2 = nlm_read_nae_reg(nae_base,
	    SGMII_MAC_CONF2(nblock,iface));
	netwk_inf = nlm_read_nae_reg(nae_base,
	    SGMII_NET_IFACE_CTRL(nblock, iface));

	mac_cfg1 &= ~(0x1 << 31); /* remove reset */
	mac_cfg1 &= ~(0x1 << 2); /* remove rx */
	mac_cfg1 &= ~(0x1); /* remove tx */
	mac_cfg2 &= ~(0x3 << 8); /* remove interface mode bits */
	mac_cfg2 &= ~(0x1); /* remove duplex */
	netwk_inf &= ~(0x1 << 2); /* remove tx */
	netwk_inf &= ~(0x3); /* remove speed */

	switch (speed) {
	case NLM_SGMII_SPEED_10:
		netwk_inf |= 0x0; /* 2.5 Mhz clock for 10 Mbps */
		mac_cfg2  |= (0x1 << 8); /* enable 10/100 Mbps */
		break;
	case NLM_SGMII_SPEED_100:
		netwk_inf |= 0x1; /* 25 Mhz clock for 100 Mbps */
		mac_cfg2  |= (0x1 << 8); /* enable 10/100 Mbps */
		break;
	default: /* make it as 1G */
		netwk_inf |= 0x2; /* 125 Mhz clock for 1G */
		mac_cfg2  |= (0x2 << 8); /* enable 1G */
		break;
	}

	if (reset)
		mac_cfg1 |= (0x1 << 31); /* set reset */

	if (rx_en)
		mac_cfg1 |= (0x1 << 2); /* set rx */

        nlm_write_nae_reg(nae_base,
	    SGMII_NET_IFACE_CTRL(nblock, iface),
	    netwk_inf);

	if (tx_en) {
		mac_cfg1 |= 0x1; /* set tx */
		netwk_inf |= (0x1 << 2); /* set tx */
	}

	switch (duplex) {
	case NLM_SGMII_DUPLEX_HALF:
		/* duplexity is already set to half duplex */
		break;
	default:
		mac_cfg2 |= 0x1; /* set full duplex */
	}

	nlm_write_nae_reg(nae_base, SGMII_MAC_CONF1(nblock, iface), mac_cfg1);
	nlm_write_nae_reg(nae_base, SGMII_MAC_CONF2(nblock, iface), mac_cfg2);
	nlm_write_nae_reg(nae_base, SGMII_NET_IFACE_CTRL(nblock, iface),
	    netwk_inf);
}