net: ethernet: stmmac: Enable Auto PHY Detection

Enable Dynamic PHY detection on sa8775 LA for different board
and PHY types.

Change-Id: I87888ca1e191db072ebdcf64fe596c39fe95f57b
Signed-off-by: Srinath Pandey <quic_srinpand@quicinc.com>
This commit is contained in:
Srinath Pandey 2024-09-10 19:16:51 +05:30
parent f3040bed7d
commit 2e6d781474
6 changed files with 133 additions and 23 deletions

View file

@ -227,3 +227,7 @@ eipv4= [KNL] Sets ipv4 address at boot up for early ethernet.
eipv6= [KNL] Sets ipv6 address at boot up for early ethernet.
ermac= [KNL] Sets mac address at boot up for early ethernet.
board= [KNL] Sets Board type of device at boot up for phy detection.
enet= [KNL] Sets the PHY type on device at boot up for phy detection.

View file

@ -7096,4 +7096,8 @@
eipv6= [KNL] Sets ipv6 address at boot up for early ethernet.
ermac= [KNL] Sets mac address at boot up for early ethernet.
ermac= [KNL] Sets mac address at boot up for early ethernet.
board= [KNL] Sets Board type of device at boot up for phy detection.
enet= [KNL] Sets the PHY type on device at boot up for phy detection.

View file

@ -168,6 +168,8 @@
#define DWMAC4_PCS_BASE 0x000000e0
#define RGMII_CONFIG_10M_CLK_DVD GENMASK(18, 10)
static int phytype = -1;
static int boardtype = -1;
void *ipc_emac_log_ctxt;
struct emac_emb_smmu_cb_ctx emac_emb_smmu_ctx = {0};
@ -177,6 +179,14 @@ struct plat_stmmacenet_data *plat_dat;
struct qcom_ethqos *pethqos;
#ifdef MODULE
static char *board;
module_param(board, charp, 0660);
MODULE_PARM_DESC(board, "board type of the device");
static char *enet;
module_param(enet, charp, 0660);
MODULE_PARM_DESC(enet, "enet value for the phy connection");
static char *eipv4;
module_param(eipv4, charp, 0660);
MODULE_PARM_DESC(eipv4, "ipv4 value from ethernet partition");
@ -203,6 +213,28 @@ static unsigned char dev_addr[ETH_ALEN] = {
0, 0x55, 0x7b, 0xb5, 0x7d, 0xf7};
static struct ip_params pparams = {"", "", "", ""};
static int set_board_type(char *board_params)
{
if (!strcmp(board_params, "Air"))
boardtype = AIR_BOARD;
else if (!strcmp(board_params, "Star"))
boardtype = STAR_BOARD;
else
return -1;
return 0;
}
static int set_phy_type(char *enet_params)
{
if (!strcmp(enet_params, "1") || !strcmp(enet_params, "2"))
phytype = PHY_1G;
else if (!strcmp(enet_params, "3") || !strcmp(enet_params, "6"))
phytype = PHY_25G;
else
return -1;
return 0;
}
static int set_early_ethernet_ipv4(char *ipv4_addr_in)
{
int ret = 1;
@ -278,6 +310,11 @@ fail:
}
#ifndef MODULE
__setup("board=", set_board_type);
__setup("enet=", set_phy_type);
static int __init set_early_ethernet_ipv4_static(char *ipv4_addr_in)
{
int ret = 1;
@ -2221,6 +2258,12 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ETHQOSINFO("M - Ethernet probe start\n");
#ifdef MODULE
if (enet)
ret = set_phy_type(enet);
if (board)
ret = set_board_type(board);
if (eipv4)
ret = set_early_ethernet_ipv4(eipv4);
@ -2362,7 +2405,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
}
ETHQOSDBG("gdsc-off-on-suspend = %d\n",
ethqos->gdsc_off_on_suspend);
plat_dat->phy_type = phytype;
plat_dat->board_type = boardtype;
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
goto err_clk;

View file

@ -55,6 +55,11 @@ struct stmmac_tx_info {
#define STMMAC_TBS_AVAIL BIT(0)
#define STMMAC_TBS_EN BIT(1)
#define AIR_BOARD 1
#define STAR_BOARD 2
#define PHY_1G 1
#define PHY_25G 2
/* Frequently used values are kept adjacent for cache effect */
struct stmmac_tx_queue {
u32 tx_count_frames;

View file

@ -433,6 +433,76 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
return 0;
}
/**
* stmmac_get_phy_addr
* @priv: net device structure
* @new_bus: points to the mii_bus structure
* Description: it finds the PHY address from board and phy_type
*/
int stmmac_get_phy_addr(struct stmmac_priv *priv, struct mii_bus *new_bus,
struct net_device *ndev)
{
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
struct device_node *np = priv->device->of_node;
unsigned int phyaddr;
int err = 0;
init_completion(&priv->plat->mdio_op);
new_bus->reset = &stmmac_mdio_reset;
new_bus->priv = ndev;
if (priv->plat->phy_type != -1) {
if (priv->plat->phy_type == PHY_1G) {
err = of_property_read_u32(np, "emac-1g-phy-addr", &phyaddr);
new_bus->read = &virtio_mdio_read;
new_bus->write = &virtio_mdio_write;
} else {
new_bus->read = &virtio_mdio_read_c45_indirect;
new_bus->write = &virtio_mdio_write_c45_indirect;
new_bus->probe_capabilities = MDIOBUS_C22_C45;
if (priv->plat->phy_type == PHY_25G &&
priv->plat->board_type == STAR_BOARD) {
err = of_property_read_u32(np,
"emac-star-cl45-phy-addr", &phyaddr);
} else {
err = of_property_read_u32(np,
"emac-air-cl45-phy-addr", &phyaddr);
}
}
} else {
err = of_property_read_u32(np, "emac-1g-phy-addr", &phyaddr);
if (err) {
new_bus->phy_mask = mdio_bus_data->phy_mask;
return -1;
}
new_bus->read = &virtio_mdio_read;
new_bus->write = &virtio_mdio_write;
/* Do MDIO reset before the bus->read call */
err = new_bus->reset(new_bus);
if (err) {
new_bus->phy_mask = ~(1 << phyaddr);
return phyaddr;
}
/* 1G phy check */
err = new_bus->read(new_bus, phyaddr, MII_BMSR);
if (err == -EBUSY || err == 0xffff) {
/* 2.5 G PHY case */
new_bus->read = &virtio_mdio_read_c45_indirect;
new_bus->write = &virtio_mdio_write_c45_indirect;
new_bus->probe_capabilities = MDIOBUS_C22_C45;
err = of_property_read_u32(np,
"emac-air-cl45-phy-addr", &phyaddr);
/* Board Type check */
err = new_bus->read(new_bus, phyaddr, MII_BMSR);
if (err == -EBUSY || !err || err == 0xffff)
err = of_property_read_u32(np,
"emac-star-cl45-phy-addr", &phyaddr);
}
}
new_bus->phy_mask = ~(1 << phyaddr);
return phyaddr;
}
/**
* stmmac_mdio_register
* @ndev: net device structure
@ -474,10 +544,9 @@ int stmmac_mdio_register(struct net_device *ndev)
err = of_property_read_bool(np, "virtio-mdio");
if (err) {
new_bus->read = &virtio_mdio_read;
new_bus->write = &virtio_mdio_write;
init_completion(&priv->plat->mdio_op);
phyaddr = stmmac_get_phy_addr(priv, new_bus, ndev);
max_addr = PHY_MAX_ADDR;
skip_phy_detect = 1;
} else if (priv->plat->has_xgmac) {
new_bus->read = &stmmac_xgmac2_mdio_read;
new_bus->write = &stmmac_xgmac2_mdio_write;
@ -501,24 +570,6 @@ int stmmac_mdio_register(struct net_device *ndev)
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
new_bus->name, priv->plat->bus_id);
new_bus->priv = ndev;
err = of_property_read_u32(np, "emac-phy-addr", &phyaddr);
if (err) {
new_bus->phy_mask = mdio_bus_data->phy_mask;
} else {
err = new_bus->read(new_bus, phyaddr, MII_BMSR);
if (err == -EBUSY || !err || err == 0xffff) {
err = of_property_read_u32(np, "emac-cl45-phy-addr", &phyaddr);
new_bus->phy_mask = ~(1 << phyaddr);
skip_phy_detect = 1;
new_bus->read = &virtio_mdio_read_c45_indirect;
new_bus->write = &virtio_mdio_write_c45_indirect;
new_bus->probe_capabilities = MDIOBUS_C22_C45;
} else {
new_bus->phy_mask = ~(1 << phyaddr);
skip_phy_detect = 1;
}
}
new_bus->parent = priv->device;
err = of_mdiobus_register(new_bus, mdio_node);

View file

@ -308,5 +308,7 @@ struct plat_stmmacenet_data {
bool mdio_op_busy;
atomic_t phy_clks_suspended;
struct completion mdio_op;
int board_type;
int phy_type;
};
#endif