Skip to content

Commit

Permalink
net: ti: icssg-prueth: am65x SR2.0 add 10M full duplex support
Browse files Browse the repository at this point in the history
For AM65x SR2.0 it's required to enable IEP1 in raw 64bit mode which is
used by PRU FW to monitor the link and apply w/a for 10M link issue.
Note. No public errata available yet.

Without this w/a the PRU FW will stuck if link state changes under TX
traffic pressure.

Hence, add support for 10M full duplex for AM65x SR2.0:
 - add new IEP API to enable IEP, but without PTP support
 - add pdata quirk_10m_link_issue to enable 10M link issue w/a.

Signed-off-by: Grygorii Strashko <[email protected]>
Signed-off-by: Vignesh Raghavendra <[email protected]>
Reviewed-by: Roger Quadros <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Reviewed-by: Jacob Keller <[email protected]>
Signed-off-by: MD Danish Anwar <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
grygoriyS authored and davem330 committed Aug 27, 2023
1 parent 186734c commit 443a236
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 2 deletions.
26 changes: 26 additions & 0 deletions drivers/net/ethernet/ti/icssg/icss_iep.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,32 @@ void icss_iep_put(struct icss_iep *iep)
}
EXPORT_SYMBOL_GPL(icss_iep_put);

void icss_iep_init_fw(struct icss_iep *iep)
{
/* start IEP for FW use in raw 64bit mode, no PTP support */
iep->clk_tick_time = iep->def_inc;
iep->cycle_time_ns = 0;
iep->ops = NULL;
iep->clockops_data = NULL;
icss_iep_set_default_inc(iep, iep->def_inc);
icss_iep_set_compensation_inc(iep, iep->def_inc);
icss_iep_set_compensation_count(iep, 0);
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, iep->refclk_freq / 10); /* 100 ms pulse */
regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
if (iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT)
icss_iep_set_slow_compensation_count(iep, 0);

icss_iep_enable(iep);
icss_iep_settime(iep, 0);
}
EXPORT_SYMBOL_GPL(icss_iep_init_fw);

void icss_iep_exit_fw(struct icss_iep *iep)
{
icss_iep_disable(iep);
}
EXPORT_SYMBOL_GPL(icss_iep_exit_fw);

int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops,
void *clockops_data, u32 cycle_time_ns)
{
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/ti/icssg/icss_iep.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,7 @@ int icss_iep_exit(struct icss_iep *iep);
int icss_iep_get_count_low(struct icss_iep *iep);
int icss_iep_get_count_hi(struct icss_iep *iep);
int icss_iep_get_ptp_clock_idx(struct icss_iep *iep);
void icss_iep_init_fw(struct icss_iep *iep);
void icss_iep_exit_fw(struct icss_iep *iep);

#endif /* __NET_TI_ICSS_IEP_H */
7 changes: 7 additions & 0 deletions drivers/net/ethernet/ti/icssg/icssg_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ void icssg_config_ipg(struct prueth_emac *emac)
case SPEED_100:
icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
break;
case SPEED_10:
/* IPG for 10M is same as 100M */
icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
break;
default:
/* Other links speeds not supported */
netdev_err(emac->ndev, "Unsupported link speed\n");
Expand Down Expand Up @@ -440,6 +444,9 @@ void icssg_config_set_speed(struct prueth_emac *emac)
case SPEED_100:
fw_speed = FW_LINK_SPEED_100M;
break;
case SPEED_10:
fw_speed = FW_LINK_SPEED_10M;
break;
default:
/* Other links speeds not supported */
netdev_err(emac->ndev, "Unsupported link speed\n");
Expand Down
27 changes: 25 additions & 2 deletions drivers/net/ethernet/ti/icssg/icssg_prueth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,6 @@ static int emac_phy_connect(struct prueth_emac *emac)

/* remove unsupported modes */
phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Pause_BIT);
Expand Down Expand Up @@ -2090,13 +2089,29 @@ static int prueth_probe(struct platform_device *pdev)
goto free_pool;
}

prueth->iep1 = icss_iep_get_idx(np, 1);
if (IS_ERR(prueth->iep1)) {
ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n");
icss_iep_put(prueth->iep0);
prueth->iep0 = NULL;
prueth->iep1 = NULL;
goto free_pool;
}

if (prueth->pdata.quirk_10m_link_issue) {
/* Enable IEP1 for FW in 64bit mode as W/A for 10M FD link detect issue under TX
* traffic.
*/
icss_iep_init_fw(prueth->iep1);
}

/* setup netdev interfaces */
if (eth0_node) {
ret = prueth_netdev_init(prueth, eth0_node);
if (ret) {
dev_err_probe(dev, ret, "netdev init %s failed\n",
eth0_node->name);
goto netdev_exit;
goto exit_iep;
}
prueth->emac[PRUETH_MAC0]->iep = prueth->iep0;
}
Expand Down Expand Up @@ -2167,6 +2182,10 @@ static int prueth_probe(struct platform_device *pdev)
prueth_netdev_exit(prueth, eth_node);
}

exit_iep:
if (prueth->pdata.quirk_10m_link_issue)
icss_iep_exit_fw(prueth->iep1);

free_pool:
gen_pool_free(prueth->sram_pool,
(unsigned long)prueth->msmcram.va, msmc_ram_size);
Expand Down Expand Up @@ -2212,6 +2231,10 @@ static void prueth_remove(struct platform_device *pdev)
prueth_netdev_exit(prueth, eth_node);
}

if (prueth->pdata.quirk_10m_link_issue)
icss_iep_exit_fw(prueth->iep1);

icss_iep_put(prueth->iep1);
icss_iep_put(prueth->iep0);

gen_pool_free(prueth->sram_pool,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/ti/icssg/icssg_prueth.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ struct prueth_pdata {
* @icssg_hwcmdseq: seq counter or HWQ messages
* @emacs_initialized: num of EMACs/ext ports that are up/running
* @iep0: pointer to IEP0 device
* @iep1: pointer to IEP1 device
*/
struct prueth {
struct device *dev;
Expand All @@ -231,6 +232,7 @@ struct prueth {
u8 icssg_hwcmdseq;
int emacs_initialized;
struct icss_iep *iep0;
struct icss_iep *iep1;
};

struct emac_tx_ts_response {
Expand Down

0 comments on commit 443a236

Please sign in to comment.