summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 696ba15)
raw | patch | inline | side by side (parent: 696ba15)
author | Tinku Mannan <tmannan@ti.com> | |
Mon, 5 Aug 2019 19:05:05 +0000 (15:05 -0400) | ||
committer | Mahesh Radhakrishnan <a0875154@ti.com> | |
Fri, 9 Aug 2019 17:49:10 +0000 (12:49 -0500) |
update to emac_poll_v5 API to support 100 mbps link detection and config
Signed-off-by: Tinku Mannan <tmannan@ti.com>
Signed-off-by: Tinku Mannan <tmannan@ti.com>
src/v5/emac_drv_v5.c | patch | blob | history |
diff --git a/src/v5/emac_drv_v5.c b/src/v5/emac_drv_v5.c
index 4d31ca86a261e575d5a8d9af80f9f98e4a9dda43..0c6697666855fb2219dfc45d14f582b52c1bbd3c 100644 (file)
--- a/src/v5/emac_drv_v5.c
+++ b/src/v5/emac_drv_v5.c
**********************************************************************/
EMAC_MCB_V5_T emac_mcb;
-
/* EMAC_v5 local functions */
static void
EMAC_get_cpsw_stats(CSL_Xge_cpswRegs *hCpswRegs,EMAC_STATISTICS_T* p_stats);
@@ -167,6 +166,9 @@ emac_poll_mgmt_pkts(uint32_t port_num, Udma_RingHandle compRingHandle, Udma_Ring
static void
emac_poll_tx_complete(uint32_t port_num, Udma_RingHandle compRingHandle, Udma_RingHandle freeRingHandle, uint32_t ringNum);
+static void
+emac_icssg_update_link_params(uint32_t port_num, uint32_t virt_port_num, EMAC_LINK_INFO_T *pLinkInfo);
+
void EMAC_rxIsrFxn(Udma_EventHandle eventHandle,
uint32_t eventType,
void *appData);
@@ -2102,15 +2104,18 @@ static EMAC_DRV_ERR_E EMAC_poll_v5(uint32_t port_num, EMAC_LINK_INFO_T* p_info)
EMAC_DRV_ERR_E result = EMAC_DRV_RESULT_OK;
uint32_t phy_addr;
uint32_t mdioStatus;
+ uint32_t virt_port_num =0;
switch (port_num)
{
case EMAC_INTERPOSER_PORT0:
case EMAC_SWITCH_PORT1:
- port_num = 0U;
+ virt_port_num = port_num;
+ port_num = 0;
break;
case EMAC_INTERPOSER_PORT1:
case EMAC_SWITCH_PORT2:
+ virt_port_num = port_num;
port_num = 1U;
break;
default:
@@ -2141,29 +2146,8 @@ static EMAC_DRV_ERR_E EMAC_poll_v5(uint32_t port_num, EMAC_LINK_INFO_T* p_info)
p_info->link_status_change = TRUE;
EMAC_mdioGetStatus( &emac_mcb.port_cb[port_num].MdioDev, &phy_addr, &p_info->link_status );
+ emac_icssg_update_link_params(port_num, virt_port_num, p_info);
- if (port_num == EMAC_CPSW_PORT_NUM)
- {
- /* On a new link, set the EMAC duplex */
- if( mdioStatus == EMAC_MDIO_EVENT_LINKUP )
- {
- if( p_info->link_status == EMAC_MDIO_LINKSTATUS_FD10 ||
- p_info->link_status == EMAC_MDIO_LINKSTATUS_FD100 ||
- p_info->link_status == EMAC_MDIO_LINKSTATUS_FD1000
- )
- {
- CSL_CPGMAC_SL_enableFullDuplex(emac_mcb.port_cb[port_num].hCpswRegs,0);
- }
- else
- {
- CSL_CPGMAC_SL_disableFullDuplex(emac_mcb.port_cb[port_num].hCpswRegs,0);
- }
- if( p_info->link_status == EMAC_MDIO_LINKSTATUS_FD1000 )
- {
- CSL_CPGMAC_SL_enableGigabit(emac_mcb.port_cb[port_num].hCpswRegs,0);
- }
- }
- }
}
else if ( mdioStatus == EMAC_MDIO_EVENT_PHYERROR)
{
CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_ICSS_G_CFG),
reg_val);
-
- /* Configure TX IPG. TBD: Need to move to firmware */
- reg_val = 26;
- emac_hw_mem_write (icssgBaseAddr + CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_REGS_BASE +
- CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_TX_IPG1, ®_val, 1);
-
/*Configure task manager TXL2 watermark. TBD: Need to move to firmware */
/*TX_WM ask runs on TX_PRU/PRU1 */
reg_val = 0;
/* Enable stats block, 0 64-bit counters */
CSL_REG32_WR (icssgBaseAddr + CSL_ICSS_G_PA_STAT_WRAP_PA_SLV_REGS_BASE + 8, EMAC_BIT(31));
- /* Debug (Workaround for NAVSS failure issue): Verify CMP0 */
- reg_val = CSL_REG32_RD(icssgBaseAddr + CSL_ICSS_G_PR1_IEP0_SLV_REGS_BASE +
- CSL_ICSS_G_PR1_IEP0_SLV_CMP0_REG0);
+}
+
+/*
+ * ======== emac_get_icssg_dram0_base_addr ========
+ */
+uintptr_t emac_get_icssg_dram0_base_addr(uint32_t port_num, uint32_t virt_port_num)
+{
+
+ uintptr_t baseAddr = 0;
+ switch (virt_port_num)
+ {
+ case EMAC_SWITCH_PORT1:
+ baseAddr = emac_mcb.port_cb[3].icssDram0BaseAddr;
+ break;
+ case EMAC_SWITCH_PORT2:
+ baseAddr = emac_mcb.port_cb[1].icssDram0BaseAddr;
+ break;
+ default:
+ baseAddr = emac_mcb.port_cb[port_num].icssDram0BaseAddr;
+ break;
+ }
+
+ return baseAddr;
+}
+/*
+ * ======== emac_icssg_update_rgmii_cfg_hd100 ========
+ */
+void emac_icssg_update_rgmii_cfg_hd100(uint32_t port_num, uintptr_t icssgRgmiiCfgBaseAddr)
+{
+ uint32_t regVal;
+
+ regVal = CSL_REG32_RD(icssgRgmiiCfgBaseAddr);
+ if ((port_num & 1) == 0)
+ {
+ regVal &= ~CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII0_GIG_IN_MASK;
+ regVal &= ~CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII0_FULLDUPLEX_IN_MASK;
+ }
+ else
+ {
+ regVal &= ~CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII1_GIG_IN_MASK;
+ regVal &= ~CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII1_FULLDUPLEX_IN_MASK;
+ }
+ CSL_REG32_WR (icssgRgmiiCfgBaseAddr, regVal);
+}
+
+#define EMAC_ICSSG_CONFIG_TX_IPG_960_NS ((uint32_t)(0x166)) /* configure 960 nano-second TX IPG */
+/*
+ * ======== emac_icssg_update_link_speed_hd100 ========
+ */
+void emac_icssg_update_link_speed_hd100(uint32_t port_num, uint32_t virt_port_num)
+{
+ uintptr_t icssgRgmiiCfgAddr, icssgTxIpg1CfgAddr;
+ uint32_t regVal;
+ /* Need tup update ICSSG_RGMII_CFG for both ICSSG instances if virt_port_num is a switch port*/
+ /* Need to clear bit 17 for slice 0 or bit 21 for slice 1 of ICSSG_RGMII_CFG to configure 100 mpbs */
+ /* Need to clear bit 18 for slice 0 or bit 22 for slice 1 of ICSSG_RGMII_CFG o configure full duplex */
+ if ((virt_port_num == EMAC_SWITCH_PORT1) ||(virt_port_num == EMAC_SWITCH_PORT2))
+ {
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, EMAC_SWITCH_PORT1) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_hd100(port_num, icssgRgmiiCfgAddr);
+
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, EMAC_SWITCH_PORT2) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_hd100(port_num, icssgRgmiiCfgAddr);
+ }
+ else
+ {
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, port_num) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_hd100(port_num, icssgRgmiiCfgAddr);
+ }
+ /*Configuring 960ns TX IPG in ICSSG HW MMR*/
+ regVal = EMAC_ICSSG_CONFIG_TX_IPG_960_NS;
+ icssgTxIpg1CfgAddr = emac_get_icssg_dram0_base_addr(port_num, virt_port_num) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_TX_IPG1;
+ CSL_REG32_WR (icssgTxIpg1CfgAddr, regVal);
}
+/*
+ * ======== emac_icssg_update_rgmii_cfg_fd100 ========
+ */
+void emac_icssg_update_rgmii_cfg_fd100(uint32_t port_num, uintptr_t icssgRgmiiCfgBaseAddr)
+{
+ uint32_t regVal;
+ regVal = CSL_REG32_RD(icssgRgmiiCfgBaseAddr);
+ if ((port_num & 1) == 0)
+ {
+ regVal &= ~CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII0_GIG_IN_MASK;
+ regVal |= CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII0_FULLDUPLEX_IN_MASK;
+ }
+ else
+ {
+ regVal &= ~CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII1_GIG_IN_MASK;
+ regVal |= CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII1_FULLDUPLEX_IN_MASK;
+ }
+ CSL_REG32_WR (icssgRgmiiCfgBaseAddr, regVal);
+}
+
+/*
+ * ======== emac_icssg_update_link_speed_fd100 ========
+ */
+void emac_icssg_update_link_speed_fd100(uint32_t port_num, uint32_t virt_port_num)
+{
+ uintptr_t icssgRgmiiCfgAddr, icssgTxIpg1CfgAddr;
+ uint32_t regVal;
+
+ /* Need tup update ICSSG_RGMII_CFG for both ICSSG instances if virt_port_num is a switch port*/
+ /* Need to clear bit 17 for slice 0 or bit 21 for slice 1 of ICSSG_RGMII_CFG to configure 100 mpbs */
+ /* Need to set bit 18 for slice 0 or bit 22 for slice 1 of ICSSG_RGMII_CFG to configure full duplex */
+ if ((virt_port_num == EMAC_SWITCH_PORT1) ||(virt_port_num == EMAC_SWITCH_PORT2))
+ {
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, EMAC_SWITCH_PORT1) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_fd100(port_num, icssgRgmiiCfgAddr);
+
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, EMAC_SWITCH_PORT2) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_fd100(port_num, icssgRgmiiCfgAddr);
+ }
+ else
+ {
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, port_num) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_fd100(port_num, icssgRgmiiCfgAddr);
+ }
+
+ /*Configuring 960ns TX IPG in ICSSG HW MMR*/
+ regVal = EMAC_ICSSG_CONFIG_TX_IPG_960_NS;
+ icssgTxIpg1CfgAddr = emac_get_icssg_dram0_base_addr(port_num, virt_port_num) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_TX_IPG1;
+ CSL_REG32_WR (icssgTxIpg1CfgAddr, regVal);
+}
+
+/*
+ * ======== emac_icssg_update_rgmii_cfg_fd1000 ========
+ */
+void emac_icssg_update_rgmii_cfg_fd1000(uint32_t port_num, uintptr_t icssgRgmiiCfgBaseAddr)
+{
+ uint32_t regVal;
+
+ regVal = CSL_REG32_RD(icssgRgmiiCfgBaseAddr);
+ if ((port_num & 1) == 0)
+ {
+ regVal |= CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII0_GIG_IN_MASK;
+ regVal |= CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII0_FULLDUPLEX_IN_MASK;
+ }
+ else
+ {
+ regVal |= CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII1_GIG_IN_MASK;
+ regVal |= CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG_RGMII1_FULLDUPLEX_IN_MASK;
+ }
+ CSL_REG32_WR (icssgRgmiiCfgBaseAddr, regVal);
+}
+
+
+#define EMAC_ICSSG_CONFIG_TX_IPG_104_NS ((uint32_t)(0x1A)) /* configure 104 nano-second TX IPG */
+/*
+ * ======== emac_icssg_update_link_speed_fd1000 ========
+ */
+void emac_icssg_update_link_speed_fd1000(uint32_t port_num, uint32_t virt_port_num)
+{
+ uintptr_t icssgRgmiiCfgAddr, icssgTxIpg1CfgAddr;
+ uint32_t regVal;
+
+ /* Need tup update ICSSG_RGMII_CFG for both ICSSG instances if virt_port_num is a switch port*/
+ /* need to set bit 17 for slice 0 or bit 21 for slice 1 of ICSSG_RGMII_CFG for Gig */
+ /* Need to set bit 18 for slice 0 or bit 22 for slice 1 of ICSSG_RGMII_CFG to configure full duplex */
+ if ((virt_port_num == EMAC_SWITCH_PORT1) ||(virt_port_num == EMAC_SWITCH_PORT2))
+ {
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, EMAC_SWITCH_PORT1) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_fd1000(port_num, icssgRgmiiCfgAddr);
+
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, EMAC_SWITCH_PORT2) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_fd1000(port_num, icssgRgmiiCfgAddr);
+ }
+ else
+ {
+ icssgRgmiiCfgAddr = emac_get_icssg_dram0_base_addr(port_num, port_num) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_G_CFG_REGS_G_RGMII_CFG;
+ emac_icssg_update_rgmii_cfg_fd1000(port_num, icssgRgmiiCfgAddr);
+ }
+ /*Configuring 104ns TX IPG ICSSG HW MMR */
+ regVal = EMAC_ICSSG_CONFIG_TX_IPG_104_NS;
+ icssgTxIpg1CfgAddr = emac_get_icssg_dram0_base_addr(port_num, virt_port_num) +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_REGS_BASE +
+ CSL_ICSS_G_PR1_MII_RT_PR1_MII_RT_CFG_TX_IPG1;
+ CSL_REG32_WR (icssgTxIpg1CfgAddr, regVal);
+}
+
+/*
+ * ======== emac_icssg_update_link_params ========
+ */
+static void emac_icssg_update_link_params(uint32_t port_num, uint32_t virt_port_num, EMAC_LINK_INFO_T *p_info)
+{
+ if(port_num == EMAC_CPSW_PORT_NUM)
+ {
+ if (p_info->link_status == EMAC_MDIO_LINKSTATUS_FD10 ||
+ p_info->link_status == EMAC_MDIO_LINKSTATUS_FD100 ||
+ p_info->link_status == EMAC_MDIO_LINKSTATUS_FD1000)
+ {
+ CSL_CPGMAC_SL_enableFullDuplex(emac_mcb.port_cb[port_num].hCpswRegs,0);
+ if (p_info->link_status == EMAC_MDIO_LINKSTATUS_FD1000)
+ {
+ CSL_CPGMAC_SL_enableGigabit(emac_mcb.port_cb[port_num].hCpswRegs,0);
+ }
+ }
+ else
+ {
+ CSL_CPGMAC_SL_disableFullDuplex(emac_mcb.port_cb[port_num].hCpswRegs,0);
+ }
+ }
+ /* ICSSG ports */
+ else
+ {
+ if(p_info->link_status == EMAC_MDIO_LINKSTATUS_FD1000)
+ {
+ emac_icssg_update_link_speed_fd1000(port_num, virt_port_num);
+ }
+ else if (p_info->link_status == EMAC_MDIO_LINKSTATUS_FD100)
+ {
+ emac_icssg_update_link_speed_fd100(port_num, virt_port_num);
+ }
+ else if (p_info->link_status == EMAC_MDIO_LINKSTATUS_HD100)
+ {
+ emac_icssg_update_link_speed_hd100(port_num, virt_port_num);
+ }
+ }
+}
/* Nothing past this point */