void nlm_nae_setup_mac_addr_xaui(uint64_t base, int nblock, int iface, int port_type, unsigned char *mac_addr) { nlm_write_nae_reg(base, XAUI_MAC_ADDR0_LO(nblock), (mac_addr[5] << 24) | (mac_addr[4] << 16) | (mac_addr[3] << 8) | mac_addr[2]); nlm_write_nae_reg(base, XAUI_MAC_ADDR0_HI(nblock), (mac_addr[1] << 24) | (mac_addr[0] << 16)); nlm_write_nae_reg(base, XAUI_MAC_ADDR_MASK0_LO(nblock), 0xffffffff); nlm_write_nae_reg(base, XAUI_MAC_ADDR_MASK0_HI(nblock), 0xffffffff); nlm_nae_setup_rx_mode_xaui(base, nblock, iface, XAUIC, 1, /* broadcast enabled */ 1, /* multicast enabled */ 0, /* do not accept pause frames */ 0 /* promisc mode disabled */ ); }
void nlm_configure_sgmii_interface(uint64_t nae_base, int block, int port, int mtu, int loopback) { uint32_t data1, data2; /* Apply a soft reset */ data1 = (0x1 << 31); /* soft reset */ if (loopback) data1 |= (0x01 << 8); data1 |= (0x01 << 2); /* Rx enable */ data1 |= 0x01; /* Tx enable */ nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF1), data1); data2 = (0x7 << 12) | /* pre-amble length=7 */ (0x2 << 8) | /* byteMode */ 0x1; /* fullDuplex */ nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF2), data2); /* Remove a soft reset */ data1 &= ~(0x01 << 31); nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF1), data1); /* setup sgmii max frame length */ nlm_write_nae_reg(nae_base, SGMII_MAX_FRAME(block, port), mtu); }
/* * 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); }
/* 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); }
/* 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))); }
/* * nae_gmac_mdio_reset -Reset sgmii mdio module. * * Input parameters: * bus - bus number, nae has two external gmac bus: 0 and 1 * * Return value: * 0 - success */ int nlm_gmac_mdio_reset(uint64_t nae_base, int bus, int block, int intf_type) { uint32_t ctrlval; 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)), EXT_G_MDIO_MMRST | ctrlval); nlm_write_nae_reg(nae_base, NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL + bus * 4)), ctrlval); return (0); }
int nlm_int_gmac_mdio_reset(uint64_t nae_base, int bus, int block, int intf_type) { uint32_t val; val = (7 << INT_MDIO_CTRL_XDIV_POS) | (1 << INT_MDIO_CTRL_MCDIV_POS); nlm_write_nae_reg(nae_base, NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)), val | INT_MDIO_CTRL_RST); nlm_write_nae_reg(nae_base, NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)), val); return (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); }
void nlm_nae_setup_rx_mode_xaui(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; 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, XAUI_MAC_FILTER_CFG(nblock), val); }
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); } } }
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); }