2017-09-21 20:10:08 +00:00
|
|
|
--- 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,
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -181,11 +179,19 @@ static int meson8b_init_prg_eth(struct m
|
2017-09-21 20:10:08 +00:00
|
|
|
{
|
|
|
|
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;
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -198,9 +204,8 @@ static int meson8b_init_prg_eth(struct m
|
2017-09-21 20:10:08 +00:00
|
|
|
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:
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -286,6 +291,11 @@ static int meson8b_dwmac_probe(struct pl
|
2017-09-21 20:10:08 +00:00
|
|
|
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
|
2018-08-24 15:58:52 +00:00
|
|
|
@@ -351,7 +351,7 @@ static int socfpga_dwmac_probe(struct pl
|
2017-09-21 20:10:08 +00:00
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-01-18 13:51:13 +00:00
|
|
|
@@ -421,7 +418,7 @@ static void stmmac_get_rx_hwtstamp(struc
|
2017-09-21 20:10:08 +00:00
|
|
|
/**
|
|
|
|
* 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)
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -621,7 +618,7 @@ static int stmmac_hwtstamp_ioctl(struct
|
2017-09-21 20:10:08 +00:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -631,7 +628,7 @@ static int stmmac_hwtstamp_ioctl(struct
|
2017-09-21 20:10:08 +00:00
|
|
|
* 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);
|
|
|
|
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -659,18 +656,6 @@ static int stmmac_init_ptp(struct stmmac
|
2017-09-21 20:10:08 +00:00
|
|
|
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)
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -697,8 +682,8 @@ static int stmmac_init_ptp(struct stmmac
|
2017-09-21 20:10:08 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -719,7 +704,7 @@ static void stmmac_adjust_link(struct ne
|
2017-09-21 20:10:08 +00:00
|
|
|
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);
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -746,33 +731,36 @@ static void stmmac_adjust_link(struct ne
|
2017-09-21 20:10:08 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -785,8 +773,8 @@ static void stmmac_adjust_link(struct ne
|
2017-09-21 20:10:08 +00:00
|
|
|
} 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))
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -848,8 +836,8 @@ static int stmmac_init_phy(struct net_de
|
2017-09-21 20:10:08 +00:00
|
|
|
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,
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -901,9 +889,7 @@ static int stmmac_init_phy(struct net_de
|
2017-09-21 20:10:08 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -1029,7 +1015,7 @@ static void stmmac_free_rx_buffers(struc
|
2017-09-21 20:10:08 +00:00
|
|
|
* @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)
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -1142,13 +1128,6 @@ static void dma_free_tx_skbufs(struct st
|
2017-09-21 20:10:08 +00:00
|
|
|
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,
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -1162,7 +1141,7 @@ static void dma_free_tx_skbufs(struct st
|
2017-09-21 20:10:08 +00:00
|
|
|
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;
|
2018-04-24 12:19:43 +00:00
|
|
|
@@ -1286,6 +1265,28 @@ static void free_dma_desc_resources(stru
|
2017-09-21 20:10:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
+ * 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
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -1691,10 +1692,6 @@ static int stmmac_hw_setup(struct net_de
|
2017-09-21 20:10:08 +00:00
|
|
|
/* 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;
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -1711,6 +1708,10 @@ static int stmmac_hw_setup(struct net_de
|
2017-09-21 20:10:08 +00:00
|
|
|
/* 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");
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -1731,8 +1732,10 @@ static int stmmac_hw_setup(struct net_de
|
2017-09-21 20:10:08 +00:00
|
|
|
|
|
|
|
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
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -1746,11 +1749,6 @@ static int stmmac_hw_setup(struct net_de
|
2017-09-21 20:10:08 +00:00
|
|
|
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)) {
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -2547,7 +2545,7 @@ static int stmmac_rx(struct stmmac_priv
|
2017-09-21 20:10:08 +00:00
|
|
|
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.
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -2570,7 +2568,7 @@ static int stmmac_rx(struct stmmac_priv
|
2017-09-21 20:10:08 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -2790,7 +2788,7 @@ static netdev_features_t stmmac_fix_feat
|
2017-09-21 20:10:08 +00:00
|
|
|
/* 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;
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -2936,9 +2934,7 @@ static void sysfs_display_ring(void *hea
|
2017-09-21 20:10:08 +00:00
|
|
|
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),
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -2947,7 +2943,6 @@ static void sysfs_display_ring(void *hea
|
2017-09-21 20:10:08 +00:00
|
|
|
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),
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -3017,7 +3012,7 @@ static int stmmac_sysfs_dma_cap_read(str
|
2017-09-21 20:10:08 +00:00
|
|
|
(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");
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -3293,44 +3288,8 @@ int stmmac_dvr_probe(struct device *devi
|
2017-09-21 20:10:08 +00:00
|
|
|
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);
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -3416,10 +3375,6 @@ error_netdev_register:
|
2017-09-21 20:10:08 +00:00
|
|
|
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;
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -3445,10 +3400,10 @@ int stmmac_dvr_remove(struct device *dev
|
2017-09-21 20:10:08 +00:00
|
|
|
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)
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -3497,14 +3452,14 @@ int stmmac_suspend(struct device *dev)
|
2017-09-21 20:10:08 +00:00
|
|
|
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);
|
2018-06-05 21:29:30 +00:00
|
|
|
@@ -3537,9 +3492,9 @@ int stmmac_resume(struct device *dev)
|
2017-09-21 20:10:08 +00:00
|
|
|
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".
|
|
|
|
|
|
|
|
@@ -121,7 +117,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");
|
|
|
|
@@ -181,10 +176,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) {
|
|
|
|
@@ -249,6 +253,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.
|
|
|
|
*/
|
|
|
|
@@ -333,7 +340,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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -357,7 +411,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
|