summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2020-02-13 12:51:16 -0800
committerLinux Build Service Account <lnxbuild@localhost>2020-02-13 12:51:16 -0800
commita910a5dd4cb9a4f9c0539369c0a3691d3e3755df (patch)
tree37ef6d04025dec3f9aab31b8b7c4bc485805fbe4
parent384f80012cfcad8b1c79c715aecae5806bf31703 (diff)
parentc93506932fc4870b824f8412a34775d37900b04c (diff)
downloaddata-kernel-a910a5dd4cb9a4f9c0539369c0a3691d3e3755df.tar.gz
Merge c93506932fc4870b824f8412a34775d37900b04c on remote branch
Change-Id: I17a95af88c915280d5342e5a99a392498fda534f
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c13
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c101
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c12
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h2
4 files changed, 80 insertions, 48 deletions
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
index 7ce0a31..b262b23 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
@@ -3126,7 +3126,7 @@ static INT set_promiscuous_mode(void)
static INT write_phy_regs(INT phy_id, INT phy_reg, INT phy_reg_data)
{
- ULONG RETRYCOUNT = 1000;
+ ULONG RETRYCOUNT = 5000;
ULONG vy_count;
volatile ULONG VARMAC_GMIIAR;
@@ -3139,7 +3139,7 @@ static INT write_phy_regs(INT phy_id, INT phy_reg, INT phy_reg_data)
return -Y_FAILURE;
vy_count++;
- mdelay(1);
+ udelay(200);
MAC_GMIIAR_RGRD(VARMAC_GMIIAR);
if (GET_VALUE(
@@ -3173,7 +3173,7 @@ static INT write_phy_regs(INT phy_id, INT phy_reg, INT phy_reg_data)
return -Y_FAILURE;
vy_count++;
- mdelay(1);
+ udelay(200);
MAC_GMIIAR_RGRD(VARMAC_GMIIAR);
if (GET_VALUE(
@@ -3197,7 +3197,7 @@ static INT write_phy_regs(INT phy_id, INT phy_reg, INT phy_reg_data)
static INT read_phy_regs(INT phy_id, INT phy_reg, INT *phy_reg_data)
{
- ULONG RETRYCOUNT = 1000;
+ ULONG RETRYCOUNT = 5000;
ULONG vy_count;
volatile ULONG VARMAC_GMIIAR;
ULONG VARMAC_GMIIDR;
@@ -3211,8 +3211,7 @@ static INT read_phy_regs(INT phy_id, INT phy_reg, INT *phy_reg_data)
return -Y_FAILURE;
vy_count++;
- mdelay(1);
-
+ udelay(200);
MAC_GMIIAR_RGRD(VARMAC_GMIIAR);
if (GET_VALUE(
VARMAC_GMIIAR, MAC_GMIIAR_GB_LPOS,
@@ -3243,7 +3242,7 @@ static INT read_phy_regs(INT phy_id, INT phy_reg, INT *phy_reg_data)
return -Y_FAILURE;
vy_count++;
- mdelay(1);
+ udelay(200);
MAC_GMIIAR_RGRD(VARMAC_GMIIAR);
if (GET_VALUE(
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c
index faac49e..defeef8 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c
@@ -445,6 +445,43 @@ void dump_phy_registers(struct DWC_ETH_QOS_prv_data *pdata)
pr_alert("\n****************************************************\n");
}
+static void DWC_ETH_QOS_request_phy_wol(struct DWC_ETH_QOS_prv_data *pdata)
+{
+ pdata->phy_wol_supported = 0;
+ pdata->phy_wol_wolopts = 0;
+
+ /* Check if phydev is valid*/
+ /* Check and enable Wake-on-LAN functionality in PHY*/
+ if (pdata->phydev) {
+ struct ethtool_wolinfo wol = {.cmd = ETHTOOL_GWOL};
+ wol.supported = 0;
+ wol.wolopts= 0;
+
+ phy_ethtool_get_wol(pdata->phydev, &wol);
+ pdata->phy_wol_supported = wol.supported;
+
+ /* Try to enable supported Wake-on-LAN features in PHY*/
+ if (wol.supported) {
+
+ device_set_wakeup_capable(&pdata->pdev->dev, 1);
+
+ wol.cmd = ETHTOOL_SWOL;
+ wol.wolopts = wol.supported;
+
+ if (!phy_ethtool_set_wol(pdata->phydev, &wol)){
+ pdata->phy_wol_wolopts = wol.wolopts;
+
+ enable_irq_wake(pdata->phy_irq);
+
+ device_set_wakeup_enable(&pdata->pdev->dev, 1);
+ EMACDBG("Enabled WoL[0x%x] in %s\n", wol.wolopts,
+ pdata->phydev->drv->name);
+ pdata->wol_enabled = 1;
+ }
+ }
+ }
+}
+
/*!
* \brief API to enable or disable PHY hibernation mode
*
@@ -1007,6 +1044,9 @@ void DWC_ETH_QOS_adjust_link(struct net_device *dev)
}
#endif
+ if (pdata->phy_intr_en && !pdata->wol_enabled)
+ DWC_ETH_QOS_request_phy_wol(pdata);
+
if (pdata->ipa_enabled && netif_running(dev)) {
if (phydev->link == 1)
DWC_ETH_QOS_ipa_offload_event_handler(pdata, EV_PHY_LINK_UP);
@@ -1030,42 +1070,6 @@ void DWC_ETH_QOS_adjust_link(struct net_device *dev)
DBGPR_MDIO("<--DWC_ETH_QOS_adjust_link\n");
}
-static void DWC_ETH_QOS_request_phy_wol(struct DWC_ETH_QOS_prv_data *pdata)
-{
- pdata->phy_wol_supported = 0;
- pdata->phy_wol_wolopts = 0;
-
- /* Check if phydev is valid*/
- /* Check and enable Wake-on-LAN functionality in PHY*/
- if (pdata->phydev) {
- struct ethtool_wolinfo wol = {.cmd = ETHTOOL_GWOL};
- wol.supported = 0;
- wol.wolopts= 0;
-
- phy_ethtool_get_wol(pdata->phydev, &wol);
- pdata->phy_wol_supported = wol.supported;
-
- /* Try to enable supported Wake-on-LAN features in PHY*/
- if (wol.supported) {
-
- device_set_wakeup_capable(&pdata->pdev->dev, 1);
-
- wol.cmd = ETHTOOL_SWOL;
- wol.wolopts = wol.supported;
-
- if (!phy_ethtool_set_wol(pdata->phydev, &wol)){
- pdata->phy_wol_wolopts = wol.wolopts;
-
- enable_irq_wake(pdata->phy_irq);
-
- device_set_wakeup_enable(&pdata->pdev->dev, 1);
- EMACDBG("Enabled WoL[0x%x] in %s\n", wol.wolopts,
- pdata->phydev->drv->name);
- }
- }
- }
-}
-
bool DWC_ETH_QOS_is_phy_link_up(struct DWC_ETH_QOS_prv_data *pdata)
{
/* PHY driver initializes phydev->link=1.
@@ -1194,10 +1198,8 @@ static int DWC_ETH_QOS_init_phy(struct net_device *dev)
phydev->irq = PHY_IGNORE_INTERRUPT;
phydev->interrupts = PHY_INTERRUPT_ENABLED;
- if (phydev->drv->config_intr &&
- !phydev->drv->config_intr(phydev)){
- DWC_ETH_QOS_request_phy_wol(pdata);
- } else {
+ if (!(phydev->drv->config_intr &&
+ !phydev->drv->config_intr(phydev))){
EMACERR("Failed to configure PHY interrupts");
BUG();
}
@@ -1250,6 +1252,21 @@ int DWC_ETH_QOS_mdio_register(struct net_device *dev)
DBGPR_MDIO("-->DWC_ETH_QOS_mdio_register\n");
+ if (pdata->res_data->phy_addr != -1) {
+ phy_reg_read_status =
+ DWC_ETH_QOS_mdio_read_direct(pdata, pdata->res_data->phy_addr, MII_BMSR,
+ &mii_status);
+ if (phy_reg_read_status == 0) {
+ if (mii_status != 0x0000 && mii_status != 0xffff) {
+ phy_detected = 1;
+ phyaddr = pdata->res_data->phy_addr;
+ EMACINFO("skip_phy_detection (phyaddr)%d\n", phyaddr);
+ goto skip_phy_detection;
+ } else
+ EMACERR("Invlaid phy address specified in device tree\n");
+ }
+ }
+
/* find the phy ID or phy address which is connected to our MAC */
for (phyaddr = 0; phyaddr < 32; phyaddr++) {
@@ -1276,6 +1293,8 @@ int DWC_ETH_QOS_mdio_register(struct net_device *dev)
return -ENOLINK;
}
+ skip_phy_detection:
+
pdata->phyaddr = phyaddr;
pdata->bus_id = 0x1;
pdata->phy_intr_en = false;
@@ -1307,7 +1326,7 @@ int DWC_ETH_QOS_mdio_register(struct net_device *dev)
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", new_bus->name,
pdata->bus_id);
new_bus->priv = dev;
- new_bus->phy_mask = 0;
+ new_bus->phy_mask = ~(1 << phyaddr);
new_bus->parent = &pdata->pdev->dev;
ret = mdiobus_register(new_bus);
if (ret != 0) {
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c
index 50d1e55..62daeb6 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c
@@ -920,6 +920,16 @@ static int DWC_ETH_QOS_get_dts_config(struct platform_device *pdev)
dwc_eth_qos_res_data.is_pinctrl_names = true;
EMACDBG("qcom,pinctrl-names present\n");
}
+ dwc_eth_qos_res_data.phy_addr = -1;
+ if (of_property_read_bool(pdev->dev.of_node, "emac-phy-addr")) {
+ ret = of_property_read_u32(pdev->dev.of_node, "emac-phy-addr",
+ &dwc_eth_qos_res_data.phy_addr);
+ if (ret) {
+ EMACINFO("Pphy_addr not specified, using dynamic phy detection\n");
+ dwc_eth_qos_res_data.phy_addr = -1;
+ }
+ EMACINFO("phy_addr = %d\n", dwc_eth_qos_res_data.phy_addr);
+ }
return ret;
@@ -1491,6 +1501,8 @@ static int DWC_ETH_QOS_init_gpios(struct device *dev)
gpio_set_value(dwc_eth_qos_res_data.gpio_phy_reset, PHY_RESET_GPIO_HIGH);
EMACDBG("PHY is out of reset successfully\n");
+ /* Add delay of 50ms so that phy should get sufficient time*/
+ mdelay(50);
}
return ret;
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h b/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h
index ee29121..b0a1210 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h
@@ -1584,6 +1584,7 @@ struct DWC_ETH_QOS_res_data {
unsigned int emac_hw_version_type;
bool early_eth_en;
bool pps_lpass_conn_en;
+ int phy_addr;
};
struct DWC_ETH_QOS_prv_ipa_data {
@@ -1878,6 +1879,7 @@ struct DWC_ETH_QOS_prv_data {
struct class* avb_class_b_class;
struct delayed_work ipv6_addr_assign_wq;
bool print_kpi;
+ bool wol_enabled;
};
struct ip_params {