diff options
Diffstat (limited to 'target/linux/sunxi/patches-4.9/0051-stmmac-form-4-11.patch')
-rw-r--r-- | target/linux/sunxi/patches-4.9/0051-stmmac-form-4-11.patch | 2296 |
1 files changed, 0 insertions, 2296 deletions
diff --git a/target/linux/sunxi/patches-4.9/0051-stmmac-form-4-11.patch b/target/linux/sunxi/patches-4.9/0051-stmmac-form-4-11.patch deleted file mode 100644 index 5f89e4b728..0000000000 --- a/target/linux/sunxi/patches-4.9/0051-stmmac-form-4-11.patch +++ /dev/null @@ -1,2296 +0,0 @@ ---- a/Documentation/devicetree/bindings/net/stmmac.txt -+++ b/Documentation/devicetree/bindings/net/stmmac.txt -@@ -49,6 +49,8 @@ Optional properties: - - snps,force_sf_dma_mode Force DMA to use the Store and Forward - mode for both tx and rx. This flag is - ignored if force_thresh_dma_mode is set. -+- snps,en-tx-lpi-clockgating Enable gating of the MAC TX clock during -+ TX low-power mode - - snps,multicast-filter-bins: Number of multicast filter hash bins - supported by this device instance - - snps,perfect-filter-entries: Number of perfect filter entries supported -@@ -65,7 +67,6 @@ Optional properties: - - snps,wr_osr_lmt: max write outstanding req. limit - - snps,rd_osr_lmt: max read outstanding req. limit - - snps,kbbe: do not cross 1KiB boundary. -- - snps,axi_all: align address - - snps,blen: this is a vector of supported burst length. - - snps,fb: fixed-burst - - snps,mb: mixed-burst ---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig -+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig -@@ -1,5 +1,5 @@ - config STMMAC_ETH -- tristate "STMicroelectronics 10/100/1000 Ethernet driver" -+ tristate "STMicroelectronics 10/100/1000/EQOS Ethernet driver" - depends on HAS_IOMEM && HAS_DMA - select MII - select PHYLIB -@@ -7,9 +7,8 @@ config STMMAC_ETH - select PTP_1588_CLOCK - select RESET_CONTROLLER - ---help--- -- This is the driver for the Ethernet IPs are built around a -- Synopsys IP Core and only tested on the STMicroelectronics -- platforms. -+ This is the driver for the Ethernet IPs built around a -+ Synopsys IP Core. - - if STMMAC_ETH - -@@ -29,6 +28,15 @@ config STMMAC_PLATFORM - - if STMMAC_PLATFORM - -+config DWMAC_DWC_QOS_ETH -+ tristate "Support for snps,dwc-qos-ethernet.txt DT binding." -+ select PHYLIB -+ select CRC32 -+ select MII -+ depends on OF && HAS_DMA -+ help -+ Support for chips using the snps,dwc-qos-ethernet.txt DT binding. -+ - config DWMAC_GENERIC - tristate "Generic driver for DWMAC" - default STMMAC_PLATFORM -@@ -143,11 +151,11 @@ config STMMAC_PCI - tristate "STMMAC PCI bus support" - depends on STMMAC_ETH && PCI - ---help--- -- This is to select the Synopsys DWMAC available on PCI devices, -- if you have a controller with this interface, say Y or M here. -+ This selects the platform specific bus support for the stmmac driver. -+ This driver was tested on XLINX XC2V3000 FF1152AMT0221 -+ D1215994A VIRTEX FPGA board and SNPS QoS IPK Prototyping Kit. - -- This PCI support is tested on XLINX XC2V3000 FF1152AMT0221 -- D1215994A VIRTEX FPGA board. -+ If you have a controller with this interface, say Y or M here. - - If unsure, say N. - endif ---- a/drivers/net/ethernet/stmicro/stmmac/Makefile -+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile -@@ -16,6 +16,7 @@ obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-alt - obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o - obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o - obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o -+obj-$(CONFIG_DWMAC_DWC_QOS_ETH) += dwmac-dwc-qos-eth.o - obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o - stmmac-platform-objs:= stmmac_platform.o - dwmac-altr-socfpga-objs := altr_tse_pcs.o dwmac-socfpga.o ---- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c -+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c -@@ -16,10 +16,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/common.h -+++ b/drivers/net/ethernet/stmicro/stmmac/common.h -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -71,7 +67,7 @@ struct stmmac_extra_stats { - unsigned long overflow_error; - unsigned long ipc_csum_error; - unsigned long rx_collision; -- unsigned long rx_crc; -+ unsigned long rx_crc_errors; - unsigned long dribbling_bit; - unsigned long rx_length; - unsigned long rx_mii; -@@ -323,6 +319,9 @@ struct dma_features { - /* TX and RX number of channels */ - unsigned int number_rx_channel; - unsigned int number_tx_channel; -+ /* TX and RX number of queues */ -+ unsigned int number_rx_queues; -+ unsigned int number_tx_queues; - /* Alternate (enhanced) DESC mode */ - unsigned int enh_desc; - }; -@@ -340,7 +339,7 @@ struct dma_features { - /* Common MAC defines */ - #define MAC_CTRL_REG 0x00000000 /* MAC Control */ - #define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */ --#define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */ -+#define MAC_ENABLE_RX 0x00000004 /* Receiver Enable */ - - /* Default LPI timers */ - #define STMMAC_DEFAULT_LIT_LS 0x3E8 -@@ -417,7 +416,7 @@ struct stmmac_dma_ops { - /* Configure the AXI Bus Mode Register */ - void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi); - /* Dump DMA registers */ -- void (*dump_regs) (void __iomem *ioaddr); -+ void (*dump_regs)(void __iomem *ioaddr, u32 *reg_space); - /* Set tx/rx threshold in the csr6 register - * An invalid value enables the store-and-forward mode */ - void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode, -@@ -454,8 +453,10 @@ struct stmmac_ops { - void (*core_init)(struct mac_device_info *hw, int mtu); - /* Enable and verify that the IPC module is supported */ - int (*rx_ipc)(struct mac_device_info *hw); -+ /* Enable RX Queues */ -+ void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue); - /* Dump MAC registers */ -- void (*dump_regs)(struct mac_device_info *hw); -+ void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); - /* Handle extra events on specific interrupts hw dependent */ - int (*host_irq_status)(struct mac_device_info *hw, - struct stmmac_extra_stats *x); -@@ -471,7 +472,8 @@ struct stmmac_ops { - unsigned int reg_n); - void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr, - unsigned int reg_n); -- void (*set_eee_mode)(struct mac_device_info *hw); -+ void (*set_eee_mode)(struct mac_device_info *hw, -+ bool en_tx_lpi_clockgating); - void (*reset_eee_mode)(struct mac_device_info *hw); - void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw); - void (*set_eee_pls)(struct mac_device_info *hw, int link); ---- a/drivers/net/ethernet/stmicro/stmmac/descs.h -+++ b/drivers/net/ethernet/stmicro/stmmac/descs.h -@@ -11,10 +11,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h -+++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h -@@ -17,10 +17,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- /dev/null -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c -@@ -0,0 +1,202 @@ -+/* -+ * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver -+ * -+ * Copyright (C) 2016 Joao Pinto <jpinto@synopsys.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/clk-provider.h> -+#include <linux/device.h> -+#include <linux/ethtool.h> -+#include <linux/io.h> -+#include <linux/ioport.h> -+#include <linux/module.h> -+#include <linux/of_net.h> -+#include <linux/mfd/syscon.h> -+#include <linux/platform_device.h> -+#include <linux/stmmac.h> -+ -+#include "stmmac_platform.h" -+ -+static int dwc_eth_dwmac_config_dt(struct platform_device *pdev, -+ struct plat_stmmacenet_data *plat_dat) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ u32 burst_map = 0; -+ u32 bit_index = 0; -+ u32 a_index = 0; -+ -+ if (!plat_dat->axi) { -+ plat_dat->axi = kzalloc(sizeof(struct stmmac_axi), GFP_KERNEL); -+ -+ if (!plat_dat->axi) -+ return -ENOMEM; -+ } -+ -+ plat_dat->axi->axi_lpi_en = of_property_read_bool(np, "snps,en-lpi"); -+ if (of_property_read_u32(np, "snps,write-requests", -+ &plat_dat->axi->axi_wr_osr_lmt)) { -+ /** -+ * Since the register has a reset value of 1, if property -+ * is missing, default to 1. -+ */ -+ plat_dat->axi->axi_wr_osr_lmt = 1; -+ } else { -+ /** -+ * If property exists, to keep the behavior from dwc_eth_qos, -+ * subtract one after parsing. -+ */ -+ plat_dat->axi->axi_wr_osr_lmt--; -+ } -+ -+ if (of_property_read_u32(np, "read,read-requests", -+ &plat_dat->axi->axi_rd_osr_lmt)) { -+ /** -+ * Since the register has a reset value of 1, if property -+ * is missing, default to 1. -+ */ -+ plat_dat->axi->axi_rd_osr_lmt = 1; -+ } else { -+ /** -+ * If property exists, to keep the behavior from dwc_eth_qos, -+ * subtract one after parsing. -+ */ -+ plat_dat->axi->axi_rd_osr_lmt--; -+ } -+ of_property_read_u32(np, "snps,burst-map", &burst_map); -+ -+ /* converts burst-map bitmask to burst array */ -+ for (bit_index = 0; bit_index < 7; bit_index++) { -+ if (burst_map & (1 << bit_index)) { -+ switch (bit_index) { -+ case 0: -+ plat_dat->axi->axi_blen[a_index] = 4; break; -+ case 1: -+ plat_dat->axi->axi_blen[a_index] = 8; break; -+ case 2: -+ plat_dat->axi->axi_blen[a_index] = 16; break; -+ case 3: -+ plat_dat->axi->axi_blen[a_index] = 32; break; -+ case 4: -+ plat_dat->axi->axi_blen[a_index] = 64; break; -+ case 5: -+ plat_dat->axi->axi_blen[a_index] = 128; break; -+ case 6: -+ plat_dat->axi->axi_blen[a_index] = 256; break; -+ default: -+ break; -+ } -+ a_index++; -+ } -+ } -+ -+ /* dwc-qos needs GMAC4, AAL, TSO and PMT */ -+ plat_dat->has_gmac4 = 1; -+ plat_dat->dma_cfg->aal = 1; -+ plat_dat->tso_en = 1; -+ plat_dat->pmt = 1; -+ -+ return 0; -+} -+ -+static int dwc_eth_dwmac_probe(struct platform_device *pdev) -+{ -+ struct plat_stmmacenet_data *plat_dat; -+ struct stmmac_resources stmmac_res; -+ struct resource *res; -+ int ret; -+ -+ memset(&stmmac_res, 0, sizeof(struct stmmac_resources)); -+ -+ /** -+ * Since stmmac_platform supports name IRQ only, basic platform -+ * resource initialization is done in the glue logic. -+ */ -+ stmmac_res.irq = platform_get_irq(pdev, 0); -+ if (stmmac_res.irq < 0) { -+ if (stmmac_res.irq != -EPROBE_DEFER) -+ dev_err(&pdev->dev, -+ "IRQ configuration information not found\n"); -+ -+ return stmmac_res.irq; -+ } -+ stmmac_res.wol_irq = stmmac_res.irq; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ stmmac_res.addr = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(stmmac_res.addr)) -+ return PTR_ERR(stmmac_res.addr); -+ -+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); -+ if (IS_ERR(plat_dat)) -+ return PTR_ERR(plat_dat); -+ -+ plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk"); -+ if (IS_ERR(plat_dat->stmmac_clk)) { -+ dev_err(&pdev->dev, "apb_pclk clock not found.\n"); -+ ret = PTR_ERR(plat_dat->stmmac_clk); -+ plat_dat->stmmac_clk = NULL; -+ goto err_remove_config_dt; -+ } -+ clk_prepare_enable(plat_dat->stmmac_clk); -+ -+ plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk"); -+ if (IS_ERR(plat_dat->pclk)) { -+ dev_err(&pdev->dev, "phy_ref_clk clock not found.\n"); -+ ret = PTR_ERR(plat_dat->pclk); -+ plat_dat->pclk = NULL; -+ goto err_out_clk_dis_phy; -+ } -+ clk_prepare_enable(plat_dat->pclk); -+ -+ ret = dwc_eth_dwmac_config_dt(pdev, plat_dat); -+ if (ret) -+ goto err_out_clk_dis_aper; -+ -+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); -+ if (ret) -+ goto err_out_clk_dis_aper; -+ -+ return 0; -+ -+err_out_clk_dis_aper: -+ clk_disable_unprepare(plat_dat->pclk); -+err_out_clk_dis_phy: -+ clk_disable_unprepare(plat_dat->stmmac_clk); -+err_remove_config_dt: -+ stmmac_remove_config_dt(pdev, plat_dat); -+ -+ return ret; -+} -+ -+static int dwc_eth_dwmac_remove(struct platform_device *pdev) -+{ -+ return stmmac_pltfr_remove(pdev); -+} -+ -+static const struct of_device_id dwc_eth_dwmac_match[] = { -+ { .compatible = "snps,dwc-qos-ethernet-4.10", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match); -+ -+static struct platform_driver dwc_eth_dwmac_driver = { -+ .probe = dwc_eth_dwmac_probe, -+ .remove = dwc_eth_dwmac_remove, -+ .driver = { -+ .name = "dwc-eth-dwmac", -+ .of_match_table = dwc_eth_dwmac_match, -+ }, -+}; -+module_platform_driver(dwc_eth_dwmac_driver); -+ -+MODULE_AUTHOR("Joao Pinto <jpinto@synopsys.com>"); -+MODULE_DESCRIPTION("Synopsys DWC Ethernet Quality-of-Service v4.10a driver"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c -@@ -35,10 +35,6 @@ - - #define PRG_ETH0_TXDLY_SHIFT 5 - #define PRG_ETH0_TXDLY_MASK GENMASK(6, 5) --#define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT) --#define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT) --#define PRG_ETH0_TXDLY_HALF (0x2 << PRG_ETH0_TXDLY_SHIFT) --#define PRG_ETH0_TXDLY_THREE_QUARTERS (0x3 << PRG_ETH0_TXDLY_SHIFT) - - /* divider for the result of m250_sel */ - #define PRG_ETH0_CLK_M250_DIV_SHIFT 7 -@@ -69,6 +65,8 @@ struct meson8b_dwmac { - - struct clk_divider m25_div; - struct clk *m25_div_clk; -+ -+ u32 tx_delay_ns; - }; - - static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg, -@@ -181,11 +179,19 @@ static int meson8b_init_prg_eth(struct m - { - int ret; - unsigned long clk_rate; -+ u8 tx_dly_val = 0; - - switch (dwmac->phy_mode) { - case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: -+ /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where -+ * 8ns are exactly one cycle of the 125MHz RGMII TX clock): -+ * 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3 -+ */ -+ tx_dly_val = dwmac->tx_delay_ns >> 1; -+ /* fall through */ -+ -+ case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_TXID: - /* Generate a 25MHz clock for the PHY */ - clk_rate = 25 * 1000 * 1000; -@@ -198,9 +204,8 @@ static int meson8b_init_prg_eth(struct m - meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, - PRG_ETH0_INVERTED_RMII_CLK, 0); - -- /* TX clock delay - all known boards use a 1/4 cycle delay */ - meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK, -- PRG_ETH0_TXDLY_QUARTER); -+ tx_dly_val << PRG_ETH0_TXDLY_SHIFT); - break; - - case PHY_INTERFACE_MODE_RMII: -@@ -286,6 +291,11 @@ static int meson8b_dwmac_probe(struct pl - goto err_remove_config_dt; - } - -+ /* use 2ns as fallback since this value was previously hardcoded */ -+ if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns", -+ &dwmac->tx_delay_ns)) -+ dwmac->tx_delay_ns = 2; -+ - ret = meson8b_init_clk(dwmac); - if (ret) - goto err_remove_config_dt; ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -@@ -302,6 +302,122 @@ static const struct rk_gmac_ops rk3288_o - .set_rmii_speed = rk3288_set_rmii_speed, - }; - -+#define RK3328_GRF_MAC_CON0 0x0900 -+#define RK3328_GRF_MAC_CON1 0x0904 -+ -+/* RK3328_GRF_MAC_CON0 */ -+#define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) -+#define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) -+ -+/* RK3328_GRF_MAC_CON1 */ -+#define RK3328_GMAC_PHY_INTF_SEL_RGMII \ -+ (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) -+#define RK3328_GMAC_PHY_INTF_SEL_RMII \ -+ (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) -+#define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) -+#define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) -+#define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) -+#define RK3328_GMAC_SPEED_100M GRF_BIT(2) -+#define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) -+#define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) -+#define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) -+#define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) -+#define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) -+#define RK3328_GMAC_RMII_MODE GRF_BIT(9) -+#define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) -+#define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) -+#define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) -+#define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) -+#define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) -+ -+static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, -+ int tx_delay, int rx_delay) -+{ -+ struct device *dev = &bsp_priv->pdev->dev; -+ -+ if (IS_ERR(bsp_priv->grf)) { -+ dev_err(dev, "Missing rockchip,grf property\n"); -+ return; -+ } -+ -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_PHY_INTF_SEL_RGMII | -+ RK3328_GMAC_RMII_MODE_CLR | -+ RK3328_GMAC_RXCLK_DLY_ENABLE | -+ RK3328_GMAC_TXCLK_DLY_ENABLE); -+ -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, -+ RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | -+ RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); -+} -+ -+static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) -+{ -+ struct device *dev = &bsp_priv->pdev->dev; -+ -+ if (IS_ERR(bsp_priv->grf)) { -+ dev_err(dev, "Missing rockchip,grf property\n"); -+ return; -+ } -+ -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_PHY_INTF_SEL_RMII | -+ RK3328_GMAC_RMII_MODE); -+ -+ /* set MAC to RMII mode */ -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11)); -+} -+ -+static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -+{ -+ struct device *dev = &bsp_priv->pdev->dev; -+ -+ if (IS_ERR(bsp_priv->grf)) { -+ dev_err(dev, "Missing rockchip,grf property\n"); -+ return; -+ } -+ -+ if (speed == 10) -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_CLK_2_5M); -+ else if (speed == 100) -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_CLK_25M); -+ else if (speed == 1000) -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_CLK_125M); -+ else -+ dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -+} -+ -+static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) -+{ -+ struct device *dev = &bsp_priv->pdev->dev; -+ -+ if (IS_ERR(bsp_priv->grf)) { -+ dev_err(dev, "Missing rockchip,grf property\n"); -+ return; -+ } -+ -+ if (speed == 10) -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_RMII_CLK_2_5M | -+ RK3328_GMAC_SPEED_10M); -+ else if (speed == 100) -+ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, -+ RK3328_GMAC_RMII_CLK_25M | -+ RK3328_GMAC_SPEED_100M); -+ else -+ dev_err(dev, "unknown speed value for RMII! speed=%d", speed); -+} -+ -+static const struct rk_gmac_ops rk3328_ops = { -+ .set_to_rgmii = rk3328_set_to_rgmii, -+ .set_to_rmii = rk3328_set_to_rmii, -+ .set_rgmii_speed = rk3328_set_rgmii_speed, -+ .set_rmii_speed = rk3328_set_rmii_speed, -+}; -+ - #define RK3366_GRF_SOC_CON6 0x0418 - #define RK3366_GRF_SOC_CON7 0x041c - -@@ -1006,6 +1122,7 @@ static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, - static const struct of_device_id rk_gmac_dwmac_match[] = { - { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, - { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, -+ { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, - { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, - { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, - { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c -@@ -351,7 +351,7 @@ static int socfpga_dwmac_probe(struct pl - * mode. Create a copy of the core reset handle so it can be used by - * the driver later. - */ -- dwmac->stmmac_rst = stpriv->stmmac_rst; -+ dwmac->stmmac_rst = stpriv->plat->stmmac_rst; - - ret = socfpga_dwmac_set_phy_mode(dwmac); - if (ret) ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h -@@ -10,10 +10,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c -@@ -16,10 +16,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -96,17 +92,13 @@ static int dwmac1000_rx_ipc_enable(struc - return !!(value & GMAC_CONTROL_IPC); - } - --static void dwmac1000_dump_regs(struct mac_device_info *hw) -+static void dwmac1000_dump_regs(struct mac_device_info *hw, u32 *reg_space) - { - void __iomem *ioaddr = hw->pcsr; - int i; -- pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr); - -- for (i = 0; i < 55; i++) { -- int offset = i * 4; -- pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i, -- offset, readl(ioaddr + offset)); -- } -+ for (i = 0; i < 55; i++) -+ reg_space[i] = readl(ioaddr + i * 4); - } - - static void dwmac1000_set_umac_addr(struct mac_device_info *hw, -@@ -347,11 +339,14 @@ static int dwmac1000_irq_status(struct m - return ret; - } - --static void dwmac1000_set_eee_mode(struct mac_device_info *hw) -+static void dwmac1000_set_eee_mode(struct mac_device_info *hw, -+ bool en_tx_lpi_clockgating) - { - void __iomem *ioaddr = hw->pcsr; - u32 value; - -+ /*TODO - en_tx_lpi_clockgating treatment */ -+ - /* Enable the link status receive on RGMII, SGMII ore SMII - * receive path and instruct the transmit to enter in LPI - * state. ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c -@@ -16,10 +16,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -205,18 +201,14 @@ static void dwmac1000_dma_operation_mode - writel(csr6, ioaddr + DMA_CONTROL); - } - --static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) -+static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space) - { - int i; -- pr_info(" DMA registers\n"); -- for (i = 0; i < 22; i++) { -- if ((i < 9) || (i > 17)) { -- int offset = i * 4; -- pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i, -- (DMA_BUS_MODE + offset), -- readl(ioaddr + DMA_BUS_MODE + offset)); -- } -- } -+ -+ for (i = 0; i < 22; i++) -+ if ((i < 9) || (i > 17)) -+ reg_space[DMA_BUS_MODE / 4 + i] = -+ readl(ioaddr + DMA_BUS_MODE + i * 4); - } - - static void dwmac1000_get_hw_feature(void __iomem *ioaddr, ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c -@@ -18,10 +18,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -44,28 +40,18 @@ static void dwmac100_core_init(struct ma - #endif - } - --static void dwmac100_dump_mac_regs(struct mac_device_info *hw) -+static void dwmac100_dump_mac_regs(struct mac_device_info *hw, u32 *reg_space) - { - void __iomem *ioaddr = hw->pcsr; -- pr_info("\t----------------------------------------------\n" -- "\t DWMAC 100 CSR (base addr = 0x%p)\n" -- "\t----------------------------------------------\n", ioaddr); -- pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL, -- readl(ioaddr + MAC_CONTROL)); -- pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH, -- readl(ioaddr + MAC_ADDR_HIGH)); -- pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW, -- readl(ioaddr + MAC_ADDR_LOW)); -- pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n", -- MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH)); -- pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n", -- MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW)); -- pr_info("\tflow control (offset 0x%x): 0x%08x\n", -- MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL)); -- pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1, -- readl(ioaddr + MAC_VLAN1)); -- pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2, -- readl(ioaddr + MAC_VLAN2)); -+ -+ reg_space[MAC_CONTROL / 4] = readl(ioaddr + MAC_CONTROL); -+ reg_space[MAC_ADDR_HIGH / 4] = readl(ioaddr + MAC_ADDR_HIGH); -+ reg_space[MAC_ADDR_LOW / 4] = readl(ioaddr + MAC_ADDR_LOW); -+ reg_space[MAC_HASH_HIGH / 4] = readl(ioaddr + MAC_HASH_HIGH); -+ reg_space[MAC_HASH_LOW / 4] = readl(ioaddr + MAC_HASH_LOW); -+ reg_space[MAC_FLOW_CTRL / 4] = readl(ioaddr + MAC_FLOW_CTRL); -+ reg_space[MAC_VLAN1 / 4] = readl(ioaddr + MAC_VLAN1); -+ reg_space[MAC_VLAN2 / 4] = readl(ioaddr + MAC_VLAN2); - } - - static int dwmac100_rx_ipc_enable(struct mac_device_info *hw) ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c -@@ -18,10 +18,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -70,19 +66,18 @@ static void dwmac100_dma_operation_mode( - writel(csr6, ioaddr + DMA_CONTROL); - } - --static void dwmac100_dump_dma_regs(void __iomem *ioaddr) -+static void dwmac100_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space) - { - int i; - -- pr_debug("DWMAC 100 DMA CSR\n"); - for (i = 0; i < 9; i++) -- pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i, -- (DMA_BUS_MODE + i * 4), -- readl(ioaddr + DMA_BUS_MODE + i * 4)); -- -- pr_debug("\tCSR20 (0x%x): 0x%08x, CSR21 (0x%x): 0x%08x\n", -- DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR), -- DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR)); -+ reg_space[DMA_BUS_MODE / 4 + i] = -+ readl(ioaddr + DMA_BUS_MODE + i * 4); -+ -+ reg_space[DMA_CUR_TX_BUF_ADDR / 4] = -+ readl(ioaddr + DMA_CUR_TX_BUF_ADDR); -+ reg_space[DMA_CUR_RX_BUF_ADDR / 4] = -+ readl(ioaddr + DMA_CUR_RX_BUF_ADDR); - } - - /* DMA controller has two counters to track the number of the missed frames. */ ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h -@@ -22,6 +22,7 @@ - #define GMAC_HASH_TAB_32_63 0x00000014 - #define GMAC_RX_FLOW_CTRL 0x00000090 - #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4) -+#define GMAC_RXQ_CTRL0 0x000000a0 - #define GMAC_INT_STATUS 0x000000b0 - #define GMAC_INT_EN 0x000000b4 - #define GMAC_PCS_BASE 0x000000e0 -@@ -44,6 +45,11 @@ - - #define GMAC_MAX_PERFECT_ADDRESSES 128 - -+/* MAC RX Queue Enable */ -+#define GMAC_RX_QUEUE_CLEAR(queue) ~(GENMASK(1, 0) << ((queue) * 2)) -+#define GMAC_RX_AV_QUEUE_ENABLE(queue) BIT((queue) * 2) -+#define GMAC_RX_DCB_QUEUE_ENABLE(queue) BIT(((queue) * 2) + 1) -+ - /* MAC Flow Control RX */ - #define GMAC_RX_FLOW_CTRL_RFE BIT(0) - -@@ -84,6 +90,19 @@ enum power_event { - power_down = 0x00000001, - }; - -+/* Energy Efficient Ethernet (EEE) for GMAC4 -+ * -+ * LPI status, timer and control register offset -+ */ -+#define GMAC4_LPI_CTRL_STATUS 0xd0 -+#define GMAC4_LPI_TIMER_CTRL 0xd4 -+ -+/* LPI control and status defines */ -+#define GMAC4_LPI_CTRL_STATUS_LPITCSE BIT(21) /* LPI Tx Clock Stop Enable */ -+#define GMAC4_LPI_CTRL_STATUS_LPITXA BIT(19) /* Enable LPI TX Automate */ -+#define GMAC4_LPI_CTRL_STATUS_PLS BIT(17) /* PHY Link Status */ -+#define GMAC4_LPI_CTRL_STATUS_LPIEN BIT(16) /* LPI Enable */ -+ - /* MAC Debug bitmap */ - #define GMAC_DEBUG_TFCSTS_MASK GENMASK(18, 17) - #define GMAC_DEBUG_TFCSTS_SHIFT 17 -@@ -133,6 +152,8 @@ enum power_event { - /* MAC HW features2 bitmap */ - #define GMAC_HW_FEAT_TXCHCNT GENMASK(21, 18) - #define GMAC_HW_FEAT_RXCHCNT GENMASK(15, 12) -+#define GMAC_HW_FEAT_TXQCNT GENMASK(9, 6) -+#define GMAC_HW_FEAT_RXQCNT GENMASK(3, 0) - - /* MAC HW ADDR regs */ - #define GMAC_HI_DCS GENMASK(18, 16) ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c -@@ -59,19 +59,24 @@ static void dwmac4_core_init(struct mac_ - writel(value, ioaddr + GMAC_INT_EN); - } - --static void dwmac4_dump_regs(struct mac_device_info *hw) -+static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue) - { - void __iomem *ioaddr = hw->pcsr; -- int i; -+ u32 value = readl(ioaddr + GMAC_RXQ_CTRL0); - -- pr_debug("\tDWMAC4 regs (base addr = 0x%p)\n", ioaddr); -+ value &= GMAC_RX_QUEUE_CLEAR(queue); -+ value |= GMAC_RX_AV_QUEUE_ENABLE(queue); - -- for (i = 0; i < GMAC_REG_NUM; i++) { -- int offset = i * 4; -+ writel(value, ioaddr + GMAC_RXQ_CTRL0); -+} - -- pr_debug("\tReg No. %d (offset 0x%x): 0x%08x\n", i, -- offset, readl(ioaddr + offset)); -- } -+static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) -+{ -+ void __iomem *ioaddr = hw->pcsr; -+ int i; -+ -+ for (i = 0; i < GMAC_REG_NUM; i++) -+ reg_space[i] = readl(ioaddr + i * 4); - } - - static int dwmac4_rx_ipc_enable(struct mac_device_info *hw) -@@ -126,6 +131,65 @@ static void dwmac4_get_umac_addr(struct - GMAC_ADDR_LOW(reg_n)); - } - -+static void dwmac4_set_eee_mode(struct mac_device_info *hw, -+ bool en_tx_lpi_clockgating) -+{ -+ void __iomem *ioaddr = hw->pcsr; -+ u32 value; -+ -+ /* Enable the link status receive on RGMII, SGMII ore SMII -+ * receive path and instruct the transmit to enter in LPI -+ * state. -+ */ -+ value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); -+ value |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA; -+ -+ if (en_tx_lpi_clockgating) -+ value |= GMAC4_LPI_CTRL_STATUS_LPITCSE; -+ -+ writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); -+} -+ -+static void dwmac4_reset_eee_mode(struct mac_device_info *hw) -+{ -+ void __iomem *ioaddr = hw->pcsr; -+ u32 value; -+ -+ value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); -+ value &= ~(GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA); -+ writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); -+} -+ -+static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link) -+{ -+ void __iomem *ioaddr = hw->pcsr; -+ u32 value; -+ -+ value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); -+ -+ if (link) -+ value |= GMAC4_LPI_CTRL_STATUS_PLS; -+ else -+ value &= ~GMAC4_LPI_CTRL_STATUS_PLS; -+ -+ writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); -+} -+ -+static void dwmac4_set_eee_timer(struct mac_device_info *hw, int ls, int tw) -+{ -+ void __iomem *ioaddr = hw->pcsr; -+ int value = ((tw & 0xffff)) | ((ls & 0x3ff) << 16); -+ -+ /* Program the timers in the LPI timer control register: -+ * LS: minimum time (ms) for which the link -+ * status from PHY should be ok before transmitting -+ * the LPI pattern. -+ * TW: minimum time (us) for which the core waits -+ * after it has stopped transmitting the LPI pattern. -+ */ -+ writel(value, ioaddr + GMAC4_LPI_TIMER_CTRL); -+} -+ - static void dwmac4_set_filter(struct mac_device_info *hw, - struct net_device *dev) - { -@@ -392,12 +456,17 @@ static void dwmac4_debug(void __iomem *i - static const struct stmmac_ops dwmac4_ops = { - .core_init = dwmac4_core_init, - .rx_ipc = dwmac4_rx_ipc_enable, -+ .rx_queue_enable = dwmac4_rx_queue_enable, - .dump_regs = dwmac4_dump_regs, - .host_irq_status = dwmac4_irq_status, - .flow_ctrl = dwmac4_flow_ctrl, - .pmt = dwmac4_pmt, - .set_umac_addr = dwmac4_set_umac_addr, - .get_umac_addr = dwmac4_get_umac_addr, -+ .set_eee_mode = dwmac4_set_eee_mode, -+ .reset_eee_mode = dwmac4_reset_eee_mode, -+ .set_eee_timer = dwmac4_set_eee_timer, -+ .set_eee_pls = dwmac4_set_eee_pls, - .pcs_ctrl_ane = dwmac4_ctrl_ane, - .pcs_rane = dwmac4_rane, - .pcs_get_adv_lp = dwmac4_get_adv_lp, ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c -@@ -103,7 +103,7 @@ static int dwmac4_wrback_get_rx_status(v - x->rx_mii++; - - if (unlikely(rdes3 & RDES3_CRC_ERROR)) { -- x->rx_crc++; -+ x->rx_crc_errors++; - stats->rx_crc_errors++; - } - ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c -@@ -127,53 +127,51 @@ static void dwmac4_dma_init(void __iomem - dwmac4_dma_init_channel(ioaddr, dma_cfg, dma_tx, dma_rx, i); - } - --static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel) -+static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel, -+ u32 *reg_space) - { -- pr_debug(" Channel %d\n", channel); -- pr_debug("\tDMA_CHAN_CONTROL, offset: 0x%x, val: 0x%x\n", 0, -- readl(ioaddr + DMA_CHAN_CONTROL(channel))); -- pr_debug("\tDMA_CHAN_TX_CONTROL, offset: 0x%x, val: 0x%x\n", 0x4, -- readl(ioaddr + DMA_CHAN_TX_CONTROL(channel))); -- pr_debug("\tDMA_CHAN_RX_CONTROL, offset: 0x%x, val: 0x%x\n", 0x8, -- readl(ioaddr + DMA_CHAN_RX_CONTROL(channel))); -- pr_debug("\tDMA_CHAN_TX_BASE_ADDR, offset: 0x%x, val: 0x%x\n", 0x14, -- readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(channel))); -- pr_debug("\tDMA_CHAN_RX_BASE_ADDR, offset: 0x%x, val: 0x%x\n", 0x1c, -- readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(channel))); -- pr_debug("\tDMA_CHAN_TX_END_ADDR, offset: 0x%x, val: 0x%x\n", 0x20, -- readl(ioaddr + DMA_CHAN_TX_END_ADDR(channel))); -- pr_debug("\tDMA_CHAN_RX_END_ADDR, offset: 0x%x, val: 0x%x\n", 0x28, -- readl(ioaddr + DMA_CHAN_RX_END_ADDR(channel))); -- pr_debug("\tDMA_CHAN_TX_RING_LEN, offset: 0x%x, val: 0x%x\n", 0x2c, -- readl(ioaddr + DMA_CHAN_TX_RING_LEN(channel))); -- pr_debug("\tDMA_CHAN_RX_RING_LEN, offset: 0x%x, val: 0x%x\n", 0x30, -- readl(ioaddr + DMA_CHAN_RX_RING_LEN(channel))); -- pr_debug("\tDMA_CHAN_INTR_ENA, offset: 0x%x, val: 0x%x\n", 0x34, -- readl(ioaddr + DMA_CHAN_INTR_ENA(channel))); -- pr_debug("\tDMA_CHAN_RX_WATCHDOG, offset: 0x%x, val: 0x%x\n", 0x38, -- readl(ioaddr + DMA_CHAN_RX_WATCHDOG(channel))); -- pr_debug("\tDMA_CHAN_SLOT_CTRL_STATUS, offset: 0x%x, val: 0x%x\n", 0x3c, -- readl(ioaddr + DMA_CHAN_SLOT_CTRL_STATUS(channel))); -- pr_debug("\tDMA_CHAN_CUR_TX_DESC, offset: 0x%x, val: 0x%x\n", 0x44, -- readl(ioaddr + DMA_CHAN_CUR_TX_DESC(channel))); -- pr_debug("\tDMA_CHAN_CUR_RX_DESC, offset: 0x%x, val: 0x%x\n", 0x4c, -- readl(ioaddr + DMA_CHAN_CUR_RX_DESC(channel))); -- pr_debug("\tDMA_CHAN_CUR_TX_BUF_ADDR, offset: 0x%x, val: 0x%x\n", 0x54, -- readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(channel))); -- pr_debug("\tDMA_CHAN_CUR_RX_BUF_ADDR, offset: 0x%x, val: 0x%x\n", 0x5c, -- readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(channel))); -- pr_debug("\tDMA_CHAN_STATUS, offset: 0x%x, val: 0x%x\n", 0x60, -- readl(ioaddr + DMA_CHAN_STATUS(channel))); -+ reg_space[DMA_CHAN_CONTROL(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_CONTROL(channel)); -+ reg_space[DMA_CHAN_TX_CONTROL(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_TX_CONTROL(channel)); -+ reg_space[DMA_CHAN_RX_CONTROL(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_RX_CONTROL(channel)); -+ reg_space[DMA_CHAN_TX_BASE_ADDR(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(channel)); -+ reg_space[DMA_CHAN_RX_BASE_ADDR(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(channel)); -+ reg_space[DMA_CHAN_TX_END_ADDR(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_TX_END_ADDR(channel)); -+ reg_space[DMA_CHAN_RX_END_ADDR(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_RX_END_ADDR(channel)); -+ reg_space[DMA_CHAN_TX_RING_LEN(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_TX_RING_LEN(channel)); -+ reg_space[DMA_CHAN_RX_RING_LEN(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_RX_RING_LEN(channel)); -+ reg_space[DMA_CHAN_INTR_ENA(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_INTR_ENA(channel)); -+ reg_space[DMA_CHAN_RX_WATCHDOG(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_RX_WATCHDOG(channel)); -+ reg_space[DMA_CHAN_SLOT_CTRL_STATUS(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_SLOT_CTRL_STATUS(channel)); -+ reg_space[DMA_CHAN_CUR_TX_DESC(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_CUR_TX_DESC(channel)); -+ reg_space[DMA_CHAN_CUR_RX_DESC(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_CUR_RX_DESC(channel)); -+ reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(channel)); -+ reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(channel)); -+ reg_space[DMA_CHAN_STATUS(channel) / 4] = -+ readl(ioaddr + DMA_CHAN_STATUS(channel)); - } - --static void dwmac4_dump_dma_regs(void __iomem *ioaddr) -+static void dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space) - { - int i; - -- pr_debug(" GMAC4 DMA registers\n"); -- - for (i = 0; i < DMA_CHANNEL_NB_MAX; i++) -- _dwmac4_dump_dma_regs(ioaddr, i); -+ _dwmac4_dump_dma_regs(ioaddr, i, reg_space); - } - - static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt) -@@ -303,6 +301,11 @@ static void dwmac4_get_hw_feature(void _ - ((hw_cap & GMAC_HW_FEAT_RXCHCNT) >> 12) + 1; - dma_cap->number_tx_channel = - ((hw_cap & GMAC_HW_FEAT_TXCHCNT) >> 18) + 1; -+ /* TX and RX number of queues */ -+ dma_cap->number_rx_queues = -+ ((hw_cap & GMAC_HW_FEAT_RXQCNT) >> 0) + 1; -+ dma_cap->number_tx_queues = -+ ((hw_cap & GMAC_HW_FEAT_TXQCNT) >> 6) + 1; - - /* IEEE 1588-2002 */ - dma_cap->time_stamp = 0; ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -@@ -10,10 +10,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -21,6 +17,7 @@ - *******************************************************************************/ - - #include <linux/io.h> -+#include <linux/iopoll.h> - #include "common.h" - #include "dwmac_dma.h" - -@@ -29,19 +26,16 @@ - int dwmac_dma_reset(void __iomem *ioaddr) - { - u32 value = readl(ioaddr + DMA_BUS_MODE); -- int limit; -+ int err; - - /* DMA SW reset */ - value |= DMA_BUS_MODE_SFT_RESET; - writel(value, ioaddr + DMA_BUS_MODE); -- limit = 10; -- while (limit--) { -- if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) -- break; -- mdelay(10); -- } - -- if (limit < 0) -+ err = readl_poll_timeout(ioaddr + DMA_BUS_MODE, value, -+ !(value & DMA_BUS_MODE_SFT_RESET), -+ 100000, 10000); -+ if (err) - return -EBUSY; - - return 0; -@@ -102,7 +96,7 @@ static void show_tx_process_state(unsign - pr_debug("- TX (Stopped): Reset or Stop command\n"); - break; - case 1: -- pr_debug("- TX (Running):Fetching the Tx desc\n"); -+ pr_debug("- TX (Running): Fetching the Tx desc\n"); - break; - case 2: - pr_debug("- TX (Running): Waiting for end of tx\n"); -@@ -136,7 +130,7 @@ static void show_rx_process_state(unsign - pr_debug("- RX (Running): Fetching the Rx desc\n"); - break; - case 2: -- pr_debug("- RX (Running):Checking for end of pkt\n"); -+ pr_debug("- RX (Running): Checking for end of pkt\n"); - break; - case 3: - pr_debug("- RX (Running): Waiting for Rx pkt\n"); -@@ -246,7 +240,7 @@ void stmmac_set_mac_addr(void __iomem *i - unsigned long data; - - data = (addr[5] << 8) | addr[4]; -- /* For MAC Addr registers se have to set the Address Enable (AE) -+ /* For MAC Addr registers we have to set the Address Enable (AE) - * bit that has no effect on the High Reg 0 where the bit 31 (MO) - * is RO. - */ -@@ -261,9 +255,9 @@ void stmmac_set_mac(void __iomem *ioaddr - u32 value = readl(ioaddr + MAC_CTRL_REG); - - if (enable) -- value |= MAC_RNABLE_RX | MAC_ENABLE_TX; -+ value |= MAC_ENABLE_RX | MAC_ENABLE_TX; - else -- value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX); -+ value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX); - - writel(value, ioaddr + MAC_CTRL_REG); - } ---- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c -+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -225,7 +221,7 @@ static int enh_desc_get_rx_status(void * - x->rx_mii++; - - if (unlikely(rdes0 & RDES0_CRC_ERROR)) { -- x->rx_crc++; -+ x->rx_crc_errors++; - stats->rx_crc_errors++; - } - ret = discard_frame; ---- a/drivers/net/ethernet/stmicro/stmmac/mmc.h -+++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c -+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -115,7 +111,7 @@ static int ndesc_get_rx_status(void *dat - stats->collisions++; - } - if (unlikely(rdes0 & RDES0_CRC_ERROR)) { -- x->rx_crc++; -+ x->rx_crc_errors++; - stats->rx_crc_errors++; - } - ret = discard_frame; ---- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c -+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c -@@ -16,10 +16,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -@@ -10,10 +10,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -106,9 +102,6 @@ struct stmmac_priv { - u32 msg_enable; - int wolopts; - int wol_irq; -- struct clk *stmmac_clk; -- struct clk *pclk; -- struct reset_control *stmmac_rst; - int clk_csr; - struct timer_list eee_ctrl_timer; - int lpi_irq; -@@ -120,8 +113,6 @@ struct stmmac_priv { - struct ptp_clock *ptp_clock; - struct ptp_clock_info ptp_clock_ops; - unsigned int default_addend; -- struct clk *clk_ptp_ref; -- unsigned int clk_ptp_rate; - u32 adv_ts; - int use_riwt; - int irq_wake; ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -65,7 +61,7 @@ static const struct stmmac_stats stmmac_ - STMMAC_STAT(overflow_error), - STMMAC_STAT(ipc_csum_error), - STMMAC_STAT(rx_collision), -- STMMAC_STAT(rx_crc), -+ STMMAC_STAT(rx_crc_errors), - STMMAC_STAT(dribbling_bit), - STMMAC_STAT(rx_length), - STMMAC_STAT(rx_mii), -@@ -439,32 +435,14 @@ static int stmmac_ethtool_get_regs_len(s - static void stmmac_ethtool_gregs(struct net_device *dev, - struct ethtool_regs *regs, void *space) - { -- int i; - u32 *reg_space = (u32 *) space; - - struct stmmac_priv *priv = netdev_priv(dev); - - memset(reg_space, 0x0, REG_SPACE_SIZE); - -- if (!(priv->plat->has_gmac || priv->plat->has_gmac4)) { -- /* MAC registers */ -- for (i = 0; i < 12; i++) -- reg_space[i] = readl(priv->ioaddr + (i * 4)); -- /* DMA registers */ -- for (i = 0; i < 9; i++) -- reg_space[i + 12] = -- readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); -- reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR); -- reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR); -- } else { -- /* MAC registers */ -- for (i = 0; i < 55; i++) -- reg_space[i] = readl(priv->ioaddr + (i * 4)); -- /* DMA registers */ -- for (i = 0; i < 22; i++) -- reg_space[i + 55] = -- readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); -- } -+ priv->hw->mac->dump_regs(priv->hw, reg_space); -+ priv->hw->dma->dump_regs(priv->ioaddr, reg_space); - } - - static void -@@ -712,7 +690,7 @@ static int stmmac_ethtool_op_set_eee(str - - static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv) - { -- unsigned long clk = clk_get_rate(priv->stmmac_clk); -+ unsigned long clk = clk_get_rate(priv->plat->stmmac_clk); - - if (!clk) - return 0; -@@ -722,7 +700,7 @@ static u32 stmmac_usec2riwt(u32 usec, st - - static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv) - { -- unsigned long clk = clk_get_rate(priv->stmmac_clk); -+ unsigned long clk = clk_get_rate(priv->plat->stmmac_clk); - - if (!clk) - return 0; ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -13,10 +13,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -158,7 +154,7 @@ static void stmmac_clk_csr_set(struct st - { - u32 clk_rate; - -- clk_rate = clk_get_rate(priv->stmmac_clk); -+ clk_rate = clk_get_rate(priv->plat->stmmac_clk); - - /* Platform provided default clk_csr would be assumed valid - * for all other cases except for the below mentioned ones. -@@ -191,7 +187,7 @@ static void print_pkt(unsigned char *buf - - static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) - { -- unsigned avail; -+ u32 avail; - - if (priv->dirty_tx > priv->cur_tx) - avail = priv->dirty_tx - priv->cur_tx - 1; -@@ -203,7 +199,7 @@ static inline u32 stmmac_tx_avail(struct - - static inline u32 stmmac_rx_dirty(struct stmmac_priv *priv) - { -- unsigned dirty; -+ u32 dirty; - - if (priv->dirty_rx <= priv->cur_rx) - dirty = priv->cur_rx - priv->dirty_rx; -@@ -216,7 +212,7 @@ static inline u32 stmmac_rx_dirty(struct - /** - * stmmac_hw_fix_mac_speed - callback for speed selection - * @priv: driver private structure -- * Description: on some platforms (e.g. ST), some HW system configuraton -+ * Description: on some platforms (e.g. ST), some HW system configuration - * registers have to be set according to the link speed negotiated. - */ - static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) -@@ -239,7 +235,8 @@ static void stmmac_enable_eee_mode(struc - /* Check and enter in LPI mode */ - if ((priv->dirty_tx == priv->cur_tx) && - (priv->tx_path_in_lpi_mode == false)) -- priv->hw->mac->set_eee_mode(priv->hw); -+ priv->hw->mac->set_eee_mode(priv->hw, -+ priv->plat->en_tx_lpi_clockgating); - } - - /** -@@ -421,7 +418,7 @@ static void stmmac_get_rx_hwtstamp(struc - /** - * stmmac_hwtstamp_ioctl - control hardware timestamping. - * @dev: device pointer. -- * @ifr: An IOCTL specefic structure, that can contain a pointer to -+ * @ifr: An IOCTL specific structure, that can contain a pointer to - * a proprietary structure used to pass information to the driver. - * Description: - * This function configures the MAC to enable/disable both outgoing(TX) -@@ -621,7 +618,7 @@ static int stmmac_hwtstamp_ioctl(struct - - /* program Sub Second Increment reg */ - sec_inc = priv->hw->ptp->config_sub_second_increment( -- priv->ptpaddr, priv->clk_ptp_rate, -+ priv->ptpaddr, priv->plat->clk_ptp_rate, - priv->plat->has_gmac4); - temp = div_u64(1000000000ULL, sec_inc); - -@@ -631,7 +628,7 @@ static int stmmac_hwtstamp_ioctl(struct - * where, freq_div_ratio = 1e9ns/sec_inc - */ - temp = (u64)(temp << 32); -- priv->default_addend = div_u64(temp, priv->clk_ptp_rate); -+ priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); - priv->hw->ptp->config_addend(priv->ptpaddr, - priv->default_addend); - -@@ -659,18 +656,6 @@ static int stmmac_init_ptp(struct stmmac - if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) - return -EOPNOTSUPP; - -- /* Fall-back to main clock in case of no PTP ref is passed */ -- priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref"); -- if (IS_ERR(priv->clk_ptp_ref)) { -- priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk); -- priv->clk_ptp_ref = NULL; -- netdev_dbg(priv->dev, "PTP uses main clock\n"); -- } else { -- clk_prepare_enable(priv->clk_ptp_ref); -- priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref); -- netdev_dbg(priv->dev, "PTP rate %d\n", priv->clk_ptp_rate); -- } -- - priv->adv_ts = 0; - /* Check if adv_ts can be enabled for dwmac 4.x core */ - if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp) -@@ -697,8 +682,8 @@ static int stmmac_init_ptp(struct stmmac - - static void stmmac_release_ptp(struct stmmac_priv *priv) - { -- if (priv->clk_ptp_ref) -- clk_disable_unprepare(priv->clk_ptp_ref); -+ if (priv->plat->clk_ptp_ref) -+ clk_disable_unprepare(priv->plat->clk_ptp_ref); - stmmac_ptp_unregister(priv); - } - -@@ -719,7 +704,7 @@ static void stmmac_adjust_link(struct ne - int new_state = 0; - unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; - -- if (phydev == NULL) -+ if (!phydev) - return; - - spin_lock_irqsave(&priv->lock, flags); -@@ -746,33 +731,36 @@ static void stmmac_adjust_link(struct ne - new_state = 1; - switch (phydev->speed) { - case 1000: -- if (likely((priv->plat->has_gmac) || -- (priv->plat->has_gmac4))) -+ if (priv->plat->has_gmac || -+ priv->plat->has_gmac4) - ctrl &= ~priv->hw->link.port; -- stmmac_hw_fix_mac_speed(priv); - break; - case 100: -+ if (priv->plat->has_gmac || -+ priv->plat->has_gmac4) { -+ ctrl |= priv->hw->link.port; -+ ctrl |= priv->hw->link.speed; -+ } else { -+ ctrl &= ~priv->hw->link.port; -+ } -+ break; - case 10: -- if (likely((priv->plat->has_gmac) || -- (priv->plat->has_gmac4))) { -+ if (priv->plat->has_gmac || -+ priv->plat->has_gmac4) { - ctrl |= priv->hw->link.port; -- if (phydev->speed == SPEED_100) { -- ctrl |= priv->hw->link.speed; -- } else { -- ctrl &= ~(priv->hw->link.speed); -- } -+ ctrl &= ~(priv->hw->link.speed); - } else { - ctrl &= ~priv->hw->link.port; - } -- stmmac_hw_fix_mac_speed(priv); - break; - default: - netif_warn(priv, link, priv->dev, -- "Speed (%d) not 10/100\n", -- phydev->speed); -+ "broken speed: %d\n", phydev->speed); -+ phydev->speed = SPEED_UNKNOWN; - break; - } -- -+ if (phydev->speed != SPEED_UNKNOWN) -+ stmmac_hw_fix_mac_speed(priv); - priv->speed = phydev->speed; - } - -@@ -785,8 +773,8 @@ static void stmmac_adjust_link(struct ne - } else if (priv->oldlink) { - new_state = 1; - priv->oldlink = 0; -- priv->speed = 0; -- priv->oldduplex = -1; -+ priv->speed = SPEED_UNKNOWN; -+ priv->oldduplex = DUPLEX_UNKNOWN; - } - - if (new_state && netif_msg_link(priv)) -@@ -848,8 +836,8 @@ static int stmmac_init_phy(struct net_de - int interface = priv->plat->interface; - int max_speed = priv->plat->max_speed; - priv->oldlink = 0; -- priv->speed = 0; -- priv->oldduplex = -1; -+ priv->speed = SPEED_UNKNOWN; -+ priv->oldduplex = DUPLEX_UNKNOWN; - - if (priv->plat->phy_node) { - phydev = of_phy_connect(dev, priv->plat->phy_node, -@@ -901,9 +889,7 @@ static int stmmac_init_phy(struct net_de - if (phydev->is_pseudo_fixed_link) - phydev->irq = PHY_POLL; - -- netdev_dbg(priv->dev, "%s: attached to PHY (UID 0x%x) Link = %d\n", -- __func__, phydev->phy_id, phydev->link); -- -+ phy_attached_info(phydev); - return 0; - } - -@@ -1029,7 +1015,7 @@ static void stmmac_free_rx_buffers(struc - * @dev: net device structure - * @flags: gfp flag. - * Description: this function initializes the DMA RX/TX descriptors -- * and allocates the socket buffers. It suppors the chained and ring -+ * and allocates the socket buffers. It supports the chained and ring - * modes. - */ - static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) -@@ -1142,13 +1128,6 @@ static void dma_free_tx_skbufs(struct st - int i; - - for (i = 0; i < DMA_TX_SIZE; i++) { -- struct dma_desc *p; -- -- if (priv->extend_desc) -- p = &((priv->dma_etx + i)->basic); -- else -- p = priv->dma_tx + i; -- - if (priv->tx_skbuff_dma[i].buf) { - if (priv->tx_skbuff_dma[i].map_as_page) - dma_unmap_page(priv->device, -@@ -1162,7 +1141,7 @@ static void dma_free_tx_skbufs(struct st - DMA_TO_DEVICE); - } - -- if (priv->tx_skbuff[i] != NULL) { -+ if (priv->tx_skbuff[i]) { - dev_kfree_skb_any(priv->tx_skbuff[i]); - priv->tx_skbuff[i] = NULL; - priv->tx_skbuff_dma[i].buf = 0; -@@ -1286,6 +1265,28 @@ static void free_dma_desc_resources(stru - } - - /** -+ * stmmac_mac_enable_rx_queues - Enable MAC rx queues -+ * @priv: driver private structure -+ * Description: It is used for enabling the rx queues in the MAC -+ */ -+static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv) -+{ -+ int rx_count = priv->dma_cap.number_rx_queues; -+ int queue = 0; -+ -+ /* If GMAC does not have multiple queues, then this is not necessary*/ -+ if (rx_count == 1) -+ return; -+ -+ /** -+ * If the core is synthesized with multiple rx queues / multiple -+ * dma channels, then rx queues will be disabled by default. -+ * For now only rx queue 0 is enabled. -+ */ -+ priv->hw->mac->rx_queue_enable(priv->hw, queue); -+} -+ -+/** - * stmmac_dma_operation_mode - HW DMA operation mode - * @priv: driver private structure - * Description: it is used for configuring the DMA operation mode register in -@@ -1691,10 +1692,6 @@ static int stmmac_hw_setup(struct net_de - /* Copy the MAC addr into the HW */ - priv->hw->mac->set_umac_addr(priv->hw, dev->dev_addr, 0); - -- /* If required, perform hw setup of the bus. */ -- if (priv->plat->bus_setup) -- priv->plat->bus_setup(priv->ioaddr); -- - /* PS and related bits will be programmed according to the speed */ - if (priv->hw->pcs) { - int speed = priv->plat->mac_port_sel_speed; -@@ -1711,6 +1708,10 @@ static int stmmac_hw_setup(struct net_de - /* Initialize the MAC Core */ - priv->hw->mac->core_init(priv->hw, dev->mtu); - -+ /* Initialize MAC RX Queues */ -+ if (priv->hw->mac->rx_queue_enable) -+ stmmac_mac_enable_rx_queues(priv); -+ - ret = priv->hw->mac->rx_ipc(priv->hw); - if (!ret) { - netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n"); -@@ -1731,8 +1732,10 @@ static int stmmac_hw_setup(struct net_de - - if (init_ptp) { - ret = stmmac_init_ptp(priv); -- if (ret) -- netdev_warn(priv->dev, "fail to init PTP.\n"); -+ if (ret == -EOPNOTSUPP) -+ netdev_warn(priv->dev, "PTP not supported by HW\n"); -+ else if (ret) -+ netdev_warn(priv->dev, "PTP init failed\n"); - } - - #ifdef CONFIG_DEBUG_FS -@@ -1746,11 +1749,6 @@ static int stmmac_hw_setup(struct net_de - priv->hw->dma->start_tx(priv->ioaddr); - priv->hw->dma->start_rx(priv->ioaddr); - -- /* Dump DMA/MAC registers */ -- if (netif_msg_hw(priv)) { -- priv->hw->mac->dump_regs(priv->hw); -- priv->hw->dma->dump_regs(priv->ioaddr); -- } - priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; - - if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { -@@ -2547,7 +2545,7 @@ static int stmmac_rx(struct stmmac_priv - if (unlikely(status == discard_frame)) { - priv->dev->stats.rx_errors++; - if (priv->hwts_rx_en && !priv->extend_desc) { -- /* DESC2 & DESC3 will be overwitten by device -+ /* DESC2 & DESC3 will be overwritten by device - * with timestamp value, hence reinitialize - * them in stmmac_rx_refill() function so that - * device can reuse it. -@@ -2570,7 +2568,7 @@ static int stmmac_rx(struct stmmac_priv - - frame_len = priv->hw->desc->get_rx_frame_len(p, coe); - -- /* If frame length is greather than skb buffer size -+ /* If frame length is greater than skb buffer size - * (preallocated during init) then the packet is - * ignored - */ -@@ -2790,7 +2788,7 @@ static netdev_features_t stmmac_fix_feat - /* Some GMAC devices have a bugged Jumbo frame support that - * needs to have the Tx COE disabled for oversized frames - * (due to limited buffer sizes). In this case we disable -- * the TX csum insertionin the TDES and not use SF. -+ * the TX csum insertion in the TDES and not use SF. - */ - if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) - features &= ~NETIF_F_CSUM_MASK; -@@ -2936,9 +2934,7 @@ static void sysfs_display_ring(void *hea - struct dma_desc *p = (struct dma_desc *)head; - - for (i = 0; i < size; i++) { -- u64 x; - if (extend_desc) { -- x = *(u64 *) ep; - seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", - i, (unsigned int)virt_to_phys(ep), - le32_to_cpu(ep->basic.des0), -@@ -2947,7 +2943,6 @@ static void sysfs_display_ring(void *hea - le32_to_cpu(ep->basic.des3)); - ep++; - } else { -- x = *(u64 *) p; - seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", - i, (unsigned int)virt_to_phys(ep), - le32_to_cpu(p->des0), le32_to_cpu(p->des1), -@@ -3017,7 +3012,7 @@ static int stmmac_sysfs_dma_cap_read(str - (priv->dma_cap.hash_filter) ? "Y" : "N"); - seq_printf(seq, "\tMultiple MAC address registers: %s\n", - (priv->dma_cap.multi_addr) ? "Y" : "N"); -- seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", -+ seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfaces): %s\n", - (priv->dma_cap.pcs) ? "Y" : "N"); - seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", - (priv->dma_cap.sma_mdio) ? "Y" : "N"); -@@ -3293,44 +3288,8 @@ int stmmac_dvr_probe(struct device *devi - if ((phyaddr >= 0) && (phyaddr <= 31)) - priv->plat->phy_addr = phyaddr; - -- priv->stmmac_clk = devm_clk_get(priv->device, STMMAC_RESOURCE_NAME); -- if (IS_ERR(priv->stmmac_clk)) { -- netdev_warn(priv->dev, "%s: warning: cannot get CSR clock\n", -- __func__); -- /* If failed to obtain stmmac_clk and specific clk_csr value -- * is NOT passed from the platform, probe fail. -- */ -- if (!priv->plat->clk_csr) { -- ret = PTR_ERR(priv->stmmac_clk); -- goto error_clk_get; -- } else { -- priv->stmmac_clk = NULL; -- } -- } -- clk_prepare_enable(priv->stmmac_clk); -- -- priv->pclk = devm_clk_get(priv->device, "pclk"); -- if (IS_ERR(priv->pclk)) { -- if (PTR_ERR(priv->pclk) == -EPROBE_DEFER) { -- ret = -EPROBE_DEFER; -- goto error_pclk_get; -- } -- priv->pclk = NULL; -- } -- clk_prepare_enable(priv->pclk); -- -- priv->stmmac_rst = devm_reset_control_get(priv->device, -- STMMAC_RESOURCE_NAME); -- if (IS_ERR(priv->stmmac_rst)) { -- if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) { -- ret = -EPROBE_DEFER; -- goto error_hw_init; -- } -- dev_info(priv->device, "no reset control found\n"); -- priv->stmmac_rst = NULL; -- } -- if (priv->stmmac_rst) -- reset_control_deassert(priv->stmmac_rst); -+ if (priv->plat->stmmac_rst) -+ reset_control_deassert(priv->plat->stmmac_rst); - - /* Init MAC and get the capabilities */ - ret = stmmac_hw_init(priv); -@@ -3416,10 +3375,6 @@ error_netdev_register: - error_mdio_register: - netif_napi_del(&priv->napi); - error_hw_init: -- clk_disable_unprepare(priv->pclk); --error_pclk_get: -- clk_disable_unprepare(priv->stmmac_clk); --error_clk_get: - free_netdev(ndev); - - return ret; -@@ -3445,10 +3400,10 @@ int stmmac_dvr_remove(struct device *dev - stmmac_set_mac(priv->ioaddr, false); - netif_carrier_off(ndev); - unregister_netdev(ndev); -- if (priv->stmmac_rst) -- reset_control_assert(priv->stmmac_rst); -- clk_disable_unprepare(priv->pclk); -- clk_disable_unprepare(priv->stmmac_clk); -+ if (priv->plat->stmmac_rst) -+ reset_control_assert(priv->plat->stmmac_rst); -+ clk_disable_unprepare(priv->plat->pclk); -+ clk_disable_unprepare(priv->plat->stmmac_clk); - if (priv->hw->pcs != STMMAC_PCS_RGMII && - priv->hw->pcs != STMMAC_PCS_TBI && - priv->hw->pcs != STMMAC_PCS_RTBI) -@@ -3497,14 +3452,14 @@ int stmmac_suspend(struct device *dev) - stmmac_set_mac(priv->ioaddr, false); - pinctrl_pm_select_sleep_state(priv->device); - /* Disable clock in case of PWM is off */ -- clk_disable(priv->pclk); -- clk_disable(priv->stmmac_clk); -+ clk_disable(priv->plat->pclk); -+ clk_disable(priv->plat->stmmac_clk); - } - spin_unlock_irqrestore(&priv->lock, flags); - - priv->oldlink = 0; -- priv->speed = 0; -- priv->oldduplex = -1; -+ priv->speed = SPEED_UNKNOWN; -+ priv->oldduplex = DUPLEX_UNKNOWN; - return 0; - } - EXPORT_SYMBOL_GPL(stmmac_suspend); -@@ -3537,9 +3492,9 @@ int stmmac_resume(struct device *dev) - priv->irq_wake = 0; - } else { - pinctrl_pm_select_default_state(priv->device); -- /* enable the clk prevously disabled */ -- clk_enable(priv->stmmac_clk); -- clk_enable(priv->pclk); -+ /* enable the clk previously disabled */ -+ clk_enable(priv->plat->stmmac_clk); -+ clk_enable(priv->plat->pclk); - /* reset the phy so that it's ready */ - if (priv->mii) - stmmac_mdio_reset(priv->mii); ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c -@@ -13,10 +13,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -24,13 +20,14 @@ - Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com> - *******************************************************************************/ - -+#include <linux/io.h> -+#include <linux/iopoll.h> - #include <linux/mii.h> --#include <linux/phy.h> --#include <linux/slab.h> - #include <linux/of.h> - #include <linux/of_gpio.h> - #include <linux/of_mdio.h> --#include <asm/io.h> -+#include <linux/phy.h> -+#include <linux/slab.h> - - #include "stmmac.h" - -@@ -42,22 +39,6 @@ - #define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT) - #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT) - --static int stmmac_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_addr) --{ -- unsigned long curr; -- unsigned long finish = jiffies + 3 * HZ; -- -- do { -- curr = jiffies; -- if (readl(ioaddr + mii_addr) & MII_BUSY) -- cpu_relax(); -- else -- return 0; -- } while (!time_after_eq(curr, finish)); -- -- return -EBUSY; --} -- - /** - * stmmac_mdio_read - * @bus: points to the mii_bus structure -@@ -74,7 +55,7 @@ static int stmmac_mdio_read(struct mii_b - struct stmmac_priv *priv = netdev_priv(ndev); - unsigned int mii_address = priv->hw->mii.addr; - unsigned int mii_data = priv->hw->mii.data; -- -+ u32 v; - int data; - u32 value = MII_BUSY; - -@@ -86,12 +67,14 @@ static int stmmac_mdio_read(struct mii_b - if (priv->plat->has_gmac4) - value |= MII_GMAC4_READ; - -- if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) -+ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), -+ 100, 10000)) - return -EBUSY; - - writel(value, priv->ioaddr + mii_address); - -- if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) -+ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), -+ 100, 10000)) - return -EBUSY; - - /* Read the data from the MII data register */ -@@ -115,7 +98,7 @@ static int stmmac_mdio_write(struct mii_ - struct stmmac_priv *priv = netdev_priv(ndev); - unsigned int mii_address = priv->hw->mii.addr; - unsigned int mii_data = priv->hw->mii.data; -- -+ u32 v; - u32 value = MII_BUSY; - - value |= (phyaddr << priv->hw->mii.addr_shift) -@@ -130,7 +113,8 @@ static int stmmac_mdio_write(struct mii_ - value |= MII_WRITE; - - /* Wait until any existing MII operation is complete */ -- if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) -+ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), -+ 100, 10000)) - return -EBUSY; - - /* Set the MII address register to write */ -@@ -138,7 +122,8 @@ static int stmmac_mdio_write(struct mii_ - writel(value, priv->ioaddr + mii_address); - - /* Wait until any existing MII operation is complete */ -- return stmmac_mdio_busy_wait(priv->ioaddr, mii_address); -+ return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), -+ 100, 10000); - } - - /** -@@ -156,9 +141,9 @@ int stmmac_mdio_reset(struct mii_bus *bu - - #ifdef CONFIG_OF - if (priv->device->of_node) { -- - if (data->reset_gpio < 0) { - struct device_node *np = priv->device->of_node; -+ - if (!np) - return 0; - -@@ -198,7 +183,7 @@ int stmmac_mdio_reset(struct mii_bus *bu - - /* This is a workaround for problems with the STE101P PHY. - * It doesn't complete its reset until at least one clock cycle -- * on MDC, so perform a dummy mdio read. To be upadted for GMAC4 -+ * on MDC, so perform a dummy mdio read. To be updated for GMAC4 - * if needed. - */ - if (!priv->plat->has_gmac4) -@@ -225,7 +210,7 @@ int stmmac_mdio_register(struct net_devi - return 0; - - new_bus = mdiobus_alloc(); -- if (new_bus == NULL) -+ if (!new_bus) - return -ENOMEM; - - if (mdio_bus_data->irqs) -@@ -262,49 +247,48 @@ int stmmac_mdio_register(struct net_devi - found = 0; - for (addr = 0; addr < PHY_MAX_ADDR; addr++) { - struct phy_device *phydev = mdiobus_get_phy(new_bus, addr); -- if (phydev) { -- int act = 0; -- char irq_num[4]; -- char *irq_str; -- -- /* -- * If an IRQ was provided to be assigned after -- * the bus probe, do it here. -- */ -- if ((mdio_bus_data->irqs == NULL) && -- (mdio_bus_data->probed_phy_irq > 0)) { -- new_bus->irq[addr] = -- mdio_bus_data->probed_phy_irq; -- phydev->irq = mdio_bus_data->probed_phy_irq; -- } -- -- /* -- * If we're going to bind the MAC to this PHY bus, -- * and no PHY number was provided to the MAC, -- * use the one probed here. -- */ -- if (priv->plat->phy_addr == -1) -- priv->plat->phy_addr = addr; -- -- act = (priv->plat->phy_addr == addr); -- switch (phydev->irq) { -- case PHY_POLL: -- irq_str = "POLL"; -- break; -- case PHY_IGNORE_INTERRUPT: -- irq_str = "IGNORE"; -- break; -- default: -- sprintf(irq_num, "%d", phydev->irq); -- irq_str = irq_num; -- break; -- } -- netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n", -- phydev->phy_id, addr, -- irq_str, phydev_name(phydev), -- act ? " active" : ""); -- found = 1; -+ int act = 0; -+ char irq_num[4]; -+ char *irq_str; -+ -+ if (!phydev) -+ continue; -+ -+ /* -+ * If an IRQ was provided to be assigned after -+ * the bus probe, do it here. -+ */ -+ if (!mdio_bus_data->irqs && -+ (mdio_bus_data->probed_phy_irq > 0)) { -+ new_bus->irq[addr] = mdio_bus_data->probed_phy_irq; -+ phydev->irq = mdio_bus_data->probed_phy_irq; -+ } -+ -+ /* -+ * If we're going to bind the MAC to this PHY bus, -+ * and no PHY number was provided to the MAC, -+ * use the one probed here. -+ */ -+ if (priv->plat->phy_addr == -1) -+ priv->plat->phy_addr = addr; -+ -+ act = (priv->plat->phy_addr == addr); -+ switch (phydev->irq) { -+ case PHY_POLL: -+ irq_str = "POLL"; -+ break; -+ case PHY_IGNORE_INTERRUPT: -+ irq_str = "IGNORE"; -+ break; -+ default: -+ sprintf(irq_num, "%d", phydev->irq); -+ irq_str = irq_num; -+ break; - } -+ netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n", -+ phydev->phy_id, addr, irq_str, phydev_name(phydev), -+ act ? " active" : ""); -+ found = 1; - } - - if (!found && !mdio_node) { ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - -@@ -120,7 +116,6 @@ static struct stmmac_axi *stmmac_axi_set - axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en"); - axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm"); - axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe"); -- axi->axi_axi_all = of_property_read_bool(np, "snps,axi_all"); - axi->axi_fb = of_property_read_bool(np, "snps,axi_fb"); - axi->axi_mb = of_property_read_bool(np, "snps,axi_mb"); - axi->axi_rb = of_property_read_bool(np, "snps,axi_rb"); -@@ -180,10 +175,19 @@ static int stmmac_dt_phy(struct plat_stm - mdio = false; - } - -- /* If snps,dwmac-mdio is passed from DT, always register the MDIO */ -- for_each_child_of_node(np, plat->mdio_node) { -- if (of_device_is_compatible(plat->mdio_node, "snps,dwmac-mdio")) -- break; -+ /* exception for dwmac-dwc-qos-eth glue logic */ -+ if (of_device_is_compatible(np, "snps,dwc-qos-ethernet-4.10")) { -+ plat->mdio_node = of_get_child_by_name(np, "mdio"); -+ } else { -+ /** -+ * If snps,dwmac-mdio is passed from DT, always register -+ * the MDIO -+ */ -+ for_each_child_of_node(np, plat->mdio_node) { -+ if (of_device_is_compatible(plat->mdio_node, -+ "snps,dwmac-mdio")) -+ break; -+ } - } - - if (plat->mdio_node) { -@@ -248,6 +252,9 @@ stmmac_probe_config_dt(struct platform_d - plat->force_sf_dma_mode = - of_property_read_bool(np, "snps,force_sf_dma_mode"); - -+ plat->en_tx_lpi_clockgating = -+ of_property_read_bool(np, "snps,en-tx-lpi-clockgating"); -+ - /* Set the maxmtu to a default of JUMBO_LEN in case the - * parameter is not present in the device tree. - */ -@@ -332,7 +339,54 @@ stmmac_probe_config_dt(struct platform_d - - plat->axi = stmmac_axi_setup(pdev); - -+ /* clock setup */ -+ plat->stmmac_clk = devm_clk_get(&pdev->dev, -+ STMMAC_RESOURCE_NAME); -+ if (IS_ERR(plat->stmmac_clk)) { -+ dev_warn(&pdev->dev, "Cannot get CSR clock\n"); -+ plat->stmmac_clk = NULL; -+ } -+ clk_prepare_enable(plat->stmmac_clk); -+ -+ plat->pclk = devm_clk_get(&pdev->dev, "pclk"); -+ if (IS_ERR(plat->pclk)) { -+ if (PTR_ERR(plat->pclk) == -EPROBE_DEFER) -+ goto error_pclk_get; -+ -+ plat->pclk = NULL; -+ } -+ clk_prepare_enable(plat->pclk); -+ -+ /* Fall-back to main clock in case of no PTP ref is passed */ -+ plat->clk_ptp_ref = devm_clk_get(&pdev->dev, "clk_ptp_ref"); -+ if (IS_ERR(plat->clk_ptp_ref)) { -+ plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk); -+ plat->clk_ptp_ref = NULL; -+ dev_warn(&pdev->dev, "PTP uses main clock\n"); -+ } else { -+ clk_prepare_enable(plat->clk_ptp_ref); -+ plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref); -+ dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate); -+ } -+ -+ plat->stmmac_rst = devm_reset_control_get(&pdev->dev, -+ STMMAC_RESOURCE_NAME); -+ if (IS_ERR(plat->stmmac_rst)) { -+ if (PTR_ERR(plat->stmmac_rst) == -EPROBE_DEFER) -+ goto error_hw_init; -+ -+ dev_info(&pdev->dev, "no reset control found\n"); -+ plat->stmmac_rst = NULL; -+ } -+ - return plat; -+ -+error_hw_init: -+ clk_disable_unprepare(plat->pclk); -+error_pclk_get: -+ clk_disable_unprepare(plat->stmmac_clk); -+ -+ return ERR_PTR(-EPROBE_DEFER); - } - - /** -@@ -356,7 +410,7 @@ void stmmac_remove_config_dt(struct plat - struct plat_stmmacenet_data * - stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) - { -- return ERR_PTR(-ENOSYS); -+ return ERR_PTR(-EINVAL); - } - - void stmmac_remove_config_dt(struct platform_device *pdev, ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h -@@ -12,10 +12,6 @@ - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - -- You should have received a copy of the GNU General Public License along with -- this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -- - The full GNU General Public License is included in this distribution in - the file called "COPYING". - ---- a/include/linux/stmmac.h -+++ b/include/linux/stmmac.h -@@ -103,7 +103,6 @@ struct stmmac_axi { - u32 axi_wr_osr_lmt; - u32 axi_rd_osr_lmt; - bool axi_kbbe; -- bool axi_axi_all; - u32 axi_blen[AXI_BLEN]; - bool axi_fb; - bool axi_mb; -@@ -135,13 +134,18 @@ struct plat_stmmacenet_data { - int tx_fifo_size; - int rx_fifo_size; - void (*fix_mac_speed)(void *priv, unsigned int speed); -- void (*bus_setup)(void __iomem *ioaddr); - int (*init)(struct platform_device *pdev, void *priv); - void (*exit)(struct platform_device *pdev, void *priv); - void *bsp_priv; -+ struct clk *stmmac_clk; -+ struct clk *pclk; -+ struct clk *clk_ptp_ref; -+ unsigned int clk_ptp_rate; -+ struct reset_control *stmmac_rst; - struct stmmac_axi *axi; - int has_gmac4; - bool tso_en; - int mac_port_sel_speed; -+ bool en_tx_lpi_clockgating; - }; - #endif |