From 3f8905ade23bcfc6d8d852178993d321da2d02db Mon Sep 17 00:00:00 2001 From: Ian Ray Date: Wed, 4 Nov 2020 17:26:01 +0100 Subject: net: e1000: implement eth_write_hwaddr for DM_ETH Implement programming MAC address to the hardware also for device model configuration. Fixes: b565b18a294f ("board: ge: bx50v3: Enable DM for PCI and ethernet") Signed-off-by: Ian Ray Signed-off-by: Sebastian Reichel --- drivers/net/e1000.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 3b3dd104cd..733588302d 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -869,7 +869,6 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, return E1000_SUCCESS; } -#ifndef CONFIG_DM_ETH /****************************************************************************** * e1000_write_eeprom_srwr - Write to Shadow Ram using EEWR * @hw: pointer to the HW structure @@ -1035,7 +1034,6 @@ static int32_t e1000_update_eeprom_checksum_i210(struct e1000_hw *hw) out: return ret_val; } -#endif /****************************************************************************** * Verifies that the EEPROM has a valid checksum @@ -5660,13 +5658,24 @@ e1000_poll(struct eth_device *nic) return len ? 1 : 0; } +#endif /* !CONFIG_DM_ETH */ +#ifdef CONFIG_DM_ETH +static int e1000_write_hwaddr(struct udevice *dev) +#else static int e1000_write_hwaddr(struct eth_device *dev) +#endif { #ifndef CONFIG_E1000_NO_NVM - unsigned char *mac = dev->enetaddr; unsigned char current_mac[6]; +#ifdef CONFIG_DM_ETH + struct eth_pdata *plat = dev_get_plat(dev); + struct e1000_hw *hw = dev_get_priv(dev); + u8 *mac = plat->enetaddr; +#else struct e1000_hw *hw = dev->priv; + u8 *mac = dev->enetaddr; +#endif uint16_t data[3]; int ret_val, i; @@ -5700,6 +5709,7 @@ static int e1000_write_hwaddr(struct eth_device *dev) #endif } +#ifndef CONFIG_DM_ETH /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside You should omit the last argument struct pci_device * for a non-PCI NIC @@ -5926,6 +5936,7 @@ static const struct eth_ops e1000_eth_ops = { .recv = e1000_eth_recv, .stop = e1000_eth_stop, .free_pkt = e1000_free_pkt, + .write_hwaddr = e1000_write_hwaddr, }; static const struct udevice_id e1000_eth_ids[] = { -- cgit v1.2.3 From 0be3d1fafb54bc2fd3d5862304528d7a21e500d9 Mon Sep 17 00:00:00 2001 From: Hongwei Zhang Date: Thu, 10 Dec 2020 18:11:09 -0500 Subject: net: ftgmac100: Read and retain MAC address Read and retain MAC address across flash and QEMU support. Signed-off-by: Hongwei Zhang --- drivers/net/ftgmac100.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c index 69e299d6a3..0687230b4b 100644 --- a/drivers/net/ftgmac100.c +++ b/drivers/net/ftgmac100.c @@ -270,6 +270,28 @@ static int ftgmac100_set_mac(struct ftgmac100_data *priv, return 0; } +/* + * Get MAC address + */ +static int ftgmac100_get_mac(struct ftgmac100_data *priv, + unsigned char *mac) +{ + struct ftgmac100 *ftgmac100 = priv->iobase; + unsigned int maddr = readl(&ftgmac100->mac_madr); + unsigned int laddr = readl(&ftgmac100->mac_ladr); + + debug("%s(%x %x)\n", __func__, maddr, laddr); + + mac[0] = (maddr >> 8) & 0xff; + mac[1] = maddr & 0xff; + mac[2] = (laddr >> 24) & 0xff; + mac[3] = (laddr >> 16) & 0xff; + mac[4] = (laddr >> 8) & 0xff; + mac[5] = laddr & 0xff; + + return 0; +} + /* * disable transmitter, receiver */ @@ -511,6 +533,14 @@ static int ftgmac100_write_hwaddr(struct udevice *dev) return ftgmac100_set_mac(priv, pdata->enetaddr); } +static int ftgmac_read_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct ftgmac100_data *priv = dev_get_priv(dev); + + return ftgmac100_get_mac(priv, pdata->enetaddr); +} + static int ftgmac100_of_to_plat(struct udevice *dev) { struct eth_pdata *pdata = dev_get_plat(dev); @@ -571,6 +601,8 @@ static int ftgmac100_probe(struct udevice *dev) goto out; } + ftgmac_read_hwaddr(dev); + out: if (ret) clk_release_bulk(&priv->clks); -- cgit v1.2.3 From dd70ff481526a87f69bec732fcc402c60441560c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 6 Jan 2021 15:16:01 +0100 Subject: net: ks8851: Reset internal RXFC count on bad packet A sporadic condition occurs when the "bad packet" error is triggered repeatedly, which results in "bad packet" messages scrolling on the console during transfer. To avoid triggering this, reset the internal RXFC count on the first occurance of the "bad packet", which forces the code to re-read the RX packet count from the MAC, and prevents any additional "bad packet" messages if there are no more packets in the MAC. Also print better debug information if this condition occurs. Signed-off-by: Marek Vasut Cc: Eugen Hristev Cc: Joe Hershberger Cc: Tom Rini --- drivers/net/ks8851_mll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 91c2d10ffc..9dd9b33955 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -251,7 +251,8 @@ static int ks_rcv(struct ks_net *ks, uchar *data) } ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL | RXQCR_RRXEF); - printf(DRIVERNAME ": bad packet\n"); + printf(DRIVERNAME ": bad packet (sts=0x%04x len=0x%04x)\n", sts, len); + ks->rxfc = 0; return 0; } -- cgit v1.2.3 From 6f1e668d964ebd3244a99288ea4bda7b7b8627c3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 7 Jan 2021 11:12:16 +0100 Subject: net: dwc_eth_qos: Pad descriptors to cacheline size The DWMAC4 IP has the possibility to skip up to 7 AXI bus width size words after the descriptor. Use this to pad the descriptors to cacheline size and remove the need for noncached memory altogether. Moreover, this lets Tegra use the generic cache flush / invalidate operations. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren Tested-by: Stephen Warren Reviewed-by: Stephen Warren Tested-by: Patrice Chotard --- drivers/net/dwc_eth_qos.c | 129 ++++++++++++++++++--------------------------- include/configs/stm32mp1.h | 1 - 2 files changed, 51 insertions(+), 79 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 45a1648ad5..944412958d 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -209,6 +209,7 @@ struct eqos_dma_regs { #define EQOS_DMA_SYSBUS_MODE_BLEN8 BIT(2) #define EQOS_DMA_SYSBUS_MODE_BLEN4 BIT(1) +#define EQOS_DMA_CH0_CONTROL_DSL_SHIFT 18 #define EQOS_DMA_CH0_CONTROL_PBLX8 BIT(16) #define EQOS_DMA_CH0_TX_CONTROL_TXPBL_SHIFT 16 @@ -239,37 +240,15 @@ struct eqos_tegra186_regs { #define EQOS_AUTO_CAL_STATUS_ACTIVE BIT(31) /* Descriptors */ - -#define EQOS_DESCRIPTOR_WORDS 4 -#define EQOS_DESCRIPTOR_SIZE (EQOS_DESCRIPTOR_WORDS * 4) /* We assume ARCH_DMA_MINALIGN >= 16; 16 is the EQOS HW minimum */ #define EQOS_DESCRIPTOR_ALIGN ARCH_DMA_MINALIGN #define EQOS_DESCRIPTORS_TX 4 #define EQOS_DESCRIPTORS_RX 4 #define EQOS_DESCRIPTORS_NUM (EQOS_DESCRIPTORS_TX + EQOS_DESCRIPTORS_RX) -#define EQOS_DESCRIPTORS_SIZE ALIGN(EQOS_DESCRIPTORS_NUM * \ - EQOS_DESCRIPTOR_SIZE, ARCH_DMA_MINALIGN) #define EQOS_BUFFER_ALIGN ARCH_DMA_MINALIGN #define EQOS_MAX_PACKET_SIZE ALIGN(1568, ARCH_DMA_MINALIGN) #define EQOS_RX_BUFFER_SIZE (EQOS_DESCRIPTORS_RX * EQOS_MAX_PACKET_SIZE) -/* - * Warn if the cache-line size is larger than the descriptor size. In such - * cases the driver will likely fail because the CPU needs to flush the cache - * when requeuing RX buffers, therefore descriptors written by the hardware - * may be discarded. Architectures with full IO coherence, such as x86, do not - * experience this issue, and hence are excluded from this condition. - * - * This can be fixed by defining CONFIG_SYS_NONCACHED_MEMORY which will cause - * the driver to allocate descriptors from a pool of non-cached memory. - */ -#if EQOS_DESCRIPTOR_SIZE < ARCH_DMA_MINALIGN -#if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \ - !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_X86) -#warning Cache line size is larger than descriptor size -#endif -#endif - struct eqos_desc { u32 des0; u32 des1; @@ -282,12 +261,17 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24) +#define EQOS_AXI_WIDTH_32 4 +#define EQOS_AXI_WIDTH_64 8 +#define EQOS_AXI_WIDTH_128 16 + struct eqos_config { bool reg_access_always_ok; int mdio_wait; int swr_wait; int config_mac; int config_mac_mdio; + unsigned int axi_bus_width; phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops; }; @@ -330,9 +314,8 @@ struct eqos_priv { int phyaddr; u32 max_speed; void *descs; - struct eqos_desc *tx_descs; - struct eqos_desc *rx_descs; int tx_desc_idx, rx_desc_idx; + unsigned int desc_size; void *tx_dma_buf; void *rx_dma_buf; void *rx_pkt; @@ -358,63 +341,42 @@ struct eqos_priv { * not have the same constraints since they are 1536 bytes large, so they * are unlikely to share cache-lines. */ -static void *eqos_alloc_descs(unsigned int num) +static void *eqos_alloc_descs(struct eqos_priv *eqos, unsigned int num) { -#ifdef CONFIG_SYS_NONCACHED_MEMORY - return (void *)noncached_alloc(EQOS_DESCRIPTORS_SIZE, - EQOS_DESCRIPTOR_ALIGN); -#else - return memalign(EQOS_DESCRIPTOR_ALIGN, EQOS_DESCRIPTORS_SIZE); -#endif + eqos->desc_size = ALIGN(sizeof(struct eqos_desc), + (unsigned int)ARCH_DMA_MINALIGN); + + return memalign(eqos->desc_size, num * eqos->desc_size); } static void eqos_free_descs(void *descs) { -#ifdef CONFIG_SYS_NONCACHED_MEMORY - /* FIXME: noncached_alloc() has no opposite */ -#else free(descs); -#endif } -static void eqos_inval_desc_tegra186(void *desc) +static struct eqos_desc *eqos_get_desc(struct eqos_priv *eqos, + unsigned int num, bool rx) { -#ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); - unsigned long end = ALIGN(start + EQOS_DESCRIPTOR_SIZE, - ARCH_DMA_MINALIGN); - - invalidate_dcache_range(start, end); -#endif + return eqos->descs + + ((rx ? EQOS_DESCRIPTORS_TX : 0) + num) * eqos->desc_size; } static void eqos_inval_desc_generic(void *desc) { -#ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); - unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE, - ARCH_DMA_MINALIGN); + unsigned long start = (unsigned long)desc; + unsigned long end = ALIGN(start + sizeof(struct eqos_desc), + ARCH_DMA_MINALIGN); invalidate_dcache_range(start, end); -#endif -} - -static void eqos_flush_desc_tegra186(void *desc) -{ -#ifndef CONFIG_SYS_NONCACHED_MEMORY - flush_cache((unsigned long)desc, EQOS_DESCRIPTOR_SIZE); -#endif } static void eqos_flush_desc_generic(void *desc) { -#ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); - unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE, - ARCH_DMA_MINALIGN); + unsigned long start = (unsigned long)desc; + unsigned long end = ALIGN(start + sizeof(struct eqos_desc), + ARCH_DMA_MINALIGN); flush_dcache_range(start, end); -#endif } static void eqos_inval_buffer_tegra186(void *buf, size_t size) @@ -1167,6 +1129,7 @@ static int eqos_start(struct udevice *dev) ulong rate; u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; ulong last_rx_desc; + ulong desc_pad; debug("%s(dev=%p):\n", __func__, dev); @@ -1405,8 +1368,12 @@ static int eqos_start(struct udevice *dev) EQOS_MAX_PACKET_SIZE << EQOS_DMA_CH0_RX_CONTROL_RBSZ_SHIFT); + desc_pad = (eqos->desc_size - sizeof(struct eqos_desc)) / + eqos->config->axi_bus_width; + setbits_le32(&eqos->dma_regs->ch0_control, - EQOS_DMA_CH0_CONTROL_PBLX8); + EQOS_DMA_CH0_CONTROL_PBLX8 | + (desc_pad << EQOS_DMA_CH0_CONTROL_DSL_SHIFT)); /* * Burst length must be < 1/2 FIFO size. @@ -1435,9 +1402,15 @@ static int eqos_start(struct udevice *dev) /* Set up descriptors */ - memset(eqos->descs, 0, EQOS_DESCRIPTORS_SIZE); + memset(eqos->descs, 0, eqos->desc_size * EQOS_DESCRIPTORS_NUM); + + for (i = 0; i < EQOS_DESCRIPTORS_TX; i++) { + struct eqos_desc *tx_desc = eqos_get_desc(eqos, i, false); + eqos->config->ops->eqos_flush_desc(tx_desc); + } + for (i = 0; i < EQOS_DESCRIPTORS_RX; i++) { - struct eqos_desc *rx_desc = &(eqos->rx_descs[i]); + struct eqos_desc *rx_desc = eqos_get_desc(eqos, i, true); rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf + (i * EQOS_MAX_PACKET_SIZE)); rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; @@ -1449,12 +1422,14 @@ static int eqos_start(struct udevice *dev) } writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress); - writel((ulong)eqos->tx_descs, &eqos->dma_regs->ch0_txdesc_list_address); + writel((ulong)eqos_get_desc(eqos, 0, false), + &eqos->dma_regs->ch0_txdesc_list_address); writel(EQOS_DESCRIPTORS_TX - 1, &eqos->dma_regs->ch0_txdesc_ring_length); writel(0, &eqos->dma_regs->ch0_rxdesc_list_haddress); - writel((ulong)eqos->rx_descs, &eqos->dma_regs->ch0_rxdesc_list_address); + writel((ulong)eqos_get_desc(eqos, 0, true), + &eqos->dma_regs->ch0_rxdesc_list_address); writel(EQOS_DESCRIPTORS_RX - 1, &eqos->dma_regs->ch0_rxdesc_ring_length); @@ -1473,7 +1448,7 @@ static int eqos_start(struct udevice *dev) * that's not distinguishable from none of the descriptors being * available. */ - last_rx_desc = (ulong)&(eqos->rx_descs[(EQOS_DESCRIPTORS_RX - 1)]); + last_rx_desc = (ulong)eqos_get_desc(eqos, EQOS_DESCRIPTORS_RX - 1, true); writel(last_rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer); eqos->started = true; @@ -1558,7 +1533,7 @@ static int eqos_send(struct udevice *dev, void *packet, int length) memcpy(eqos->tx_dma_buf, packet, length); eqos->config->ops->eqos_flush_buffer(eqos->tx_dma_buf, length); - tx_desc = &(eqos->tx_descs[eqos->tx_desc_idx]); + tx_desc = eqos_get_desc(eqos, eqos->tx_desc_idx, false); eqos->tx_desc_idx++; eqos->tx_desc_idx %= EQOS_DESCRIPTORS_TX; @@ -1573,7 +1548,7 @@ static int eqos_send(struct udevice *dev, void *packet, int length) tx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_FD | EQOS_DESC3_LD | length; eqos->config->ops->eqos_flush_desc(tx_desc); - writel((ulong)(&(eqos->tx_descs[eqos->tx_desc_idx])), + writel((ulong)eqos_get_desc(eqos, eqos->tx_desc_idx, false), &eqos->dma_regs->ch0_txdesc_tail_pointer); for (i = 0; i < 1000000; i++) { @@ -1596,7 +1571,7 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags); - rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); + rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true); eqos->config->ops->eqos_inval_desc(rx_desc); if (rx_desc->des3 & EQOS_DESC3_OWN) { debug("%s: RX packet not available\n", __func__); @@ -1631,7 +1606,7 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) eqos->config->ops->eqos_inval_buffer(packet, length); - rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); + rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true); rx_desc->des0 = 0; mb(); @@ -1663,17 +1638,12 @@ static int eqos_probe_resources_core(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - eqos->descs = eqos_alloc_descs(EQOS_DESCRIPTORS_TX + - EQOS_DESCRIPTORS_RX); + eqos->descs = eqos_alloc_descs(eqos, EQOS_DESCRIPTORS_NUM); if (!eqos->descs) { debug("%s: eqos_alloc_descs() failed\n", __func__); ret = -ENOMEM; goto err; } - eqos->tx_descs = (struct eqos_desc *)eqos->descs; - eqos->rx_descs = (eqos->tx_descs + EQOS_DESCRIPTORS_TX); - debug("%s: tx_descs=%p, rx_descs=%p\n", __func__, eqos->tx_descs, - eqos->rx_descs); eqos->tx_dma_buf = memalign(EQOS_BUFFER_ALIGN, EQOS_MAX_PACKET_SIZE); if (!eqos->tx_dma_buf) { @@ -2083,8 +2053,8 @@ static const struct eth_ops eqos_ops = { }; static struct eqos_ops eqos_tegra186_ops = { - .eqos_inval_desc = eqos_inval_desc_tegra186, - .eqos_flush_desc = eqos_flush_desc_tegra186, + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, .eqos_inval_buffer = eqos_inval_buffer_tegra186, .eqos_flush_buffer = eqos_flush_buffer_tegra186, .eqos_probe_resources = eqos_probe_resources_tegra186, @@ -2105,6 +2075,7 @@ static const struct eqos_config __maybe_unused eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, + .axi_bus_width = EQOS_AXI_WIDTH_128, .interface = eqos_get_interface_tegra186, .ops = &eqos_tegra186_ops }; @@ -2132,6 +2103,7 @@ static const struct eqos_config __maybe_unused eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, + .axi_bus_width = EQOS_AXI_WIDTH_64, .interface = eqos_get_interface_stm32, .ops = &eqos_stm32_ops }; @@ -2159,6 +2131,7 @@ struct eqos_config __maybe_unused eqos_imx_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, + .axi_bus_width = EQOS_AXI_WIDTH_64, .interface = eqos_get_interface_imx, .ops = &eqos_imx_ops }; diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h index 1aa7514ac7..863b652ca4 100644 --- a/include/configs/stm32mp1.h +++ b/include/configs/stm32mp1.h @@ -69,7 +69,6 @@ /* Ethernet need */ #ifdef CONFIG_DWC_ETH_QOS -#define CONFIG_SYS_NONCACHED_MEMORY (1 * SZ_1M) /* 1M */ #define CONFIG_SERVERIP 192.168.1.1 #define CONFIG_BOOTP_SERVERIP #define CONFIG_SYS_AUTOLOAD "no" -- cgit v1.2.3