From 75e375b0a979176b72b0355534e03a863c19d95a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 20 Jun 2020 17:36:42 +0200 Subject: net: dc2114x: Use PCI_DEVICE() to define PCI device compat list Use this macro to fully fill the PCI device ID table. This is mandatory for the DM PCI support, which checks all the fields. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 0cb54e3214..dee699a59f 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -568,8 +568,8 @@ static void read_hw_addr(struct eth_device *dev, struct bd_info *bis) } static struct pci_device_id supported[] = { - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST }, - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 }, + { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST) }, + { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142) }, { } }; -- cgit From 777aa715317213fc4eda62916e515a8da89d6e64 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 20 Jun 2020 17:39:21 +0200 Subject: net: dc2114x: Support all DC2114x For the usage in this driver, the chips are identical, so support all of them. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index dee699a59f..dfd893bcbb 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -581,7 +581,6 @@ int dc21x4x_initialize(struct bd_info *bis) unsigned int iobase; int card_number = 0; pci_dev_t devbusfn; - unsigned int cfrv; int idx = 0; while (1) { @@ -589,14 +588,6 @@ int dc21x4x_initialize(struct bd_info *bis) if (devbusfn == -1) break; - /* Get the chip configuration revision register. */ - pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); - - if ((cfrv & CFRV_RN) < DC2114x_BRK) { - printf("Error: The chip is not DC21143.\n"); - continue; - } - pci_read_config_word(devbusfn, PCI_COMMAND, &status); status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, status); -- cgit From a410f13dfe4a458da9ab2dc0f2b7e6190c10a504 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 20 Jun 2020 17:43:29 +0200 Subject: net: dc2114x: Add Kconfig entries Add Kconfig entries for the dc2114x driver and convert various boards. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ec3fb49832..15030b8165 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -491,6 +491,12 @@ config SH_ETHER source "drivers/net/ti/Kconfig" +config TULIP + bool "DEC Tulip DC2114x Ethernet support" + depends on (DM_ETH && DM_PCI) || !DM_ETH + help + This driver supports DEC DC2114x Fast ethernet chips. + config XILINX_AXIEMAC depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP) select PHYLIB -- cgit From 9b98f20494c279389a4a6e80a6a4ca170653b49f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 20 Jun 2020 17:54:53 +0200 Subject: net: dc2114x: Drop update_srom() This code is never used, remove it. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 91 --------------------------------------------------- 1 file changed, 91 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index dfd893bcbb..dcbd818581 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -11,8 +11,6 @@ #define SROM_DLEVEL 0 -#undef UPDATE_SROM - /* PCI Registers. */ #define PCI_CFDA_PSM 0x43 @@ -270,92 +268,6 @@ static int read_srom(struct eth_device *dev, u_long ioaddr, int index) 3 + ee_addr_size + 16); } -#ifdef UPDATE_SROM -static int write_srom(struct eth_device *dev, u_long ioaddr, int index, - int new_value) -{ - unsigned short newval; - int ee_addr_size; - int i; - - ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; - - udelay(10 * 1000); /* test-only */ - - debug_cond(SROM_DLEVEL >= 1, "ee_addr_size=%d.\n", ee_addr_size); - debug_cond(SROM_DLEVEL >= 1, - "Writing new entry 0x%4.4x to offset %d.\n", - new_value, index); - - /* Enable programming modes. */ - do_eeprom_cmd(dev, ioaddr, 0x4f << (ee_addr_size - 4), - 3 + ee_addr_size); - - /* Do the actual write. */ - do_eeprom_cmd(dev, ioaddr, new_value | - (((SROM_WRITE_CMD << ee_addr_size) | index) << 16), - 3 + ee_addr_size + 16); - - /* Poll for write finished. */ - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - for (i = 0; i < 10000; i++) { /* Typical 2000 ticks */ - if (getfrom_srom(dev, ioaddr) & EE_DATA_READ) - break; - } - - debug_cond(SROM_DLEVEL >= 1, " Write finished after %d ticks.\n", i); - - /* Disable programming. */ - do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size - 4)), - 3 + ee_addr_size); - - /* And read the result. */ - newval = do_eeprom_cmd(dev, ioaddr, - (((SROM_READ_CMD << ee_addr_size) | index) << 16) - | 0xffff, 3 + ee_addr_size + 16); - - debug_cond(SROM_DLEVEL >= 1, " New value at offset %d is %4.4x.\n", - index, newval); - - return 1; -} - -static void update_srom(struct eth_device *dev, struct bd_info *bis) -{ - static unsigned short eeprom[0x40] = { - 0x140b, 0x6610, 0x0000, 0x0000, /* 00 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 04 */ - 0x00a3, 0x0103, 0x0000, 0x0000, /* 08 */ - 0x0000, 0x1f00, 0x0000, 0x0000, /* 0c */ - 0x0108, 0x038d, 0x0000, 0x0000, /* 10 */ - 0xe078, 0x0001, 0x0040, 0x0018, /* 14 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 18 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 1c */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 2c */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 34 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 38 */ - 0x0000, 0x0000, 0x0000, 0x4e07, /* 3c */ - }; - uchar enetaddr[6]; - int i; - - /* Ethernet Addr... */ - if (!eth_env_get_enetaddr("ethaddr", enetaddr)) - return; - - eeprom[0x0a] = (enetaddr[1] << 8) | enetaddr[0]; - eeprom[0x0b] = (enetaddr[3] << 8) | enetaddr[2]; - eeprom[0x0c] = (enetaddr[5] << 8) | enetaddr[4]; - - for (i = 0; i < 0x40; i++) - write_srom(dev, DE4X5_APROM, i, eeprom[i]); -} -#endif /* UPDATE_SROM */ - static void send_setup_frame(struct eth_device *dev, struct bd_info *bis) { char setup_frame[SETUP_FRAME_LEN]; @@ -561,9 +473,6 @@ static void read_hw_addr(struct eth_device *dev, struct bd_info *bis) if (!j || j == 0x2fffd) { memset(dev->enetaddr, 0, ETH_ALEN); debug("Warning: can't read HW address from SROM.\n"); -#ifdef UPDATE_SROM - update_srom(dev, bis); -#endif } } -- cgit From 02b95a4b4133cff79d72cafc2c19b1154504ac56 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 06:31:54 +0200 Subject: net: dc2114x: Use standard I/O accessors The current dc21x4x driver accesses its memory mapped registers directly instead of using the standard I/O accessors. This can cause problems on some systems as the accesses can get out of order. So convert the direct volatile dereferences to use the normal in/out macros. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index dcbd818581..9cafa3b23d 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include +#include #include #include #include @@ -104,12 +105,12 @@ static char tx_ring_size; static u32 dc2114x_inl(struct eth_device *dev, u32 addr) { - return le32_to_cpu(*(volatile u32 *)(addr + dev->iobase)); + return le32_to_cpu(readl(dev->iobase + addr)); } static void dc2114x_outl(struct eth_device *dev, u32 command, u32 addr) { - *(volatile u32 *)(addr + dev->iobase) = cpu_to_le32(command); + writel(cpu_to_le32(command), dev->iobase + addr); } static void reset_de4x5(struct eth_device *dev) -- cgit From 2301a4be6cef590237db93746e529bdb666e49f2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 06:42:07 +0200 Subject: net: dc2114x: Introduce private data Introduce dc2114x_priv, which is a super-structure around eth_device and tracks per-device state and the device IO address. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 9cafa3b23d..2976561f56 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -94,6 +94,13 @@ struct de4x5_desc { u32 next; }; +struct dc2114x_priv { + struct eth_device dev; + char *name; + void __iomem *iobase; + u8 *enetaddr; +}; + /* RX and TX descriptor ring */ static struct de4x5_desc rx_ring[NUM_RX_DESC] __aligned(32); static struct de4x5_desc tx_ring[NUM_TX_DESC] __aligned(32); @@ -460,9 +467,9 @@ static void dc21x4x_halt(struct eth_device *dev) pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); } -static void read_hw_addr(struct eth_device *dev, struct bd_info *bis) +static void read_hw_addr(struct dc2114x_priv *priv) { - u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); + u_short tmp, *p = (u_short *)(&priv->enetaddr[0]); int i, j = 0; for (i = 0; i < (ETH_ALEN >> 1); i++) { @@ -472,7 +479,7 @@ static void read_hw_addr(struct eth_device *dev, struct bd_info *bis) } if (!j || j == 0x2fffd) { - memset(dev->enetaddr, 0, ETH_ALEN); + memset(priv->enetaddr, 0, ETH_ALEN); debug("Warning: can't read HW address from SROM.\n"); } } @@ -485,6 +492,7 @@ static struct pci_device_id supported[] = { int dc21x4x_initialize(struct bd_info *bis) { + struct dc2114x_priv *priv; struct eth_device *dev; unsigned short status; unsigned char timer; @@ -526,15 +534,18 @@ int dc21x4x_initialize(struct bd_info *bis) iobase &= PCI_BASE_ADDRESS_MEM_MASK; debug("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (!dev) { + priv = malloc(sizeof(*priv)); + if (!priv) { printf("Can not allocalte memory of dc21x4x\n"); break; } + memset(priv, 0, sizeof(*priv)); - memset(dev, 0, sizeof(*dev)); + dev = &priv->dev; sprintf(dev->name, "dc21x4x#%d", card_number); + priv->name = dev->name; + priv->enetaddr = dev->enetaddr; dev->iobase = pci_mem_to_phys(devbusfn, iobase); dev->priv = (void *)devbusfn; @@ -548,7 +559,7 @@ int dc21x4x_initialize(struct bd_info *bis) udelay(10 * 1000); - read_hw_addr(dev, bis); + read_hw_addr(priv); eth_register(dev); -- cgit From fcd6217813661c07f707e804a46886c56d48d0e8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 06:46:09 +0200 Subject: net: dc2114x: Pass private data around This patch replaces the various uses of struct eth_device for accessing device private data with struct dc2114x_priv, which is compatible both with DM and non-DM operation. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 135 ++++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 2976561f56..eb7d29cf8f 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -110,78 +110,78 @@ static int tx_new; /* TX descriptor ring pointer */ static char rx_ring_size; static char tx_ring_size; -static u32 dc2114x_inl(struct eth_device *dev, u32 addr) +static u32 dc2114x_inl(struct dc2114x_priv *priv, u32 addr) { - return le32_to_cpu(readl(dev->iobase + addr)); + return le32_to_cpu(readl(priv->iobase + addr)); } -static void dc2114x_outl(struct eth_device *dev, u32 command, u32 addr) +static void dc2114x_outl(struct dc2114x_priv *priv, u32 command, u32 addr) { - writel(cpu_to_le32(command), dev->iobase + addr); + writel(cpu_to_le32(command), priv->iobase + addr); } -static void reset_de4x5(struct eth_device *dev) +static void reset_de4x5(struct dc2114x_priv *priv) { u32 i; - i = dc2114x_inl(dev, DE4X5_BMR); + i = dc2114x_inl(priv, DE4X5_BMR); mdelay(1); - dc2114x_outl(dev, i | BMR_SWR, DE4X5_BMR); + dc2114x_outl(priv, i | BMR_SWR, DE4X5_BMR); mdelay(1); - dc2114x_outl(dev, i, DE4X5_BMR); + dc2114x_outl(priv, i, DE4X5_BMR); mdelay(1); for (i = 0; i < 5; i++) { - dc2114x_inl(dev, DE4X5_BMR); + dc2114x_inl(priv, DE4X5_BMR); mdelay(10); } mdelay(1); } -static void start_de4x5(struct eth_device *dev) +static void start_de4x5(struct dc2114x_priv *priv) { u32 omr; - omr = dc2114x_inl(dev, DE4X5_OMR); + omr = dc2114x_inl(priv, DE4X5_OMR); omr |= OMR_ST | OMR_SR; - dc2114x_outl(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */ + dc2114x_outl(priv, omr, DE4X5_OMR); /* Enable the TX and/or RX */ } -static void stop_de4x5(struct eth_device *dev) +static void stop_de4x5(struct dc2114x_priv *priv) { u32 omr; - omr = dc2114x_inl(dev, DE4X5_OMR); + omr = dc2114x_inl(priv, DE4X5_OMR); omr &= ~(OMR_ST | OMR_SR); - dc2114x_outl(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ + dc2114x_outl(priv, omr, DE4X5_OMR); /* Disable the TX and/or RX */ } /* SROM Read and write routines. */ -static void sendto_srom(struct eth_device *dev, u_int command, u_long addr) +static void sendto_srom(struct dc2114x_priv *priv, u_int command, u_long addr) { - dc2114x_outl(dev, command, addr); + dc2114x_outl(priv, command, addr); udelay(1); } -static int getfrom_srom(struct eth_device *dev, u_long addr) +static int getfrom_srom(struct dc2114x_priv *priv, u_long addr) { - u32 tmp = dc2114x_inl(dev, addr); + u32 tmp = dc2114x_inl(priv, addr); udelay(1); return tmp; } /* Note: this routine returns extra data bits for size detection. */ -static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, +static int do_read_eeprom(struct dc2114x_priv *priv, u_long ioaddr, int location, int addr_len) { int read_cmd = location | (SROM_READ_CMD << addr_len); unsigned int retval = 0; int i; - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr); debug_cond(SROM_DLEVEL >= 1, " EEPROM read at %d ", location); @@ -189,35 +189,35 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, for (i = 4 + addr_len; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr); udelay(10); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr); udelay(10); debug_cond(SROM_DLEVEL >= 2, "%X", - getfrom_srom(dev, ioaddr) & 15); + getfrom_srom(priv, ioaddr) & 15); retval = (retval << 1) | - !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); + !!(getfrom_srom(priv, ioaddr) & EE_DATA_READ); } - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr); - debug_cond(SROM_DLEVEL >= 2, " :%X:", getfrom_srom(dev, ioaddr) & 15); + debug_cond(SROM_DLEVEL >= 2, " :%X:", getfrom_srom(priv, ioaddr) & 15); for (i = 16; i > 0; i--) { - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); udelay(10); debug_cond(SROM_DLEVEL >= 2, "%X", - getfrom_srom(dev, ioaddr) & 15); + getfrom_srom(priv, ioaddr) & 15); retval = (retval << 1) | - !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); + !!(getfrom_srom(priv, ioaddr) & EE_DATA_READ); + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr); udelay(10); } /* Terminate the EEPROM access. */ - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR, ioaddr); debug_cond(SROM_DLEVEL >= 2, " EEPROM value at %d is %5.5x.\n", location, retval); @@ -230,54 +230,55 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, * enable. It returns the data output from the EEPROM, and thus may * also be used for reads. */ -static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, +static int do_eeprom_cmd(struct dc2114x_priv *priv, u_long ioaddr, int cmd, int cmd_len) { unsigned int retval = 0; debug_cond(SROM_DLEVEL >= 1, " EEPROM op 0x%x: ", cmd); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); /* Shift the command bits out. */ do { short dataval = (cmd & BIT(cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; - sendto_srom(dev, dataval, ioaddr); + sendto_srom(priv, dataval, ioaddr); udelay(10); debug_cond(SROM_DLEVEL >= 2, "%X", - getfrom_srom(dev, ioaddr) & 15); + getfrom_srom(priv, ioaddr) & 15); - sendto_srom(dev, dataval | DT_CLK, ioaddr); + sendto_srom(priv, dataval | DT_CLK, ioaddr); udelay(10); retval = (retval << 1) | - !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); + !!(getfrom_srom(priv, ioaddr) & EE_DATA_READ); } while (--cmd_len >= 0); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr); /* Terminate the EEPROM access. */ - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); + sendto_srom(priv, SROM_RD | SROM_SR, ioaddr); debug_cond(SROM_DLEVEL >= 1, " EEPROM result is 0x%5.5x.\n", retval); return retval; } -static int read_srom(struct eth_device *dev, u_long ioaddr, int index) +static int read_srom(struct dc2114x_priv *priv, u_long ioaddr, int index) { int ee_addr_size; - ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; + ee_addr_size = (do_read_eeprom(priv, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; - return do_eeprom_cmd(dev, ioaddr, 0xffff | + return do_eeprom_cmd(priv, ioaddr, 0xffff | (((SROM_READ_CMD << ee_addr_size) | index) << 16), 3 + ee_addr_size + 16); } -static void send_setup_frame(struct eth_device *dev, struct bd_info *bis) +static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) { + struct eth_device *dev = &priv->dev; char setup_frame[SETUP_FRAME_LEN]; char *pa = &setup_frame[0]; int i; @@ -285,7 +286,7 @@ static void send_setup_frame(struct eth_device *dev, struct bd_info *bis) memset(pa, 0xff, SETUP_FRAME_LEN); for (i = 0; i < ETH_ALEN; i++) { - *(pa + (i & 1)) = dev->enetaddr[i]; + *(pa + (i & 1)) = priv->enetaddr[i]; if (i & 0x01) pa += 4; } @@ -294,7 +295,7 @@ static void send_setup_frame(struct eth_device *dev, struct bd_info *bis) if (i < TOUT_LOOP) continue; - printf("%s: tx error buffer not ready\n", dev->name); + printf("%s: tx error buffer not ready\n", priv->name); return; } @@ -302,13 +303,13 @@ static void send_setup_frame(struct eth_device *dev, struct bd_info *bis) tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN); tx_ring[tx_new].status = cpu_to_le32(T_OWN); - dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD); + dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD); for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) continue; - printf("%s: tx buffer not ready\n", dev->name); + printf("%s: tx buffer not ready\n", priv->name); return; } @@ -322,11 +323,13 @@ static void send_setup_frame(struct eth_device *dev, struct bd_info *bis) static int dc21x4x_send(struct eth_device *dev, void *packet, int length) { + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); int status = -1; int i; if (length <= 0) { - printf("%s: bad packet size: %d\n", dev->name, length); + printf("%s: bad packet size: %d\n", priv->name, length); goto done; } @@ -334,7 +337,7 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length) if (i < TOUT_LOOP) continue; - printf("%s: tx error buffer not ready\n", dev->name); + printf("%s: tx error buffer not ready\n", priv->name); goto done; } @@ -342,13 +345,13 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length) tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); tx_ring[tx_new].status = cpu_to_le32(T_OWN); - dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD); + dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD); for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) continue; - printf(".%s: tx buffer not ready\n", dev->name); + printf(".%s: tx buffer not ready\n", priv->name); goto done; } @@ -406,20 +409,22 @@ static int dc21x4x_recv(struct eth_device *dev) static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) { - int i; + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); int devbusfn = (int)dev->priv; + int i; /* Ensure we're not sleeping. */ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - reset_de4x5(dev); + reset_de4x5(priv); - if (dc2114x_inl(dev, DE4X5_STS) & (STS_TS | STS_RS)) { + if (dc2114x_inl(priv, DE4X5_STS) & (STS_TS | STS_RS)) { printf("Error: Cannot reset ethernet controller.\n"); return -1; } - dc2114x_outl(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); + dc2114x_outl(priv, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); for (i = 0; i < NUM_RX_DESC; i++) { rx_ring[i].status = cpu_to_le32(R_OWN); @@ -444,25 +449,27 @@ static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) tx_ring[tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ - dc2114x_outl(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); - dc2114x_outl(dev, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); + dc2114x_outl(priv, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); + dc2114x_outl(priv, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); - start_de4x5(dev); + start_de4x5(priv); tx_new = 0; rx_new = 0; - send_setup_frame(dev, bis); + send_setup_frame(priv, bis); return 0; } static void dc21x4x_halt(struct eth_device *dev) { + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); int devbusfn = (int)dev->priv; - stop_de4x5(dev); - dc2114x_outl(dev, 0, DE4X5_SICR); + stop_de4x5(priv); + dc2114x_outl(priv, 0, DE4X5_SICR); pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); } @@ -473,7 +480,7 @@ static void read_hw_addr(struct dc2114x_priv *priv) int i, j = 0; for (i = 0; i < (ETH_ALEN >> 1); i++) { - tmp = read_srom(dev, DE4X5_APROM, (SROM_HWADD >> 1) + i); + tmp = read_srom(priv, DE4X5_APROM, (SROM_HWADD >> 1) + i); *p = le16_to_cpu(tmp); j += *p++; } -- cgit From 8a5c6f158d68dd30bec672b141bf882296bff7e3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 06:50:41 +0200 Subject: net: dc2114x: Pass PCI BDF into phys_to_bus() This is a trick in preparation for adding DM support. By passing in the PCI BDF into the phys_to_bus() macros and calling that dev, we can substitute dev with udevice when DM support lands and do minor adjustment to the macros to support both DM and non-DM operation. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index eb7d29cf8f..75b10177fe 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -74,9 +74,9 @@ #define POLL_DEMAND 1 #if defined(CONFIG_E500) -#define phys_to_bus(a) (a) +#define phys_to_bus(dev, a) (a) #else -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) +#define phys_to_bus(dev, a) pci_phys_to_mem((dev), (a)) #endif #define NUM_RX_DESC PKTBUFSRX @@ -96,6 +96,7 @@ struct de4x5_desc { struct dc2114x_priv { struct eth_device dev; + pci_dev_t devno; char *name; void __iomem *iobase; u8 *enetaddr; @@ -278,7 +279,6 @@ static int read_srom(struct dc2114x_priv *priv, u_long ioaddr, int index) static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) { - struct eth_device *dev = &priv->dev; char setup_frame[SETUP_FRAME_LEN]; char *pa = &setup_frame[0]; int i; @@ -299,7 +299,8 @@ static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) return; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32)&setup_frame[0])); + tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno, + (u32)&setup_frame[0])); tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN); tx_ring[tx_new].status = cpu_to_le32(T_OWN); @@ -341,7 +342,8 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length) goto done; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32)packet)); + tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno, + (u32)packet)); tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); tx_ring[tx_new].status = cpu_to_le32(T_OWN); @@ -411,11 +413,10 @@ static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) { struct dc2114x_priv *priv = container_of(dev, struct dc2114x_priv, dev); - int devbusfn = (int)dev->priv; int i; /* Ensure we're not sleeping. */ - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); + pci_write_config_byte(priv->devno, PCI_CFDA_PSM, WAKEUP); reset_de4x5(priv); @@ -429,8 +430,8 @@ static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) for (i = 0; i < NUM_RX_DESC; i++) { rx_ring[i].status = cpu_to_le32(R_OWN); rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); - rx_ring[i].buf = - cpu_to_le32(phys_to_bus((u32)net_rx_packets[i])); + rx_ring[i].buf = cpu_to_le32(phys_to_bus(priv->devno, + (u32)net_rx_packets[i])); rx_ring[i].next = 0; } @@ -449,8 +450,10 @@ static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) tx_ring[tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ - dc2114x_outl(priv, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); - dc2114x_outl(priv, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); + dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&rx_ring), + DE4X5_RRBA); + dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&tx_ring), + DE4X5_TRBA); start_de4x5(priv); @@ -466,12 +469,11 @@ static void dc21x4x_halt(struct eth_device *dev) { struct dc2114x_priv *priv = container_of(dev, struct dc2114x_priv, dev); - int devbusfn = (int)dev->priv; stop_de4x5(priv); dc2114x_outl(priv, 0, DE4X5_SICR); - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); + pci_write_config_byte(priv->devno, PCI_CFDA_PSM, SLEEP); } static void read_hw_addr(struct dc2114x_priv *priv) @@ -551,6 +553,7 @@ int dc21x4x_initialize(struct bd_info *bis) dev = &priv->dev; sprintf(dev->name, "dc21x4x#%d", card_number); + priv->devno = devbusfn; priv->name = dev->name; priv->enetaddr = dev->enetaddr; -- cgit From 32d8d11800e8c25374dc7fd8de13869f8f26e183 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 07:01:32 +0200 Subject: net: dc2114x: Add RX/TX rings into the private data The RX/TX DMA descriptor rings are per-device-instance private data, so move them into the private data. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 92 +++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 75b10177fe..d55008de7d 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -95,6 +95,12 @@ struct de4x5_desc { }; struct dc2114x_priv { + struct de4x5_desc rx_ring[NUM_RX_DESC] __aligned(32); + struct de4x5_desc tx_ring[NUM_TX_DESC] __aligned(32); + int rx_new; /* RX descriptor ring pointer */ + int tx_new; /* TX descriptor ring pointer */ + char rx_ring_size; + char tx_ring_size; struct eth_device dev; pci_dev_t devno; char *name; @@ -103,14 +109,6 @@ struct dc2114x_priv { }; /* RX and TX descriptor ring */ -static struct de4x5_desc rx_ring[NUM_RX_DESC] __aligned(32); -static struct de4x5_desc tx_ring[NUM_TX_DESC] __aligned(32); -static int rx_new; /* RX descriptor ring pointer */ -static int tx_new; /* TX descriptor ring pointer */ - -static char rx_ring_size; -static char tx_ring_size; - static u32 dc2114x_inl(struct dc2114x_priv *priv, u32 addr) { return le32_to_cpu(readl(priv->iobase + addr)); @@ -291,7 +289,7 @@ static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) pa += 4; } - for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) continue; @@ -299,14 +297,14 @@ static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) return; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno, + priv->tx_ring[priv->tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno, (u32)&setup_frame[0])); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN); - tx_ring[tx_new].status = cpu_to_le32(T_OWN); + priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN); + priv->tx_ring[priv->tx_new].status = cpu_to_le32(T_OWN); dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD); - for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) continue; @@ -314,12 +312,12 @@ static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) return; } - if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { + if (le32_to_cpu(priv->tx_ring[priv->tx_new].status) != 0x7FFFFFFF) { printf("TX error status2 = 0x%08X\n", - le32_to_cpu(tx_ring[tx_new].status)); + le32_to_cpu(priv->tx_ring[priv->tx_new].status)); } - tx_new = (tx_new + 1) % NUM_TX_DESC; + priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC; } static int dc21x4x_send(struct eth_device *dev, void *packet, int length) @@ -334,7 +332,7 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length) goto done; } - for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) continue; @@ -342,14 +340,14 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length) goto done; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno, + priv->tx_ring[priv->tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno, (u32)packet)); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); - tx_ring[tx_new].status = cpu_to_le32(T_OWN); + priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); + priv->tx_ring[priv->tx_new].status = cpu_to_le32(T_OWN); dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD); - for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) continue; @@ -357,25 +355,27 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length) goto done; } - if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) { - tx_ring[tx_new].status = 0x0; + if (le32_to_cpu(priv->tx_ring[priv->tx_new].status) & TD_ES) { + priv->tx_ring[priv->tx_new].status = 0x0; goto done; } status = length; done: - tx_new = (tx_new + 1) % NUM_TX_DESC; + priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC; return status; } static int dc21x4x_recv(struct eth_device *dev) { + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); int length = 0; u32 status; while (true) { - status = le32_to_cpu(rx_ring[rx_new].status); + status = le32_to_cpu(priv->rx_ring[priv->rx_new].status); if (status & R_OWN) break; @@ -387,23 +387,23 @@ static int dc21x4x_recv(struct eth_device *dev) printf("RX error status = 0x%08X\n", status); } else { /* A valid frame received. */ - length = (le32_to_cpu(rx_ring[rx_new].status) + length = (le32_to_cpu(priv->rx_ring[priv->rx_new].status) >> 16); /* Pass the packet up to the protocol layers */ net_process_received_packet - (net_rx_packets[rx_new], length - 4); + (net_rx_packets[priv->rx_new], length - 4); } /* * Change buffer ownership for this frame, * back to the adapter. */ - rx_ring[rx_new].status = cpu_to_le32(R_OWN); + priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN); } /* Update entry information. */ - rx_new = (rx_new + 1) % rx_ring_size; + priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size; } return length; @@ -428,37 +428,37 @@ static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) dc2114x_outl(priv, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); for (i = 0; i < NUM_RX_DESC; i++) { - rx_ring[i].status = cpu_to_le32(R_OWN); - rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); - rx_ring[i].buf = cpu_to_le32(phys_to_bus(priv->devno, + priv->rx_ring[i].status = cpu_to_le32(R_OWN); + priv->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); + priv->rx_ring[i].buf = cpu_to_le32(phys_to_bus(priv->devno, (u32)net_rx_packets[i])); - rx_ring[i].next = 0; + priv->rx_ring[i].next = 0; } for (i = 0; i < NUM_TX_DESC; i++) { - tx_ring[i].status = 0; - tx_ring[i].des1 = 0; - tx_ring[i].buf = 0; - tx_ring[i].next = 0; + priv->tx_ring[i].status = 0; + priv->tx_ring[i].des1 = 0; + priv->tx_ring[i].buf = 0; + priv->tx_ring[i].next = 0; } - rx_ring_size = NUM_RX_DESC; - tx_ring_size = NUM_TX_DESC; + priv->rx_ring_size = NUM_RX_DESC; + priv->tx_ring_size = NUM_TX_DESC; /* Write the end of list marker to the descriptor lists. */ - rx_ring[rx_ring_size - 1].des1 |= cpu_to_le32(RD_RER); - tx_ring[tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER); + priv->rx_ring[priv->rx_ring_size - 1].des1 |= cpu_to_le32(RD_RER); + priv->tx_ring[priv->tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ - dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&rx_ring), + dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&priv->rx_ring), DE4X5_RRBA); - dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&tx_ring), + dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&priv->tx_ring), DE4X5_TRBA); start_de4x5(priv); - tx_new = 0; - rx_new = 0; + priv->tx_new = 0; + priv->rx_new = 0; send_setup_frame(priv, bis); @@ -543,7 +543,7 @@ int dc21x4x_initialize(struct bd_info *bis) iobase &= PCI_BASE_ADDRESS_MEM_MASK; debug("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); - priv = malloc(sizeof(*priv)); + priv = memalign(32, sizeof(*priv)); if (!priv) { printf("Can not allocalte memory of dc21x4x\n"); break; -- cgit From 05c4917958dbcb8b2c3e176e324c4482175d941e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 07:12:58 +0200 Subject: net: dc2114x: Split RX path Split the RX data check from the rest of the RX function, so that the check can be performed separately from the processing of the packet and the release of the received packet once the processing is finished. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 67 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index d55008de7d..527ad176c3 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -367,41 +367,60 @@ done: return status; } +static int dc21x4x_recv_check(struct dc2114x_priv *priv) +{ + int length = 0; + u32 status; + + status = le32_to_cpu(priv->rx_ring[priv->rx_new].status); + + if (status & R_OWN) + return 0; + + if (status & RD_LS) { + /* Valid frame status. */ + if (status & RD_ES) { + /* There was an error. */ + printf("RX error status = 0x%08X\n", status); + return -EINVAL; + } else { + /* A valid frame received. */ + length = (le32_to_cpu(priv->rx_ring[priv->rx_new].status) + >> 16); + + return length; + } + } + + return -EAGAIN; +} + static int dc21x4x_recv(struct eth_device *dev) { struct dc2114x_priv *priv = container_of(dev, struct dc2114x_priv, dev); int length = 0; - u32 status; + int ret; while (true) { - status = le32_to_cpu(priv->rx_ring[priv->rx_new].status); - - if (status & R_OWN) + ret = dc21x4x_recv_check(priv); + if (!ret) break; - if (status & RD_LS) { - /* Valid frame status. */ - if (status & RD_ES) { - /* There was an error. */ - printf("RX error status = 0x%08X\n", status); - } else { - /* A valid frame received. */ - length = (le32_to_cpu(priv->rx_ring[priv->rx_new].status) - >> 16); - - /* Pass the packet up to the protocol layers */ - net_process_received_packet - (net_rx_packets[priv->rx_new], length - 4); - } - - /* - * Change buffer ownership for this frame, - * back to the adapter. - */ - priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN); + if (ret > 0) { + length = ret; + /* Pass the packet up to the protocol layers */ + net_process_received_packet + (net_rx_packets[priv->rx_new], length - 4); } + /* + * Change buffer ownership for this frame, + * back to the adapter. + */ + if (ret != -EAGAIN) + priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN); + /* Update entry information. */ priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size; } -- cgit From bc4666acf3b49a9feb36c580703102d228545955 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 07:20:14 +0200 Subject: net: dc2114x: Split common parts of non-DM functions out Split the common code from the non-DM code, so it can be reused by the DM code later. As always, the recv() function had to be split into the actual receiving part and free_pkt part to fit with the DM. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 117 +++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 527ad176c3..8842d61e6e 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -275,7 +275,7 @@ static int read_srom(struct dc2114x_priv *priv, u_long ioaddr, int index) 3 + ee_addr_size + 16); } -static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) +static void send_setup_frame(struct dc2114x_priv *priv) { char setup_frame[SETUP_FRAME_LEN]; char *pa = &setup_frame[0]; @@ -320,10 +320,8 @@ static void send_setup_frame(struct dc2114x_priv *priv, struct bd_info *bis) priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC; } -static int dc21x4x_send(struct eth_device *dev, void *packet, int length) +static int dc21x4x_send_common(struct dc2114x_priv *priv, void *packet, int length) { - struct dc2114x_priv *priv = - container_of(dev, struct dc2114x_priv, dev); int status = -1; int i; @@ -395,48 +393,10 @@ static int dc21x4x_recv_check(struct dc2114x_priv *priv) return -EAGAIN; } -static int dc21x4x_recv(struct eth_device *dev) -{ - struct dc2114x_priv *priv = - container_of(dev, struct dc2114x_priv, dev); - int length = 0; - int ret; - - while (true) { - ret = dc21x4x_recv_check(priv); - if (!ret) - break; - - if (ret > 0) { - length = ret; - /* Pass the packet up to the protocol layers */ - net_process_received_packet - (net_rx_packets[priv->rx_new], length - 4); - } - - /* - * Change buffer ownership for this frame, - * back to the adapter. - */ - if (ret != -EAGAIN) - priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN); - - /* Update entry information. */ - priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size; - } - - return length; -} - -static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) +static int dc21x4x_init_common(struct dc2114x_priv *priv) { - struct dc2114x_priv *priv = - container_of(dev, struct dc2114x_priv, dev); int i; - /* Ensure we're not sleeping. */ - pci_write_config_byte(priv->devno, PCI_CFDA_PSM, WAKEUP); - reset_de4x5(priv); if (dc2114x_inl(priv, DE4X5_STS) & (STS_TS | STS_RS)) { @@ -479,20 +439,15 @@ static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) priv->tx_new = 0; priv->rx_new = 0; - send_setup_frame(priv, bis); + send_setup_frame(priv); return 0; } -static void dc21x4x_halt(struct eth_device *dev) +static void dc21x4x_halt_common(struct dc2114x_priv *priv) { - struct dc2114x_priv *priv = - container_of(dev, struct dc2114x_priv, dev); - stop_de4x5(priv); dc2114x_outl(priv, 0, DE4X5_SICR); - - pci_write_config_byte(priv->devno, PCI_CFDA_PSM, SLEEP); } static void read_hw_addr(struct dc2114x_priv *priv) @@ -518,6 +473,68 @@ static struct pci_device_id supported[] = { { } }; +static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) +{ + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); + + /* Ensure we're not sleeping. */ + pci_write_config_byte(priv->devno, PCI_CFDA_PSM, WAKEUP); + + return dc21x4x_init_common(priv); +} + +static void dc21x4x_halt(struct eth_device *dev) +{ + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); + + dc21x4x_halt_common(priv); + + pci_write_config_byte(priv->devno, PCI_CFDA_PSM, SLEEP); +} + +static int dc21x4x_send(struct eth_device *dev, void *packet, int length) +{ + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); + + return dc21x4x_send_common(priv, packet, length); +} + +static int dc21x4x_recv(struct eth_device *dev) +{ + struct dc2114x_priv *priv = + container_of(dev, struct dc2114x_priv, dev); + int length = 0; + int ret; + + while (true) { + ret = dc21x4x_recv_check(priv); + if (!ret) + break; + + if (ret > 0) { + length = ret; + /* Pass the packet up to the protocol layers */ + net_process_received_packet + (net_rx_packets[priv->rx_new], length - 4); + } + + /* + * Change buffer ownership for this frame, + * back to the adapter. + */ + if (ret != -EAGAIN) + priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN); + + /* Update entry information. */ + priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size; + } + + return length; +} + int dc21x4x_initialize(struct bd_info *bis) { struct dc2114x_priv *priv; -- cgit From f23a785cfb451f3fcb457ed1f9141907dce7dd77 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Jul 2020 07:26:14 +0200 Subject: net: dc2114x: Add DM support With all the changes in place, add support for DM into the dc2114x driver. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Ramon Fried --- drivers/net/dc2114x.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 8842d61e6e..9f8c6c58d9 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -73,7 +73,9 @@ #define POLL_DEMAND 1 -#if defined(CONFIG_E500) +#if defined(CONFIG_DM_ETH) +#define phys_to_bus(dev, a) dm_pci_phys_to_mem((dev), (a)) +#elif defined(CONFIG_E500) #define phys_to_bus(dev, a) (a) #else #define phys_to_bus(dev, a) pci_phys_to_mem((dev), (a)) @@ -101,8 +103,12 @@ struct dc2114x_priv { int tx_new; /* TX descriptor ring pointer */ char rx_ring_size; char tx_ring_size; +#ifdef CONFIG_DM_ETH + struct udevice *devno; +#else struct eth_device dev; pci_dev_t devno; +#endif char *name; void __iomem *iobase; u8 *enetaddr; @@ -473,6 +479,7 @@ static struct pci_device_id supported[] = { { } }; +#ifndef CONFIG_DM_ETH static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis) { struct dc2114x_priv *priv = @@ -614,3 +621,139 @@ int dc21x4x_initialize(struct bd_info *bis) return card_number; } + +#else /* DM_ETH */ +static int dc2114x_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct dc2114x_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + /* Ensure we're not sleeping. */ + dm_pci_write_config8(dev, PCI_CFDA_PSM, WAKEUP); + + return dc21x4x_init_common(priv); +} + +static void dc2114x_stop(struct udevice *dev) +{ + struct dc2114x_priv *priv = dev_get_priv(dev); + + dc21x4x_halt_common(priv); + + dm_pci_write_config8(dev, PCI_CFDA_PSM, SLEEP); +} + +static int dc2114x_send(struct udevice *dev, void *packet, int length) +{ + struct dc2114x_priv *priv = dev_get_priv(dev); + int ret; + + ret = dc21x4x_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int dc2114x_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct dc2114x_priv *priv = dev_get_priv(dev); + int ret; + + ret = dc21x4x_recv_check(priv); + + if (ret < 0) { + /* Update entry information. */ + priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size; + ret = 0; + } + + if (!ret) + return 0; + + *packetp = net_rx_packets[priv->rx_new]; + + return ret - 4; +} + +static int dc2114x_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct dc2114x_priv *priv = dev_get_priv(dev); + + priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN); + + /* Update entry information. */ + priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size; + + return 0; +} + +static int dc2114x_read_rom_hwaddr(struct udevice *dev) +{ + struct dc2114x_priv *priv = dev_get_priv(dev); + + read_hw_addr(priv); + + return 0; +} + +static int dc2114x_bind(struct udevice *dev) +{ + static int card_number; + char name[16]; + + sprintf(name, "dc2114x#%u", card_number++); + + return device_set_name(dev, name); +} + +static int dc2114x_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct dc2114x_priv *priv = dev_get_priv(dev); + u16 command, status; + u32 iobase; + + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase); + iobase &= ~0xf; + + debug("dc2114x: DEC 2114x PCI Device @0x%x\n", iobase); + + priv->devno = dev; + priv->enetaddr = plat->enetaddr; + priv->iobase = (void __iomem *)dm_pci_mem_to_phys(dev, iobase); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, command); + dm_pci_read_config16(dev, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("dc2114x: Couldn't enable IO access or Bus Mastering\n"); + return -EINVAL; + } + + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x60); + + return 0; +} + +static const struct eth_ops dc2114x_ops = { + .start = dc2114x_start, + .send = dc2114x_send, + .recv = dc2114x_recv, + .stop = dc2114x_stop, + .free_pkt = dc2114x_free_pkt, + .read_rom_hwaddr = dc2114x_read_rom_hwaddr, +}; + +U_BOOT_DRIVER(eth_dc2114x) = { + .name = "eth_dc2114x", + .id = UCLASS_ETH, + .bind = dc2114x_bind, + .probe = dc2114x_probe, + .ops = &dc2114x_ops, + .priv_auto_alloc_size = sizeof(struct dc2114x_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; + +U_BOOT_PCI_DEVICE(eth_dc2114x, supported); +#endif -- cgit