diff options
author | Robin Peng <robinpeng@google.com> | 2020-02-20 16:33:37 +0800 |
---|---|---|
committer | Robin Peng <robinpeng@google.com> | 2020-02-20 16:33:37 +0800 |
commit | 65d1205259b4406acaf7f1b018c3bf60db2529ba (patch) | |
tree | c738a8d4d754409fb376efc8c1ceb85d015b20c8 | |
parent | 346e30acf12d2c6970f6ae23c7152e2f15bd0f7a (diff) | |
parent | d0c4566d6011f0d0172273185e11280bc1dd6665 (diff) | |
download | data-kernel-65d1205259b4406acaf7f1b018c3bf60db2529ba.tar.gz |
Merge branch 'LA.UM.9.12.R1.10.00.00.597.022' into qcom-msm-4.19-7250
Change-Id: Ib2d4e487fedc8e99ecd7be8ad8cbc99052dcce06
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c | 13 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c | 101 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c | 12 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h | 2 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs.h | 4 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_config.c | 6 | ||||
-rwxr-xr-x | drivers/rmnet/shs/rmnet_shs_main.c | 19 |
7 files changed, 101 insertions, 56 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 9102457..4cff0e4 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c @@ -899,6 +899,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; @@ -1470,6 +1480,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 { diff --git a/drivers/rmnet/shs/rmnet_shs.h b/drivers/rmnet/shs/rmnet_shs.h index f6ce09e..b7bf773 100644 --- a/drivers/rmnet/shs/rmnet_shs.h +++ b/drivers/rmnet/shs/rmnet_shs.h @@ -299,7 +299,7 @@ extern int (*rmnet_shs_skb_entry)(struct sk_buff *skb, int rmnet_shs_is_lpwr_cpu(u16 cpu); void rmnet_shs_cancel_table(void); void rmnet_shs_rx_wq_init(void); -void rmnet_shs_rx_wq_exit(void); +unsigned int rmnet_shs_rx_wq_exit(void); int rmnet_shs_get_mask_len(u8 mask); int rmnet_shs_chk_and_flush_node(struct rmnet_shs_skbn_s *node, @@ -314,7 +314,7 @@ void rmnet_shs_assign(struct sk_buff *skb, struct rmnet_port *port); void rmnet_shs_flush_table(u8 is_force_flush, u8 ctxt); void rmnet_shs_cpu_node_remove(struct rmnet_shs_skbn_s *node); void rmnet_shs_init(struct net_device *dev, struct net_device *vnd); -void rmnet_shs_exit(void); +void rmnet_shs_exit(unsigned int cpu_switch); void rmnet_shs_ps_on_hdlr(void *port); void rmnet_shs_ps_off_hdlr(void *port); void rmnet_shs_update_cpu_proc_q_all_cpus(void); diff --git a/drivers/rmnet/shs/rmnet_shs_config.c b/drivers/rmnet/shs/rmnet_shs_config.c index e6b4002..6a628dc 100644 --- a/drivers/rmnet/shs/rmnet_shs_config.c +++ b/drivers/rmnet/shs/rmnet_shs_config.c @@ -99,14 +99,16 @@ static int rmnet_shs_dev_notify_cb(struct notifier_block *nb, * phy_dev is going down. */ if (!rmnet_vnd_total && rmnet_shs_cfg.rmnet_shs_init_complete) { + unsigned int cpu_switch; + pr_info("rmnet_shs deinit %s going down ", dev->name); RCU_INIT_POINTER(rmnet_shs_skb_entry, NULL); qmi_rmnet_ps_ind_deregister(rmnet_shs_cfg.port, &rmnet_shs_cfg.rmnet_idl_ind_cb); rmnet_shs_cancel_table(); - rmnet_shs_rx_wq_exit(); + cpu_switch = rmnet_shs_rx_wq_exit(); rmnet_shs_wq_exit(); - rmnet_shs_exit(); + rmnet_shs_exit(cpu_switch); trace_rmnet_shs_high(RMNET_SHS_MODULE, RMNET_SHS_MODULE_INIT_WQ, 0xDEF, 0xDEF, 0xDEF, diff --git a/drivers/rmnet/shs/rmnet_shs_main.c b/drivers/rmnet/shs/rmnet_shs_main.c index ae66460..2accd29 100755 --- a/drivers/rmnet/shs/rmnet_shs_main.c +++ b/drivers/rmnet/shs/rmnet_shs_main.c @@ -1359,14 +1359,25 @@ void rmnet_shs_rx_wq_init(void) INIT_WORK(&shs_rx_work.work, rmnet_flush_buffered); } -void rmnet_shs_rx_wq_exit(void) +unsigned int rmnet_shs_rx_wq_exit(void) { + unsigned int cpu_switch = rmnet_shs_inst_rate_switch; int i; - for (i = 0; i < MAX_CPUS; i++) + /* Disable any further core_flush timer starts untill cleanup + * is complete. + */ + rmnet_shs_inst_rate_switch = 0; + + for (i = 0; i < MAX_CPUS; i++) { + hrtimer_cancel(&GET_CTIMER(i)); + cancel_work_sync(&rmnet_shs_cfg.core_flush[i].work); + } cancel_work_sync(&shs_rx_work.work); + + return cpu_switch; } void rmnet_shs_ps_on_hdlr(void *port) @@ -1724,7 +1735,7 @@ void rmnet_shs_assign(struct sk_buff *skb, struct rmnet_port *port) /* Cancels the flushing timer if it has been armed * Deregisters DL marker indications */ -void rmnet_shs_exit(void) +void rmnet_shs_exit(unsigned int cpu_switch) { rmnet_shs_freq_exit(); rmnet_shs_cfg.dl_mrk_ind_cb.dl_hdr_handler = NULL; @@ -1738,5 +1749,5 @@ void rmnet_shs_exit(void) memset(&rmnet_shs_cfg, 0, sizeof(rmnet_shs_cfg)); rmnet_shs_cfg.port = NULL; rmnet_shs_cfg.rmnet_shs_init_complete = 0; - + rmnet_shs_inst_rate_switch = cpu_switch; } |