From 635a76b703f3bd5b20e28bfc86caee9889f536c2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 18 Apr 2020 01:44:12 +0200 Subject: net: pcnet: Remove CONFIG_PCNET_79C97x These macros guard one switch-case statement, which grows mips malta by some 20 bytes if debug is enabled, and even less if it is not. To make the code simpler, just support all the NICs and be done with it. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/pcnet.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b4ad11d..59241c9 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -21,10 +21,6 @@ #define PCNET_DEBUG2(fmt,args...) \ debug_cond(PCNET_DEBUG_LEVEL > 1, fmt ,##args) -#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975) -#error "Macro for PCnet chip version is not defined!" -#endif - /* * Set the number of Tx and Rx buffers, using Log_2(# buffers). * Reasonable default values are 4 Tx buffers, and 16 Rx buffers. @@ -254,16 +250,12 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) case 0x2621: chipname = "PCnet/PCI II 79C970A"; /* PCI */ break; -#ifdef CONFIG_PCNET_79C973 case 0x2625: chipname = "PCnet/FAST III 79C973"; /* PCI */ break; -#endif -#ifdef CONFIG_PCNET_79C975 case 0x2627: chipname = "PCnet/FAST III 79C975"; /* PCI */ break; -#endif default: printf("%s: PCnet version %#x not supported\n", dev->name, chip_version); -- cgit v1.1 From 171f5e580e3388090d589aa4c0f123576948ab52 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 18 Apr 2020 01:56:51 +0200 Subject: net: tulip: Remove CONFIG_TULIP_* These macros are not used by any board, remove them to simplify the driver. The EEPROM accessors are still retained however, as those might still be useful. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 88 +++------------------------------------------------ 1 file changed, 5 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 43c2253..40bfc52 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -77,15 +77,6 @@ #define POLL_DEMAND 1 -#ifdef CONFIG_TULIP_FIX_DAVICOM -#define RESET_DM9102(dev) {\ - unsigned long i;\ - i=INL(dev, 0x0);\ - udelay(1000);\ - OUTL(dev, i | BMR_SWR, DE4X5_BMR);\ - udelay(1000);\ -} -#else #define RESET_DE4X5(dev) {\ int i;\ i=INL(dev, DE4X5_BMR);\ @@ -97,7 +88,6 @@ for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\ udelay(1000);\ } -#endif #define START_DE4X5(dev) {\ s32 omr; \ @@ -114,11 +104,7 @@ } #define NUM_RX_DESC PKTBUFSRX -#ifndef CONFIG_TULIP_FIX_DAVICOM - #define NUM_TX_DESC 1 /* Number of TX descriptors */ -#else - #define NUM_TX_DESC 4 -#endif +#define NUM_TX_DESC 1 /* Number of TX descriptors */ #define RX_BUFF_SZ PKTSIZE_ALIGN #define TOUT_LOOP 1000000 @@ -140,29 +126,22 @@ static int tx_new; /* TX descriptor ring pointer */ static char rxRingSize; static char txRingSize; -#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) static void sendto_srom(struct eth_device* dev, u_int command, u_long addr); static int getfrom_srom(struct eth_device* dev, u_long addr); static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len); static int do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len); -#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */ #ifdef UPDATE_SROM static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value); static void update_srom(struct eth_device *dev, bd_t *bis); #endif -#ifndef CONFIG_TULIP_FIX_DAVICOM static int read_srom(struct eth_device *dev, u_long ioaddr, int index); static void read_hw_addr(struct eth_device* dev, bd_t * bis); -#endif /* CONFIG_TULIP_FIX_DAVICOM */ static void send_setup_frame(struct eth_device* dev, bd_t * bis); static int dc21x4x_init(struct eth_device* dev, bd_t* bis); static int dc21x4x_send(struct eth_device *dev, void *packet, int length); static int dc21x4x_recv(struct eth_device* dev); static void dc21x4x_halt(struct eth_device* dev); -#ifdef CONFIG_TULIP_SELECT_MEDIA -extern void dc21x4x_select_media(struct eth_device* dev); -#endif #if defined(CONFIG_E500) #define phys_to_bus(a) (a) @@ -183,9 +162,6 @@ static void OUTL(struct eth_device* dev, int command, u_long addr) 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 }, -#ifdef CONFIG_TULIP_FIX_DAVICOM - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A }, -#endif { } }; @@ -209,35 +185,22 @@ int dc21x4x_initialize(bd_t *bis) /* Get the chip configuration revision register. */ pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); -#ifndef CONFIG_TULIP_FIX_DAVICOM if ((cfrv & CFRV_RN) < DC2114x_BRK ) { printf("Error: The chip is not DC21143.\n"); continue; } -#endif pci_read_config_word(devbusfn, PCI_COMMAND, &status); status |= -#ifdef CONFIG_TULIP_USE_IO - PCI_COMMAND_IO | -#else PCI_COMMAND_MEMORY | -#endif PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, status); pci_read_config_word(devbusfn, PCI_COMMAND, &status); -#ifdef CONFIG_TULIP_USE_IO - if (!(status & PCI_COMMAND_IO)) { - printf("Error: Can not enable I/O access.\n"); - continue; - } -#else if (!(status & PCI_COMMAND_MEMORY)) { printf("Error: Can not enable MEMORY access.\n"); continue; } -#endif if (!(status & PCI_COMMAND_MASTER)) { printf("Error: Can not enable Bus Mastering.\n"); @@ -251,15 +214,9 @@ int dc21x4x_initialize(bd_t *bis) pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60); } -#ifdef CONFIG_TULIP_USE_IO - /* read BAR for memory space access */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase); - iobase &= PCI_BASE_ADDRESS_IO_MASK; -#else /* read BAR for memory space access */ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase); iobase &= PCI_BASE_ADDRESS_MEM_MASK; -#endif debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); dev = (struct eth_device*) malloc(sizeof *dev); @@ -270,17 +227,9 @@ int dc21x4x_initialize(bd_t *bis) } memset(dev, 0, sizeof(*dev)); -#ifdef CONFIG_TULIP_FIX_DAVICOM - sprintf(dev->name, "Davicom#%d", card_number); -#else sprintf(dev->name, "dc21x4x#%d", card_number); -#endif -#ifdef CONFIG_TULIP_USE_IO - dev->iobase = pci_io_to_phys(devbusfn, iobase); -#else dev->iobase = pci_mem_to_phys(devbusfn, iobase); -#endif dev->priv = (void*) devbusfn; dev->init = dc21x4x_init; dev->halt = dc21x4x_halt; @@ -292,9 +241,8 @@ int dc21x4x_initialize(bd_t *bis) udelay(10 * 1000); -#ifndef CONFIG_TULIP_FIX_DAVICOM read_hw_addr(dev, bis); -#endif + eth_register(dev); card_number++; @@ -311,46 +259,28 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* bis) /* Ensure we're not sleeping. */ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); -#ifdef CONFIG_TULIP_FIX_DAVICOM - RESET_DM9102(dev); -#else RESET_DE4X5(dev); -#endif if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) { printf("Error: Cannot reset ethernet controller.\n"); return -1; } -#ifdef CONFIG_TULIP_SELECT_MEDIA - dc21x4x_select_media(dev); -#else OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); -#endif 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])); -#ifdef CONFIG_TULIP_FIX_DAVICOM - rx_ring[i].next = cpu_to_le32( - phys_to_bus((u32)&rx_ring[(i + 1) % NUM_RX_DESC])); -#else rx_ring[i].next = 0; -#endif } for (i=0; i < NUM_TX_DESC; i++) { tx_ring[i].status = 0; tx_ring[i].des1 = 0; tx_ring[i].buf = 0; - -#ifdef CONFIG_TULIP_FIX_DAVICOM - tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC])); -#else tx_ring[i].next = 0; -#endif } rxRingSize = NUM_RX_DESC; @@ -520,9 +450,7 @@ Done: return; } -#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) -/* SROM Read and write routines. - */ +/* SROM Read and write routines. */ static void sendto_srom(struct eth_device* dev, u_int command, u_long addr) { @@ -594,13 +522,12 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, i return retval; } -#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */ -/* This executes a generic EEPROM command, typically a write or write +/* + * This executes a generic EEPROM command, typically a write or write * enable. It returns the data output from the EEPROM, and thus may * also be used for reads. */ -#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len) { unsigned retval = 0; @@ -636,9 +563,7 @@ static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd return retval; } -#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */ -#ifndef CONFIG_TULIP_FIX_DAVICOM static int read_srom(struct eth_device *dev, u_long ioaddr, int index) { int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; @@ -647,7 +572,6 @@ static int read_srom(struct eth_device *dev, u_long ioaddr, int index) (((SROM_READ_CMD << ee_addr_size) | index) << 16) | 0xffff, 3 + ee_addr_size + 16); } -#endif /* CONFIG_TULIP_FIX_DAVICOM */ #ifdef UPDATE_SROM static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value) @@ -695,7 +619,6 @@ static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_ } #endif -#ifndef CONFIG_TULIP_FIX_DAVICOM static void read_hw_addr(struct eth_device *dev, bd_t *bis) { u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); @@ -721,7 +644,6 @@ Done: #endif return; } -#endif /* CONFIG_TULIP_FIX_DAVICOM */ #ifdef UPDATE_SROM static void update_srom(struct eth_device *dev, bd_t *bis) -- cgit v1.1 From 3c0bcb97d6d7ed7f9b4c46eb2a6dd0e910214faf Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 18 Apr 2020 02:32:19 +0200 Subject: net: pcnet: Replace mips-specific accessors Replace mips-specific UNCACHED_SDRAM() macro with standard map_physmem(), which permits the driver to work on other systems than mips. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 59241c9..e7d6c8d 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -332,7 +332,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); flush_dcache_range(addr, addr + sizeof(*lp->uc)); - addr = UNCACHED_SDRAM(addr); + addr = (unsigned long)map_physmem(addr, + roundup(sizeof(*lp->uc), ARCH_DMA_MINALIGN), + MAP_NOCACHE); lp->uc = (struct pcnet_uncached_priv *)addr; addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, -- cgit v1.1 From 69529c912059ed4585f648cc6cde1a2fbd5b722b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 18 Apr 2020 05:11:05 +0200 Subject: net: pcnet: Switch to PCI memory access Replace the PCI IO access with PCI memory access, the card supports both, but the former does not work with QEMU SH4. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index e7d6c8d..34a5a16 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -179,14 +179,14 @@ int pcnet_initialize(bd_t *bis) /* * Setup the PCI device. */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &bar); - dev->iobase = pci_io_to_phys(devbusfn, bar); + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); + dev->iobase = pci_mem_to_phys(devbusfn, bar); dev->iobase &= ~0xf; PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", dev->name, devbusfn, (unsigned long)dev->iobase); - command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); pci_read_config_word(devbusfn, PCI_COMMAND, &status); if ((status & command) != command) { -- cgit v1.1 From ca5cb04b7fef31d66461cb58872d9ea32a24628b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:09:47 +0200 Subject: net: dc2114x: Clean up init code Clean up the driver init code to bring it up to standards with U-Boot coding style, no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 40bfc52..d302d03 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -167,33 +167,30 @@ static struct pci_device_id supported[] = { int dc21x4x_initialize(bd_t *bis) { - int idx=0; - int card_number = 0; - unsigned int cfrv; - unsigned char timer; - pci_dev_t devbusfn; - unsigned int iobase; - unsigned short status; - struct eth_device* dev; - - while(1) { - devbusfn = pci_find_devices(supported, idx++); - if (devbusfn == -1) { + struct eth_device *dev; + unsigned short status; + unsigned char timer; + unsigned int iobase; + int card_number = 0; + pci_dev_t devbusfn; + unsigned int cfrv; + int idx = 0; + + while (1) { + devbusfn = pci_find_devices(supported, idx++); + 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 ) { + 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; + status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, status); pci_read_config_word(devbusfn, PCI_COMMAND, &status); @@ -211,30 +208,31 @@ int dc21x4x_initialize(bd_t *bis) pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer); if (timer < 0x60) { - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60); + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, + 0x60); } /* read BAR for memory space access */ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase); iobase &= PCI_BASE_ADDRESS_MEM_MASK; - debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); - - dev = (struct eth_device*) malloc(sizeof *dev); + debug("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); + dev = (struct eth_device *)malloc(sizeof(*dev)); if (!dev) { printf("Can not allocalte memory of dc21x4x\n"); break; } + memset(dev, 0, sizeof(*dev)); sprintf(dev->name, "dc21x4x#%d", card_number); dev->iobase = pci_mem_to_phys(devbusfn, iobase); - dev->priv = (void*) devbusfn; - dev->init = dc21x4x_init; - dev->halt = dc21x4x_halt; - dev->send = dc21x4x_send; - dev->recv = dc21x4x_recv; + dev->priv = (void *)devbusfn; + dev->init = dc21x4x_init; + dev->halt = dc21x4x_halt; + dev->send = dc21x4x_send; + dev->recv = dc21x4x_recv; /* Ensure we're not sleeping. */ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); @@ -251,10 +249,10 @@ int dc21x4x_initialize(bd_t *bis) return card_number; } -static int dc21x4x_init(struct eth_device* dev, bd_t* bis) +static int dc21x4x_init(struct eth_device *dev, bd_t *bis) { - int i; - int devbusfn = (int) dev->priv; + int i; + int devbusfn = (int)dev->priv; /* Ensure we're not sleeping. */ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); @@ -271,12 +269,12 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* 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((u32)net_rx_packets[i])); rx_ring[i].next = 0; } - for (i=0; i < NUM_TX_DESC; i++) { + for (i = 0; i < NUM_TX_DESC; i++) { tx_ring[i].status = 0; tx_ring[i].des1 = 0; tx_ring[i].buf = 0; @@ -291,8 +289,8 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* bis) tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ - OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA); - OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA); + OUTL(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); + OUTL(dev, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); START_DE4X5(dev); -- cgit v1.1 From 7c53e3364e4dc7dc4752a75f18a3d72548098365 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:10:14 +0200 Subject: net: dc2114x: Clean up dc21x4x_send() Clean up the driver send code to bring it up to standards with U-Boot coding style, invert the loops where applicable to cut down the level of indent. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index d302d03..11ebea9 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -304,47 +304,45 @@ static int dc21x4x_init(struct eth_device *dev, bd_t *bis) static int dc21x4x_send(struct eth_device *dev, void *packet, int length) { - int status = -1; - int i; + int status = -1; + int i; if (length <= 0) { printf("%s: bad packet size: %d\n", dev->name, length); - goto Done; + goto done; } - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx error buffer not ready\n", dev->name); - goto Done; - } + for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + if (i < TOUT_LOOP) + continue; + + printf("%s: tx error buffer not ready\n", dev->name); + goto done; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) packet)); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); + tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((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); OUTL(dev, POLL_DEMAND, DE4X5_TPD); - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf(".%s: tx buffer not ready\n", dev->name); - goto Done; - } + 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); + goto done; } if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) { -#if 0 /* test-only */ - printf("TX error status = 0x%08X\n", - le32_to_cpu(tx_ring[tx_new].status)); -#endif tx_ring[tx_new].status = 0x0; - goto Done; + goto done; } status = length; - Done: - tx_new = (tx_new+1) % NUM_TX_DESC; +done: + tx_new = (tx_new + 1) % NUM_TX_DESC; return status; } -- cgit v1.1 From 9308df81a206e73687a8ba7a1f1b3753e2f2fd79 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:10:25 +0200 Subject: net: dc2114x: Clean up dc21x4x_recv() Clean up the driver recv code to bring it up to standards with U-Boot coding style. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 11ebea9..4d2e116 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -346,46 +346,40 @@ done: return status; } -static int dc21x4x_recv(struct eth_device* dev) +static int dc21x4x_recv(struct eth_device *dev) { - s32 status; - int length = 0; + int length = 0; + u32 status; - for ( ; ; ) { - status = (s32)le32_to_cpu(rx_ring[rx_new].status); + while (true) { + status = le32_to_cpu(rx_ring[rx_new].status); - if (status & R_OWN) { + if (status & R_OWN) break; - } if (status & RD_LS) { - /* Valid frame status. - */ + /* Valid frame status. */ if (status & RD_ES) { - - /* There was an error. - */ + /* There was an error. */ printf("RX error status = 0x%08X\n", status); } else { - /* A valid frame received. - */ - length = (le32_to_cpu(rx_ring[rx_new].status) >> 16); - - /* Pass the packet up to the protocol - * layers. - */ - net_process_received_packet( - net_rx_packets[rx_new], length - 4); + /* A valid frame received. */ + length = (le32_to_cpu(rx_ring[rx_new].status) + >> 16); + + /* Pass the packet up to the protocol layers */ + net_process_received_packet + (net_rx_packets[rx_new], length - 4); } - /* Change buffer ownership for this frame, back - * to the adapter. + /* + * Change buffer ownership for this frame, + * back to the adapter. */ rx_ring[rx_new].status = cpu_to_le32(R_OWN); } - /* Update entry information. - */ + /* Update entry information. */ rx_new = (rx_new + 1) % rxRingSize; } -- cgit v1.1 From 5b4e7dfb879c4b127f27bd92bac68e114d5e0b70 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:10:30 +0200 Subject: net: dc2114x: Clean up dc21x4x_halt() Clean up the driver halt code to bring it up to standards with U-Boot coding style. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- 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 4d2e116..6fe0511 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -386,9 +386,9 @@ static int dc21x4x_recv(struct eth_device *dev) return length; } -static void dc21x4x_halt(struct eth_device* dev) +static void dc21x4x_halt(struct eth_device *dev) { - int devbusfn = (int) dev->priv; + int devbusfn = (int)dev->priv; STOP_DE4X5(dev); OUTL(dev, 0, DE4X5_SICR); -- cgit v1.1 From 5a0c332a8a6fee7deadda5c8439782aa5f7b9ca2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:10:50 +0200 Subject: net: dc2114x: Clean up send_setup_frame() Clean up the send_setup_frame() to bring it up to standards with U-Boot coding style, invert the loops where applicable to cut down the level of indent. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 6fe0511..bd64c75 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -396,48 +396,48 @@ static void dc21x4x_halt(struct eth_device *dev) pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); } -static void send_setup_frame(struct eth_device* dev, bd_t *bis) +static void send_setup_frame(struct eth_device *dev, bd_t *bis) { - int i; - char setup_frame[SETUP_FRAME_LEN]; - char *pa = &setup_frame[0]; + char setup_frame[SETUP_FRAME_LEN]; + char *pa = &setup_frame[0]; + int i; memset(pa, 0xff, SETUP_FRAME_LEN); for (i = 0; i < ETH_ALEN; i++) { *(pa + (i & 1)) = dev->enetaddr[i]; - if (i & 0x01) { + if (i & 0x01) pa += 4; - } } - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx error buffer not ready\n", dev->name); - goto Done; - } + for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + if (i < TOUT_LOOP) + continue; + + printf("%s: tx error buffer not ready\n", dev->name); + return; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0])); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN); + tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((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); OUTL(dev, POLL_DEMAND, DE4X5_TPD); - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx buffer not ready\n", dev->name); - goto Done; - } + 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); + return; } if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { - printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status)); + printf("TX error status2 = 0x%08X\n", + le32_to_cpu(tx_ring[tx_new].status)); } - tx_new = (tx_new+1) % NUM_TX_DESC; -Done: - return; + tx_new = (tx_new + 1) % NUM_TX_DESC; } /* SROM Read and write routines. */ -- cgit v1.1 From 2e5c2a103edeed19bfbf393e8550a7bd77e62dfa Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:11:06 +0200 Subject: net: dc2114x: Clean up SROM operations Clean up the SROM accessors to bring them up to standards with U-Boot coding style. Sort variable into reverse xmas tree. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 117 +++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index bd64c75..b375906e 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -441,30 +441,27 @@ static void send_setup_frame(struct eth_device *dev, bd_t *bis) } /* SROM Read and write routines. */ -static void -sendto_srom(struct eth_device* dev, u_int command, u_long addr) +static void sendto_srom(struct eth_device *dev, u_int command, u_long addr) { OUTL(dev, command, addr); udelay(1); } -static int -getfrom_srom(struct eth_device* dev, u_long addr) +static int getfrom_srom(struct eth_device *dev, u_long addr) { - s32 tmp; + s32 tmp = INL(dev, addr); - tmp = INL(dev, 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, int addr_len) +static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, + int addr_len) { - int i; - unsigned retval = 0; 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); @@ -476,14 +473,18 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, i /* Shift the read command bits out. */ 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, ioaddr); + + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, + ioaddr); udelay(10); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr); + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, + ioaddr); udelay(10); #ifdef DEBUG_SROM2 printf("%X", getfrom_srom(dev, ioaddr) & 15); #endif - retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0); + retval = (retval << 1) | + !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); } sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); @@ -498,7 +499,8 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, i #ifdef DEBUG_SROM2 printf("%X", getfrom_srom(dev, ioaddr) & 15); #endif - retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0); + retval = (retval << 1) | + !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); udelay(10); } @@ -518,34 +520,38 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, i * 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, int cmd_len) +static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, + int cmd_len) { - unsigned retval = 0; + unsigned int retval = 0; #ifdef DEBUG_SROM printf(" EEPROM op 0x%x: ", cmd); #endif - sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); /* Shift the command bits out. */ do { - short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; - sendto_srom(dev,dataval, ioaddr); + short dataval = (cmd & BIT(cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; + + sendto_srom(dev, dataval, ioaddr); udelay(10); #ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev,ioaddr) & 15); + printf("%X", getfrom_srom(dev, ioaddr) & 15); #endif - sendto_srom(dev,dataval | DT_CLK, ioaddr); + sendto_srom(dev, dataval | DT_CLK, ioaddr); udelay(10); - retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0); + retval = (retval << 1) | + !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); } while (--cmd_len >= 0); - sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr); + + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); /* Terminate the EEPROM access. */ - sendto_srom(dev,SROM_RD | SROM_SR, ioaddr); + sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); #ifdef DEBUG_SROM printf(" EEPROM result is 0x%5.5x.\n", retval); @@ -556,21 +562,26 @@ static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd static int read_srom(struct eth_device *dev, u_long ioaddr, int index) { - int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; + int ee_addr_size; - return do_eeprom_cmd(dev, ioaddr, - (((SROM_READ_CMD << ee_addr_size) | index) << 16) - | 0xffff, 3 + ee_addr_size + 16); + ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; + + return do_eeprom_cmd(dev, ioaddr, 0xffff | + (((SROM_READ_CMD << ee_addr_size) | index) << 16), + 3 + ee_addr_size + 16); } #ifdef UPDATE_SROM -static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value) +static int write_srom(struct eth_device *dev, u_long ioaddr, int index, + int new_value) { - int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; - int i; unsigned short newval; + int ee_addr_size; + int i; - udelay(10*1000); /* test-only */ + ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; + + udelay(10 * 1000); /* test-only */ #ifdef DEBUG_SROM printf("ee_addr_size=%d.\n", ee_addr_size); @@ -578,33 +589,37 @@ static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_ #endif /* Enable programming modes. */ - do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size); + do_eeprom_cmd(dev, ioaddr, 0x4f << (ee_addr_size - 4), + 3 + ee_addr_size); /* Do the actual write. */ - do_eeprom_cmd(dev, ioaddr, - (((SROM_WRITE_CMD<> 1); i++) { - tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i)); + tmp = read_srom(dev, DE4X5_APROM, (SROM_HWADD >> 1) + i); *p = le16_to_cpu(tmp); j += *p++; } - if ((j == 0) || (j == 0x2fffd)) { - memset (dev->enetaddr, 0, ETH_ALEN); - debug ("Warning: can't read HW address from SROM.\n"); - goto Done; - } - - return; - -Done: + 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); + update_srom(dev, bis); #endif - return; + } } #ifdef UPDATE_SROM static void update_srom(struct eth_device *dev, bd_t *bis) { - int i; static unsigned short eeprom[0x40] = { 0x140b, 0x6610, 0x0000, 0x0000, /* 00 */ 0x0000, 0x0000, 0x0000, 0x0000, /* 04 */ @@ -658,16 +666,17 @@ static void update_srom(struct eth_device *dev, bd_t *bis) 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++) { + for (i = 0; i < 0x40; i++) write_srom(dev, DE4X5_APROM, i, eeprom[i]); - } } -#endif /* UPDATE_SROM */ +#endif /* UPDATE_SROM */ -- cgit v1.1 From eb216f1e0005ea1b3e125efeb32d72d1691eea2d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:09:26 +0200 Subject: net: dc2114x: Clean up remaining driver code Clean up the remaining driver code, macro space alignment, function declaration indent, replace __attribute__((aligned(32))) with plain __aligned(32). No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 86 +++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index b375906e..007e4ce 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -12,19 +12,17 @@ #undef UPDATE_SROM -/* PCI Registers. - */ -#define PCI_CFDA_PSM 0x43 +/* PCI Registers. */ +#define PCI_CFDA_PSM 0x43 #define CFRV_RN 0x000000f0 /* Revision Number */ #define WAKEUP 0x00 /* Power Saving Wakeup */ #define SLEEP 0x80 /* Power Saving Sleep Mode */ -#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */ +#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */ -/* Ethernet chip registers. - */ +/* Ethernet chip registers. */ #define DE4X5_BMR 0x000 /* Bus Mode Register */ #define DE4X5_TPD 0x008 /* Transmit Poll Demand Reg */ #define DE4X5_RRBA 0x018 /* RX Ring Base Address Reg */ @@ -34,8 +32,7 @@ #define DE4X5_SICR 0x068 /* SIA Connectivity Register */ #define DE4X5_APROM 0x048 /* Ethernet Address PROM */ -/* Register bits. - */ +/* Register bits. */ #define BMR_SWR 0x00000001 /* Software Reset */ #define STS_TS 0x00700000 /* Transmit Process State */ #define STS_RS 0x000e0000 /* Receive Process State */ @@ -45,8 +42,7 @@ #define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */ #define OMR_PM 0x00000080 /* Pass All Multicast */ -/* Descriptor bits. - */ +/* Descriptor bits. */ #define R_OWN 0x80000000 /* Own Bit */ #define RD_RER 0x02000000 /* Receive End Of Ring */ #define RD_LS 0x00000100 /* Last Descriptor */ @@ -63,12 +59,12 @@ #define SROM_READ_CMD 6 #define SROM_ERASE_CMD 7 -#define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */ +#define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */ #define SROM_RD 0x00004000 /* Read from Boot ROM */ -#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x4801 -#define EE_WRITE_1 0x4805 -#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ +#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ +#define EE_WRITE_0 0x4801 +#define EE_WRITE_1 0x4805 +#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define SROM_SR 0x00000800 /* Select Serial ROM when set */ #define DT_IN 0x00000004 /* Serial Data In */ @@ -79,13 +75,13 @@ #define RESET_DE4X5(dev) {\ int i;\ - i=INL(dev, DE4X5_BMR);\ + i = INL(dev, DE4X5_BMR);\ udelay(1000);\ OUTL(dev, i | BMR_SWR, DE4X5_BMR);\ udelay(1000);\ OUTL(dev, i, DE4X5_BMR);\ udelay(1000);\ - for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\ + for (i = 0; i < 5; i++) {INL(dev, DE4X5_BMR); udelay(10000); } \ udelay(1000);\ } @@ -99,7 +95,7 @@ #define STOP_DE4X5(dev) {\ s32 omr; \ omr = INL(dev, DE4X5_OMR);\ - omr &= ~(OMR_ST|OMR_SR);\ + omr &= ~(OMR_ST | OMR_SR);\ OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ \ } @@ -118,30 +114,34 @@ struct de4x5_desc { u32 next; }; -static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */ -static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */ -static int rx_new; /* RX descriptor ring pointer */ -static int tx_new; /* TX descriptor ring pointer */ - -static char rxRingSize; -static char txRingSize; - -static void sendto_srom(struct eth_device* dev, u_int command, u_long addr); -static int getfrom_srom(struct eth_device* dev, u_long addr); -static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len); -static int do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len); +/* 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 void sendto_srom(struct eth_device *dev, u_int command, u_long addr); +static int getfrom_srom(struct eth_device *dev, u_long addr); +static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, + int cmd, int cmd_len); +static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, + int location, int addr_len); #ifdef UPDATE_SROM -static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value); +static int write_srom(struct eth_device *dev, u_long ioaddr, + int index, int new_value); static void update_srom(struct eth_device *dev, bd_t *bis); #endif static int read_srom(struct eth_device *dev, u_long ioaddr, int index); -static void read_hw_addr(struct eth_device* dev, bd_t * bis); -static void send_setup_frame(struct eth_device* dev, bd_t * bis); +static void read_hw_addr(struct eth_device *dev, bd_t *bis); +static void send_setup_frame(struct eth_device *dev, bd_t *bis); -static int dc21x4x_init(struct eth_device* dev, bd_t* bis); +static int dc21x4x_init(struct eth_device *dev, bd_t *bis); static int dc21x4x_send(struct eth_device *dev, void *packet, int length); -static int dc21x4x_recv(struct eth_device* dev); -static void dc21x4x_halt(struct eth_device* dev); +static int dc21x4x_recv(struct eth_device *dev); +static void dc21x4x_halt(struct eth_device *dev); #if defined(CONFIG_E500) #define phys_to_bus(a) (a) @@ -149,12 +149,12 @@ static void dc21x4x_halt(struct eth_device* dev); #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) #endif -static int INL(struct eth_device* dev, u_long addr) +static int INL(struct eth_device *dev, u_long addr) { return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase)); } -static void OUTL(struct eth_device* dev, int command, u_long addr) +static void OUTL(struct eth_device *dev, int command, u_long addr) { *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command); } @@ -281,12 +281,12 @@ static int dc21x4x_init(struct eth_device *dev, bd_t *bis) tx_ring[i].next = 0; } - rxRingSize = NUM_RX_DESC; - txRingSize = NUM_TX_DESC; + rx_ring_size = NUM_RX_DESC; + tx_ring_size = NUM_TX_DESC; /* Write the end of list marker to the descriptor lists. */ - rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER); - tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER); + rx_ring[rx_ring_size - 1].des1 |= cpu_to_le32(RD_RER); + tx_ring[tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ OUTL(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); @@ -380,7 +380,7 @@ static int dc21x4x_recv(struct eth_device *dev) } /* Update entry information. */ - rx_new = (rx_new + 1) % rxRingSize; + rx_new = (rx_new + 1) % rx_ring_size; } return length; -- cgit v1.1 From 04da06120909729bc9d0d3974d06dc2ef758e821 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:36:46 +0200 Subject: net: dc2114x: Clean up DE4X5 macros Replace these macros with static functions to permit the compiler to do type checking on the functions. The INL()/OUTL() functions have to be moved in this patch as well, as those DE4X5 macros are using them. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 89 +++++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 007e4ce..a85fb76 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -73,30 +73,57 @@ #define POLL_DEMAND 1 -#define RESET_DE4X5(dev) {\ - int i;\ - i = INL(dev, DE4X5_BMR);\ - udelay(1000);\ - OUTL(dev, i | BMR_SWR, DE4X5_BMR);\ - udelay(1000);\ - OUTL(dev, i, DE4X5_BMR);\ - udelay(1000);\ - for (i = 0; i < 5; i++) {INL(dev, DE4X5_BMR); udelay(10000); } \ - udelay(1000);\ +#if defined(CONFIG_E500) +#define phys_to_bus(a) (a) +#else +#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) +#endif + +static int INL(struct eth_device *dev, u_long addr) +{ + return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase)); +} + +static void OUTL(struct eth_device *dev, int command, u_long addr) +{ + *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command); +} + +static void reset_de4x5(struct eth_device *dev) +{ + int i; + + i = INL(dev, DE4X5_BMR); + mdelay(1); + OUTL(dev, i | BMR_SWR, DE4X5_BMR); + mdelay(1); + OUTL(dev, i, DE4X5_BMR); + mdelay(1); + + for (i = 0; i < 5; i++) { + INL(dev, DE4X5_BMR); + mdelay(10); + } + + mdelay(1); } -#define START_DE4X5(dev) {\ - s32 omr; \ - omr = INL(dev, DE4X5_OMR);\ - omr |= OMR_ST | OMR_SR;\ - OUTL(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */\ +static void start_de4x5(struct eth_device *dev) +{ + s32 omr; + + omr = INL(dev, DE4X5_OMR); + omr |= OMR_ST | OMR_SR; + OUTL(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */ } -#define STOP_DE4X5(dev) {\ - s32 omr; \ - omr = INL(dev, DE4X5_OMR);\ - omr &= ~(OMR_ST | OMR_SR);\ - OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ \ +static void stop_de4x5(struct eth_device *dev) +{ + s32 omr; + + omr = INL(dev, DE4X5_OMR); + omr &= ~(OMR_ST | OMR_SR); + OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ } #define NUM_RX_DESC PKTBUFSRX @@ -143,22 +170,6 @@ static int dc21x4x_send(struct eth_device *dev, void *packet, int length); static int dc21x4x_recv(struct eth_device *dev); static void dc21x4x_halt(struct eth_device *dev); -#if defined(CONFIG_E500) -#define phys_to_bus(a) (a) -#else -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) -#endif - -static int INL(struct eth_device *dev, u_long addr) -{ - return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase)); -} - -static void OUTL(struct eth_device *dev, int command, u_long addr) -{ - *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command); -} - 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 }, @@ -257,7 +268,7 @@ static int dc21x4x_init(struct eth_device *dev, bd_t *bis) /* Ensure we're not sleeping. */ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - RESET_DE4X5(dev); + reset_de4x5(dev); if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) { printf("Error: Cannot reset ethernet controller.\n"); @@ -292,7 +303,7 @@ static int dc21x4x_init(struct eth_device *dev, bd_t *bis) OUTL(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); OUTL(dev, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); - START_DE4X5(dev); + start_de4x5(dev); tx_new = 0; rx_new = 0; @@ -390,7 +401,7 @@ static void dc21x4x_halt(struct eth_device *dev) { int devbusfn = (int)dev->priv; - STOP_DE4X5(dev); + stop_de4x5(dev); OUTL(dev, 0, DE4X5_SICR); pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); -- cgit v1.1 From 3b7b9e2e71e7334198d696a03f3552bbc812ce9b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 03:40:03 +0200 Subject: net: dc2114x: Clean up INL/OUTL functions Rename these functions to dc2114x_{inl,outl}(), use u32 values in them instead of plain signed integers as all those values are in fact register values and the driver code does bitwise operations on them. No functional change intended. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index a85fb76..2bbe4e5 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -79,29 +79,29 @@ #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) #endif -static int INL(struct eth_device *dev, u_long addr) +static u32 dc2114x_inl(struct eth_device *dev, u32 addr) { - return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase)); + return le32_to_cpu(*(volatile u32 *)(addr + dev->iobase)); } -static void OUTL(struct eth_device *dev, int command, u_long addr) +static void dc2114x_outl(struct eth_device *dev, u32 command, u32 addr) { - *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command); + *(volatile u32 *)(addr + dev->iobase) = cpu_to_le32(command); } static void reset_de4x5(struct eth_device *dev) { - int i; + u32 i; - i = INL(dev, DE4X5_BMR); + i = dc2114x_inl(dev, DE4X5_BMR); mdelay(1); - OUTL(dev, i | BMR_SWR, DE4X5_BMR); + dc2114x_outl(dev, i | BMR_SWR, DE4X5_BMR); mdelay(1); - OUTL(dev, i, DE4X5_BMR); + dc2114x_outl(dev, i, DE4X5_BMR); mdelay(1); for (i = 0; i < 5; i++) { - INL(dev, DE4X5_BMR); + dc2114x_inl(dev, DE4X5_BMR); mdelay(10); } @@ -110,20 +110,20 @@ static void reset_de4x5(struct eth_device *dev) static void start_de4x5(struct eth_device *dev) { - s32 omr; + u32 omr; - omr = INL(dev, DE4X5_OMR); + omr = dc2114x_inl(dev, DE4X5_OMR); omr |= OMR_ST | OMR_SR; - OUTL(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */ + dc2114x_outl(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */ } static void stop_de4x5(struct eth_device *dev) { - s32 omr; + u32 omr; - omr = INL(dev, DE4X5_OMR); + omr = dc2114x_inl(dev, DE4X5_OMR); omr &= ~(OMR_ST | OMR_SR); - OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ + dc2114x_outl(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ } #define NUM_RX_DESC PKTBUFSRX @@ -270,12 +270,12 @@ static int dc21x4x_init(struct eth_device *dev, bd_t *bis) reset_de4x5(dev); - if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) { + if (dc2114x_inl(dev, DE4X5_STS) & (STS_TS | STS_RS)) { printf("Error: Cannot reset ethernet controller.\n"); return -1; } - OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); + dc2114x_outl(dev, 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); @@ -300,8 +300,8 @@ static int dc21x4x_init(struct eth_device *dev, bd_t *bis) tx_ring[tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ - OUTL(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); - OUTL(dev, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); + dc2114x_outl(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA); + dc2114x_outl(dev, phys_to_bus((u32)&tx_ring), DE4X5_TRBA); start_de4x5(dev); @@ -335,7 +335,7 @@ 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); - OUTL(dev, POLL_DEMAND, DE4X5_TPD); + dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD); for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) @@ -402,7 +402,7 @@ static void dc21x4x_halt(struct eth_device *dev) int devbusfn = (int)dev->priv; stop_de4x5(dev); - OUTL(dev, 0, DE4X5_SICR); + dc2114x_outl(dev, 0, DE4X5_SICR); pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); } @@ -433,7 +433,7 @@ static void send_setup_frame(struct eth_device *dev, bd_t *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); - OUTL(dev, POLL_DEMAND, DE4X5_TPD); + dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD); for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { if (i < TOUT_LOOP) @@ -454,13 +454,13 @@ static void send_setup_frame(struct eth_device *dev, bd_t *bis) /* SROM Read and write routines. */ static void sendto_srom(struct eth_device *dev, u_int command, u_long addr) { - OUTL(dev, command, addr); + dc2114x_outl(dev, command, addr); udelay(1); } static int getfrom_srom(struct eth_device *dev, u_long addr) { - s32 tmp = INL(dev, addr); + u32 tmp = dc2114x_inl(dev, addr); udelay(1); return tmp; -- cgit v1.1 From dbe9c0c1457dad8446f1d9aac5f4cbd4ee6db060 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 04:00:49 +0200 Subject: net: dc2114x: Reorganize driver Move the functions in the driver around to better fit future DM conversion, drop function forward declarations. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 736 ++++++++++++++++++++++++-------------------------- 1 file changed, 357 insertions(+), 379 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 2bbe4e5..9de9634 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -79,6 +79,30 @@ #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) #endif +#define NUM_RX_DESC PKTBUFSRX +#define NUM_TX_DESC 1 /* Number of TX descriptors */ +#define RX_BUFF_SZ PKTSIZE_ALIGN + +#define TOUT_LOOP 1000000 + +#define SETUP_FRAME_LEN 192 + +struct de4x5_desc { + volatile s32 status; + u32 des1; + u32 buf; + u32 next; +}; + +/* 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 eth_device *dev, u32 addr) { return le32_to_cpu(*(volatile u32 *)(addr + dev->iobase)); @@ -126,191 +150,267 @@ static void stop_de4x5(struct eth_device *dev) dc2114x_outl(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ } -#define NUM_RX_DESC PKTBUFSRX -#define NUM_TX_DESC 1 /* Number of TX descriptors */ -#define RX_BUFF_SZ PKTSIZE_ALIGN - -#define TOUT_LOOP 1000000 +/* SROM Read and write routines. */ +static void sendto_srom(struct eth_device *dev, u_int command, u_long addr) +{ + dc2114x_outl(dev, command, addr); + udelay(1); +} -#define SETUP_FRAME_LEN 192 +static int getfrom_srom(struct eth_device *dev, u_long addr) +{ + u32 tmp = dc2114x_inl(dev, addr); -struct de4x5_desc { - volatile s32 status; - u32 des1; - u32 buf; - u32 next; -}; + udelay(1); + return tmp; +} -/* 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 */ +/* Note: this routine returns extra data bits for size detection. */ +static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, + int addr_len) +{ + int read_cmd = location | (SROM_READ_CMD << addr_len); + unsigned int retval = 0; + int i; -static char rx_ring_size; -static char tx_ring_size; + sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); -static void sendto_srom(struct eth_device *dev, u_int command, u_long addr); -static int getfrom_srom(struct eth_device *dev, u_long addr); -static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, - int cmd, int cmd_len); -static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, - int location, int addr_len); -#ifdef UPDATE_SROM -static int write_srom(struct eth_device *dev, u_long ioaddr, - int index, int new_value); -static void update_srom(struct eth_device *dev, bd_t *bis); +#ifdef DEBUG_SROM + printf(" EEPROM read at %d ", location); #endif -static int read_srom(struct eth_device *dev, u_long ioaddr, int index); -static void read_hw_addr(struct eth_device *dev, bd_t *bis); -static void send_setup_frame(struct eth_device *dev, bd_t *bis); -static int dc21x4x_init(struct eth_device *dev, bd_t *bis); -static int dc21x4x_send(struct eth_device *dev, void *packet, int length); -static int dc21x4x_recv(struct eth_device *dev); -static void dc21x4x_halt(struct eth_device *dev); + /* Shift the read command bits out. */ + for (i = 4 + addr_len; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; -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 }, - { } -}; + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, + ioaddr); + udelay(10); + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, + ioaddr); + udelay(10); +#ifdef DEBUG_SROM2 + printf("%X", getfrom_srom(dev, ioaddr) & 15); +#endif + retval = (retval << 1) | + !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); + } -int dc21x4x_initialize(bd_t *bis) -{ - struct eth_device *dev; - unsigned short status; - unsigned char timer; - unsigned int iobase; - int card_number = 0; - pci_dev_t devbusfn; - unsigned int cfrv; - int idx = 0; + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - while (1) { - devbusfn = pci_find_devices(supported, idx++); - if (devbusfn == -1) - break; +#ifdef DEBUG_SROM2 + printf(" :%X:", getfrom_srom(dev, ioaddr) & 15); +#endif - /* Get the chip configuration revision register. */ - pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); + for (i = 16; i > 0; i--) { + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); + udelay(10); +#ifdef DEBUG_SROM2 + printf("%X", getfrom_srom(dev, ioaddr) & 15); +#endif + retval = (retval << 1) | + !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); + udelay(10); + } - if ((cfrv & CFRV_RN) < DC2114x_BRK) { - printf("Error: The chip is not DC21143.\n"); - continue; - } + /* Terminate the EEPROM access. */ + sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(devbusfn, PCI_COMMAND, status); +#ifdef DEBUG_SROM2 + printf(" EEPROM value at %d is %5.5x.\n", location, retval); +#endif - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_MEMORY)) { - printf("Error: Can not enable MEMORY access.\n"); - continue; - } + return retval; +} - if (!(status & PCI_COMMAND_MASTER)) { - printf("Error: Can not enable Bus Mastering.\n"); - continue; - } +/* + * This executes a generic EEPROM command, typically a write or write + * 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, + int cmd_len) +{ + unsigned int retval = 0; - /* Check the latency timer for values >= 0x60. */ - pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer); +#ifdef DEBUG_SROM + printf(" EEPROM op 0x%x: ", cmd); +#endif - if (timer < 0x60) { - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, - 0x60); - } + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); - /* read BAR for memory space access */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase); - iobase &= PCI_BASE_ADDRESS_MEM_MASK; - debug("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); + /* Shift the command bits out. */ + do { + short dataval = (cmd & BIT(cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (!dev) { - printf("Can not allocalte memory of dc21x4x\n"); - break; - } + sendto_srom(dev, dataval, ioaddr); + udelay(10); - memset(dev, 0, sizeof(*dev)); +#ifdef DEBUG_SROM2 + printf("%X", getfrom_srom(dev, ioaddr) & 15); +#endif - sprintf(dev->name, "dc21x4x#%d", card_number); + sendto_srom(dev, dataval | DT_CLK, ioaddr); + udelay(10); + retval = (retval << 1) | + !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); + } while (--cmd_len >= 0); - dev->iobase = pci_mem_to_phys(devbusfn, iobase); - dev->priv = (void *)devbusfn; - dev->init = dc21x4x_init; - dev->halt = dc21x4x_halt; - dev->send = dc21x4x_send; - dev->recv = dc21x4x_recv; + sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - /* Ensure we're not sleeping. */ - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); + /* Terminate the EEPROM access. */ + sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - udelay(10 * 1000); +#ifdef DEBUG_SROM + printf(" EEPROM result is 0x%5.5x.\n", retval); +#endif - read_hw_addr(dev, bis); + return retval; +} - eth_register(dev); +static int read_srom(struct eth_device *dev, u_long ioaddr, int index) +{ + int ee_addr_size; - card_number++; - } + ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; - return card_number; + return do_eeprom_cmd(dev, ioaddr, 0xffff | + (((SROM_READ_CMD << ee_addr_size) | index) << 16), + 3 + ee_addr_size + 16); } -static int dc21x4x_init(struct eth_device *dev, bd_t *bis) +#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; - int devbusfn = (int)dev->priv; - /* Ensure we're not sleeping. */ - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); + ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; - reset_de4x5(dev); + udelay(10 * 1000); /* test-only */ - if (dc2114x_inl(dev, DE4X5_STS) & (STS_TS | STS_RS)) { - printf("Error: Cannot reset ethernet controller.\n"); - return -1; - } +#ifdef DEBUG_SROM + printf("ee_addr_size=%d.\n", ee_addr_size); + printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index); +#endif - dc2114x_outl(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); + /* Enable programming modes. */ + do_eeprom_cmd(dev, ioaddr, 0x4f << (ee_addr_size - 4), + 3 + ee_addr_size); - 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].next = 0; + /* 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; } - 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; +#ifdef DEBUG_SROM + printf(" Write finished after %d ticks.\n", i); +#endif + + /* 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); +#ifdef DEBUG_SROM + printf(" New value at offset %d is %4.4x.\n", index, newval); +#endif + + return 1; +} + +static void update_srom(struct eth_device *dev, bd_t *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, bd_t *bis) +{ + char setup_frame[SETUP_FRAME_LEN]; + char *pa = &setup_frame[0]; + int i; + + memset(pa, 0xff, SETUP_FRAME_LEN); + + for (i = 0; i < ETH_ALEN; i++) { + *(pa + (i & 1)) = dev->enetaddr[i]; + if (i & 0x01) + pa += 4; } - rx_ring_size = NUM_RX_DESC; - tx_ring_size = NUM_TX_DESC; + for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + if (i < TOUT_LOOP) + continue; - /* 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); + printf("%s: tx error buffer not ready\n", dev->name); + return; + } - /* 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); + tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((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); - start_de4x5(dev); + dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD); - tx_new = 0; - rx_new = 0; + for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + if (i < TOUT_LOOP) + continue; - send_setup_frame(dev, bis); + printf("%s: tx buffer not ready\n", dev->name); + return; + } - return 0; + if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { + printf("TX error status2 = 0x%08X\n", + le32_to_cpu(tx_ring[tx_new].status)); + } + + tx_new = (tx_new + 1) % NUM_TX_DESC; } static int dc21x4x_send(struct eth_device *dev, void *packet, int length) @@ -397,297 +497,175 @@ static int dc21x4x_recv(struct eth_device *dev) return length; } -static void dc21x4x_halt(struct eth_device *dev) +static int dc21x4x_init(struct eth_device *dev, bd_t *bis) { + int i; int devbusfn = (int)dev->priv; - stop_de4x5(dev); - dc2114x_outl(dev, 0, DE4X5_SICR); + /* Ensure we're not sleeping. */ + pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); -} + reset_de4x5(dev); -static void send_setup_frame(struct eth_device *dev, bd_t *bis) -{ - char setup_frame[SETUP_FRAME_LEN]; - char *pa = &setup_frame[0]; - int i; + if (dc2114x_inl(dev, DE4X5_STS) & (STS_TS | STS_RS)) { + printf("Error: Cannot reset ethernet controller.\n"); + return -1; + } - memset(pa, 0xff, SETUP_FRAME_LEN); + dc2114x_outl(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); - for (i = 0; i < ETH_ALEN; i++) { - *(pa + (i & 1)) = dev->enetaddr[i]; - if (i & 0x01) - pa += 4; + 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].next = 0; } - for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i < TOUT_LOOP) - continue; - - printf("%s: tx error buffer not ready\n", dev->name); - return; + 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; } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((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); + rx_ring_size = NUM_RX_DESC; + tx_ring_size = NUM_TX_DESC; - dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD); + /* 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); - for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i < TOUT_LOOP) - continue; + /* 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); - printf("%s: tx buffer not ready\n", dev->name); - return; - } + start_de4x5(dev); - if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { - printf("TX error status2 = 0x%08X\n", - le32_to_cpu(tx_ring[tx_new].status)); - } + tx_new = 0; + rx_new = 0; - tx_new = (tx_new + 1) % NUM_TX_DESC; -} + send_setup_frame(dev, bis); -/* SROM Read and write routines. */ -static void sendto_srom(struct eth_device *dev, u_int command, u_long addr) -{ - dc2114x_outl(dev, command, addr); - udelay(1); + return 0; } -static int getfrom_srom(struct eth_device *dev, u_long addr) +static void dc21x4x_halt(struct eth_device *dev) { - u32 tmp = dc2114x_inl(dev, addr); + int devbusfn = (int)dev->priv; - udelay(1); - return tmp; + stop_de4x5(dev); + dc2114x_outl(dev, 0, DE4X5_SICR); + + pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); } -/* Note: this routine returns extra data bits for size detection. */ -static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, - int addr_len) +static void read_hw_addr(struct eth_device *dev, bd_t *bis) { - 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); - -#ifdef DEBUG_SROM - printf(" EEPROM read at %d ", location); -#endif - - /* Shift the read command bits out. */ - for (i = 4 + addr_len; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); + int i, j = 0; - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, - ioaddr); - udelay(10); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, - ioaddr); - udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif - retval = (retval << 1) | - !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); + for (i = 0; i < (ETH_ALEN >> 1); i++) { + tmp = read_srom(dev, DE4X5_APROM, (SROM_HWADD >> 1) + i); + *p = le16_to_cpu(tmp); + j += *p++; } - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - -#ifdef DEBUG_SROM2 - printf(" :%X:", getfrom_srom(dev, ioaddr) & 15); -#endif - - for (i = 16; i > 0; i--) { - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); - udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); + 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 - retval = (retval << 1) | - !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - udelay(10); } - - /* Terminate the EEPROM access. */ - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - -#ifdef DEBUG_SROM2 - printf(" EEPROM value at %d is %5.5x.\n", location, retval); -#endif - - return retval; } -/* - * This executes a generic EEPROM command, typically a write or write - * 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, - int cmd_len) -{ - unsigned int retval = 0; - -#ifdef DEBUG_SROM - printf(" EEPROM op 0x%x: ", cmd); -#endif - - sendto_srom(dev, 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); - udelay(10); - -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif - - sendto_srom(dev, dataval | DT_CLK, ioaddr); - udelay(10); - retval = (retval << 1) | - !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); - } while (--cmd_len >= 0); - - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - - /* Terminate the EEPROM access. */ - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - -#ifdef DEBUG_SROM - printf(" EEPROM result is 0x%5.5x.\n", retval); -#endif - - return retval; -} +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 }, + { } +}; -static int read_srom(struct eth_device *dev, u_long ioaddr, int index) +int dc21x4x_initialize(bd_t *bis) { - int ee_addr_size; - - ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; + struct eth_device *dev; + unsigned short status; + unsigned char timer; + unsigned int iobase; + int card_number = 0; + pci_dev_t devbusfn; + unsigned int cfrv; + int idx = 0; - return do_eeprom_cmd(dev, ioaddr, 0xffff | - (((SROM_READ_CMD << ee_addr_size) | index) << 16), - 3 + ee_addr_size + 16); -} + while (1) { + devbusfn = pci_find_devices(supported, idx++); + if (devbusfn == -1) + break; -#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; + /* Get the chip configuration revision register. */ + pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); - ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6; + if ((cfrv & CFRV_RN) < DC2114x_BRK) { + printf("Error: The chip is not DC21143.\n"); + continue; + } - udelay(10 * 1000); /* test-only */ + pci_read_config_word(devbusfn, PCI_COMMAND, &status); + status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config_word(devbusfn, PCI_COMMAND, status); -#ifdef DEBUG_SROM - printf("ee_addr_size=%d.\n", ee_addr_size); - printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index); -#endif + pci_read_config_word(devbusfn, PCI_COMMAND, &status); + if (!(status & PCI_COMMAND_MEMORY)) { + printf("Error: Can not enable MEMORY access.\n"); + continue; + } - /* Enable programming modes. */ - do_eeprom_cmd(dev, ioaddr, 0x4f << (ee_addr_size - 4), - 3 + ee_addr_size); + if (!(status & PCI_COMMAND_MASTER)) { + printf("Error: Can not enable Bus Mastering.\n"); + continue; + } - /* Do the actual write. */ - do_eeprom_cmd(dev, ioaddr, new_value | - (((SROM_WRITE_CMD << ee_addr_size) | index) << 16), - 3 + ee_addr_size + 16); + /* Check the latency timer for values >= 0x60. */ + pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer); - /* 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; - } + if (timer < 0x60) { + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, + 0x60); + } -#ifdef DEBUG_SROM - printf(" Write finished after %d ticks.\n", i); -#endif + /* read BAR for memory space access */ + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase); + iobase &= PCI_BASE_ADDRESS_MEM_MASK; + debug("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); - /* Disable programming. */ - do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size - 4)), - 3 + ee_addr_size); + dev = (struct eth_device *)malloc(sizeof(*dev)); + if (!dev) { + printf("Can not allocalte memory of dc21x4x\n"); + break; + } - /* And read the result. */ - newval = do_eeprom_cmd(dev, ioaddr, - (((SROM_READ_CMD << ee_addr_size) | index) << 16) - | 0xffff, 3 + ee_addr_size + 16); -#ifdef DEBUG_SROM - printf(" New value at offset %d is %4.4x.\n", index, newval); -#endif + memset(dev, 0, sizeof(*dev)); - return 1; -} -#endif + sprintf(dev->name, "dc21x4x#%d", card_number); -static void read_hw_addr(struct eth_device *dev, bd_t *bis) -{ - u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); - int i, j = 0; + dev->iobase = pci_mem_to_phys(devbusfn, iobase); + dev->priv = (void *)devbusfn; + dev->init = dc21x4x_init; + dev->halt = dc21x4x_halt; + dev->send = dc21x4x_send; + dev->recv = dc21x4x_recv; - for (i = 0; i < (ETH_ALEN >> 1); i++) { - tmp = read_srom(dev, DE4X5_APROM, (SROM_HWADD >> 1) + i); - *p = le16_to_cpu(tmp); - j += *p++; - } + /* Ensure we're not sleeping. */ + pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - 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 - } -} + udelay(10 * 1000); -#ifdef UPDATE_SROM -static void update_srom(struct eth_device *dev, bd_t *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; + read_hw_addr(dev, bis); - /* Ethernet Addr... */ - if (!eth_env_get_enetaddr("ethaddr", enetaddr)) - return; + eth_register(dev); - eeprom[0x0a] = (enetaddr[1] << 8) | enetaddr[0]; - eeprom[0x0b] = (enetaddr[3] << 8) | enetaddr[2]; - eeprom[0x0c] = (enetaddr[5] << 8) | enetaddr[4]; + card_number++; + } - for (i = 0; i < 0x40; i++) - write_srom(dev, DE4X5_APROM, i, eeprom[i]); + return card_number; } -#endif /* UPDATE_SROM */ -- cgit v1.1 From c2abfca9be3a62a98c1a1b77a11cd01092c0160f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 Apr 2020 04:05:44 +0200 Subject: net: dc2114x: Switch DEBUG_SROM{,2} to debug_cond() Replace the adhoc debugging ifdeffery with debug_cond() and an internal SROM_DEBUG macro to select the debug level. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/dc2114x.c | 57 +++++++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 9de9634..d008696 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -7,8 +7,7 @@ #include #include -#undef DEBUG_SROM -#undef DEBUG_SROM2 +#define SROM_DLEVEL 0 #undef UPDATE_SROM @@ -176,9 +175,7 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); -#ifdef DEBUG_SROM - printf(" EEPROM read at %d ", location); -#endif + debug_cond(SROM_DLEVEL >= 1, " EEPROM read at %d ", location); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { @@ -190,25 +187,21 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr); udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif + debug_cond(SROM_DLEVEL >= 2, "%X", + getfrom_srom(dev, ioaddr) & 15); retval = (retval << 1) | !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); } sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); -#ifdef DEBUG_SROM2 - printf(" :%X:", getfrom_srom(dev, ioaddr) & 15); -#endif + debug_cond(SROM_DLEVEL >= 2, " :%X:", getfrom_srom(dev, ioaddr) & 15); for (i = 16; i > 0; i--) { sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif + debug_cond(SROM_DLEVEL >= 2, "%X", + getfrom_srom(dev, ioaddr) & 15); retval = (retval << 1) | !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ); sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); @@ -218,9 +211,8 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, /* Terminate the EEPROM access. */ sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); -#ifdef DEBUG_SROM2 - printf(" EEPROM value at %d is %5.5x.\n", location, retval); -#endif + debug_cond(SROM_DLEVEL >= 2, " EEPROM value at %d is %5.5x.\n", + location, retval); return retval; } @@ -235,9 +227,7 @@ static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, { unsigned int retval = 0; -#ifdef DEBUG_SROM - printf(" EEPROM op 0x%x: ", cmd); -#endif + debug_cond(SROM_DLEVEL >= 1, " EEPROM op 0x%x: ", cmd); sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); @@ -248,9 +238,8 @@ static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, sendto_srom(dev, dataval, ioaddr); udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif + debug_cond(SROM_DLEVEL >= 2, "%X", + getfrom_srom(dev, ioaddr) & 15); sendto_srom(dev, dataval | DT_CLK, ioaddr); udelay(10); @@ -263,9 +252,7 @@ static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, /* Terminate the EEPROM access. */ sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); -#ifdef DEBUG_SROM - printf(" EEPROM result is 0x%5.5x.\n", retval); -#endif + debug_cond(SROM_DLEVEL >= 1, " EEPROM result is 0x%5.5x.\n", retval); return retval; } @@ -293,10 +280,10 @@ static int write_srom(struct eth_device *dev, u_long ioaddr, int index, udelay(10 * 1000); /* test-only */ -#ifdef DEBUG_SROM - printf("ee_addr_size=%d.\n", ee_addr_size); - printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index); -#endif + 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), @@ -314,9 +301,7 @@ static int write_srom(struct eth_device *dev, u_long ioaddr, int index, break; } -#ifdef DEBUG_SROM - printf(" Write finished after %d ticks.\n", i); -#endif + debug_cond(SROM_DLEVEL >= 1, " Write finished after %d ticks.\n", i); /* Disable programming. */ do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size - 4)), @@ -326,9 +311,9 @@ static int write_srom(struct eth_device *dev, u_long ioaddr, int index, newval = do_eeprom_cmd(dev, ioaddr, (((SROM_READ_CMD << ee_addr_size) | index) << 16) | 0xffff, 3 + ee_addr_size + 16); -#ifdef DEBUG_SROM - printf(" New value at offset %d is %4.4x.\n", index, newval); -#endif + + debug_cond(SROM_DLEVEL >= 1, " New value at offset %d is %4.4x.\n", + index, newval); return 1; } -- cgit v1.1 From 4332d8061785b697ae7bdf3945adb55ba4da696b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Mar 2020 02:02:57 +0100 Subject: net: dwc_eth_qos: Fully rewrite RX descriptor field 3 The RX descriptor field 3 should contain only OWN and BUF1V bits before being used for receiving data by the DMA engine. However, right now, if the descriptor was already used for receiving data and is being cleared, the field 3 is only modified and the aforementioned two bits are ORRed into the field. This could lead to a residual dirty bits being left in the field 3 from previous transfer, and it generally does. Fully set the field 3 instead to clear those residual dirty bits. Reviewed-by: Patrick Delaunay Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren --- drivers/net/dwc_eth_qos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 63f2086..4f24520 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1288,7 +1288,7 @@ static int eqos_start(struct udevice *dev) struct eqos_desc *rx_desc = &(eqos->rx_descs[i]); rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf + (i * EQOS_MAX_PACKET_SIZE)); - rx_desc->des3 |= EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; + rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; } eqos->config->ops->eqos_flush_desc(eqos->descs); @@ -1482,7 +1482,7 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) * writes to the rest of the descriptor too. */ mb(); - rx_desc->des3 |= EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; + rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; eqos->config->ops->eqos_flush_desc(rx_desc); writel((ulong)rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer); -- cgit v1.1 From 83858d87954627af7a576ccc7c93034b055faa7b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Mar 2020 02:03:50 +0100 Subject: net: dwc_eth_qos: Correctly wrap around TX descriptor tail pointer This code programs the next descriptor in the TX descriptor ring into the hardware as the last valid TX descriptor. The problem is that if the currenty descriptor is the last one in the array, the code will not wrap around correctly and use TX descriptor 0 again, but instead will use TX descriptor at address right past the TX descriptor ring, which is the first descriptor in the RX ring. Fix this by adding the necessary wrap-around. Reviewed-by: Patrick Delaunay Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren --- drivers/net/dwc_eth_qos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 4f24520..e2fb690 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1419,7 +1419,8 @@ 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)(tx_desc + 1), &eqos->dma_regs->ch0_txdesc_tail_pointer); + writel((ulong)(&(eqos->tx_descs[eqos->tx_desc_idx])), + &eqos->dma_regs->ch0_txdesc_tail_pointer); for (i = 0; i < 1000000; i++) { eqos->config->ops->eqos_inval_desc(tx_desc); -- cgit v1.1 From dd90c2e1ea0a7abdfa501e604523c23d6f77ffdd Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Mar 2020 02:09:01 +0100 Subject: net: dwc_eth_qos: Flush the RX descriptors on init Currently the code only flushes the first RX descriptor, not every entry in the RX descriptor ring. Fix this, to make sure the DMA engine can pick the RX descriptors correctly. Reviewed-by: Patrick Delaunay Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren --- drivers/net/dwc_eth_qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e2fb690..e33f304 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1289,8 +1289,8 @@ static int eqos_start(struct udevice *dev) rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf + (i * EQOS_MAX_PACKET_SIZE)); rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; + eqos->config->ops->eqos_flush_desc(rx_desc); } - eqos->config->ops->eqos_flush_desc(eqos->descs); writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress); writel((ulong)eqos->tx_descs, &eqos->dma_regs->ch0_txdesc_list_address); -- cgit v1.1 From 738ee270fe17ea9e48fee8823eb356ed03656e7c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Mar 2020 02:09:21 +0100 Subject: net: dwc_eth_qos: Invalidate RX descriptor before reading The current code polls the RX desciptor ring for new packets by reading the RX descriptor status. This works by accident, as the RX descriptors are often in non-cacheable memory. However, the driver does support use of RX descriptors in cacheable memory. This patch adds a missing RX descriptor invalidation, which assures the CPU will read a fresh copy of the RX descriptor instead of a cached one. Reviewed-by: Patrick Delaunay Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren --- drivers/net/dwc_eth_qos.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e33f304..2b37cc3 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1443,6 +1443,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]); + eqos->config->ops->eqos_inval_desc(rx_desc); if (rx_desc->des3 & EQOS_DESC3_OWN) { debug("%s: RX packet not available\n", __func__); return -EAGAIN; -- cgit v1.1 From a83ca0c280dd41dda576d6a8f15a8534a84b782c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Mar 2020 02:09:55 +0100 Subject: net: dwc_eth_qos: Invalidate RX packet DMA buffer This patch prevents an issue where the RX packet might have been accessed by the CPU, which now has cached data from the packet in the caches and possibly various write buffers, and these data may be evicted from the caches into the DRAM while the buffer is also written by the DMA. By invalidating the buffer after the CPU accessed it and before the DMA populates the buffer, it is assured that the buffer will not be corrupted. Reviewed-by: Patrick Delaunay Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren --- drivers/net/dwc_eth_qos.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 2b37cc3..a195fe5 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1476,6 +1476,9 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) } rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); + + eqos->config->ops->eqos_inval_buffer(packet, length); + rx_desc->des0 = (u32)(ulong)packet; rx_desc->des1 = 0; rx_desc->des2 = 0; @@ -1538,6 +1541,9 @@ static int eqos_probe_resources_core(struct udevice *dev) } debug("%s: rx_pkt=%p\n", __func__, eqos->rx_pkt); + eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf, + EQOS_MAX_PACKET_SIZE * EQOS_DESCRIPTORS_RX); + debug("%s: OK\n", __func__); return 0; -- cgit v1.1 From 24891dd8d40d71c034023d2a037c97df1714393b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Mar 2020 02:11:46 +0100 Subject: net: dwc_eth_qos: Prevent DMA from writing updated RX DMA descriptor The DMA may attempt to write a DMA descriptor in the ring while it is being updated. By writing the DMA descriptor buffer address to 0, it is assured the DMA will not use such a buffer and the buffer can be updated without any interference. Reviewed-by: Patrick Delaunay Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Patrice Chotard Cc: Patrick Delaunay Cc: Ramon Fried Cc: Stephen Warren --- drivers/net/dwc_eth_qos.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index a195fe5..60dfd17 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1477,8 +1477,10 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); + rx_desc->des0 = 0; + mb(); + eqos->config->ops->eqos_flush_desc(rx_desc); eqos->config->ops->eqos_inval_buffer(packet, length); - rx_desc->des0 = (u32)(ulong)packet; rx_desc->des1 = 0; rx_desc->des2 = 0; -- cgit v1.1 From a5e66e515b0e6615d6e6fed91e20361d9a476831 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 20:47:26 +0200 Subject: net: rtl8139: Register macro cleanup Clean up the horrible register definitions in the RTL8139 driver. This does create a couple of checkpatch errors, but the driver is full of them anyway, and those will be cleaned up later. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 263 +++++++++++++++++++++++++++++--------------------- 1 file changed, 152 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index bb59629..9898f20 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -99,77 +99,96 @@ #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) /* Symbolic offsets to registers. */ -enum RTL8139_registers { - MAC0=0, /* Ethernet hardware address. */ - MAR0=8, /* Multicast filter. */ - TxStatus0=0x10, /* Transmit status (four 32bit registers). */ - TxAddr0=0x20, /* Tx descriptors (also four 32bit). */ - RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36, - ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A, - IntrMask=0x3C, IntrStatus=0x3E, - TxConfig=0x40, RxConfig=0x44, - Timer=0x48, /* general-purpose counter. */ - RxMissed=0x4C, /* 24 bits valid, write clears. */ - Cfg9346=0x50, Config0=0x51, Config1=0x52, - TimerIntrReg=0x54, /* intr if gp counter reaches this value */ - MediaStatus=0x58, - Config3=0x59, - MultiIntr=0x5C, - RevisionID=0x5E, /* revision of the RTL8139 chip */ - TxSummary=0x60, - MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68, - NWayExpansion=0x6A, - DisconnectCnt=0x6C, FalseCarrierCnt=0x6E, - NWayTestReg=0x70, - RxCnt=0x72, /* packet received counter */ - CSCR=0x74, /* chip status and configuration register */ - PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80, /* undocumented */ - /* from 0x84 onwards are a number of power management/wakeup frame - * definitions we will probably never need to know about. */ -}; - -enum ChipCmdBits { - CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, }; - -/* Interrupt register bits, using my own meaningful names. */ -enum IntrStatusBits { - PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000, - RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10, - TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01, -}; -enum TxStatusBits { - TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000, - TxOutOfWindow=0x20000000, TxAborted=0x40000000, - TxCarrierLost=0x80000000, -}; -enum RxStatusBits { - RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000, - RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004, - RxBadAlign=0x0002, RxStatusOK=0x0001, -}; - -enum MediaStatusBits { - MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08, - MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01, -}; - -enum MIIBMCRBits { - BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000, - BMCRRestartNWay=0x0200, BMCRDuplex=0x0100, -}; - -enum CSCRBits { - CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800, - CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0, - CSCR_LinkDownCmd=0x0f3c0, -}; +/* Ethernet hardware address. */ +#define RTL_REG_MAC0 0x00 +/* Multicast filter. */ +#define RTL_REG_MAR0 0x08 +/* Transmit status (four 32bit registers). */ +#define RTL_REG_TXSTATUS0 0x10 +/* Tx descriptors (also four 32bit). */ +#define RTL_REG_TXADDR0 0x20 +#define RTL_REG_RXBUF 0x30 +#define RTL_REG_RXEARLYCNT 0x34 +#define RTL_REG_RXEARLYSTATUS 0x36 +#define RTL_REG_CHIPCMD 0x37 +#define RTL_REG_CHIPCMD_CMDRESET BIT(4) +#define RTL_REG_CHIPCMD_CMDRXENB BIT(3) +#define RTL_REG_CHIPCMD_CMDTXENB BIT(2) +#define RTL_REG_CHIPCMD_RXBUFEMPTY BIT(0) +#define RTL_REG_RXBUFPTR 0x38 +#define RTL_REG_RXBUFADDR 0x3A +#define RTL_REG_INTRMASK 0x3C +#define RTL_REG_INTRSTATUS 0x3E +#define RTL_REG_INTRSTATUS_PCIERR BIT(15) +#define RTL_REG_INTRSTATUS_PCSTIMEOUT BIT(14) +#define RTL_REG_INTRSTATUS_CABLELENCHANGE BIT(13) +#define RTL_REG_INTRSTATUS_RXFIFOOVER BIT(6) +#define RTL_REG_INTRSTATUS_RXUNDERRUN BIT(5) +#define RTL_REG_INTRSTATUS_RXOVERFLOW BIT(4) +#define RTL_REG_INTRSTATUS_TXERR BIT(3) +#define RTL_REG_INTRSTATUS_TXOK BIT(2) +#define RTL_REG_INTRSTATUS_RXERR BIT(1) +#define RTL_REG_INTRSTATUS_RXOK BIT(0) +#define RTL_REG_TXCONFIG 0x40 +#define RTL_REG_RXCONFIG 0x44 +#define RTL_REG_RXCONFIG_RXCFGWRAP BIT(7) +#define RTL_REG_RXCONFIG_ACCEPTERR BIT(5) +#define RTL_REG_RXCONFIG_ACCEPTRUNT BIT(4) +#define RTL_REG_RXCONFIG_ACCEPTBROADCAST BIT(3) +#define RTL_REG_RXCONFIG_ACCEPTMULTICAST BIT(2) +#define RTL_REG_RXCONFIG_ACCEPTMYPHYS BIT(1) +#define RTL_REG_RXCONFIG_ACCEPTALLPHYS BIT(0) +/* general-purpose counter. */ +#define RTL_REG_TIMER 0x48 +/* 24 bits valid, write clears. */ +#define RTL_REG_RXMISSED 0x4C +#define RTL_REG_CFG9346 0x50 +#define RTL_REG_CONFIG0 0x51 +#define RTL_REG_CONFIG1 0x52 +/* intr if gp counter reaches this value */ +#define RTL_REG_TIMERINTRREG 0x54 +#define RTL_REG_MEDIASTATUS 0x58 +#define RTL_REG_MEDIASTATUS_MSRTXFLOWENABLE BIT(7) +#define RTL_REG_MEDIASTATUS_MSRRXFLOWENABLE BIT(6) +#define RTL_REG_MEDIASTATUS_MSRSPEED10 BIT(3) +#define RTL_REG_MEDIASTATUS_MSRLINKFAIL BIT(2) +#define RTL_REG_MEDIASTATUS_MSRRXPAUSEFLAG BIT(1) +#define RTL_REG_MEDIASTATUS_MSRTXPAUSEFLAG BIT(0) +#define RTL_REG_CONFIG3 0x59 +#define RTL_REG_MULTIINTR 0x5C +/* revision of the RTL8139 chip */ +#define RTL_REG_REVISIONID 0x5E +#define RTL_REG_TXSUMMARY 0x60 +#define RTL_REG_MII_BMCR 0x62 +#define RTL_REG_MII_BMSR 0x64 +#define RTL_REG_NWAYADVERT 0x66 +#define RTL_REG_NWAYLPAR 0x68 +#define RTL_REG_NWAYEXPANSION 0x6A +#define RTL_REG_DISCONNECTCNT 0x6C +#define RTL_REG_FALSECARRIERCNT 0x6E +#define RTL_REG_NWAYTESTREG 0x70 +/* packet received counter */ +#define RTL_REG_RXCNT 0x72 +/* chip status and configuration register */ +#define RTL_REG_CSCR 0x74 +#define RTL_REG_PHYPARM1 0x78 +#define RTL_REG_TWISTERPARM 0x7c +/* undocumented */ +#define RTL_REG_PHYPARM2 0x80 +/* + * from 0x84 onwards are a number of power management/wakeup frame + * definitions we will probably never need to know about. + */ -/* Bits in RxConfig. */ -enum rx_mode_bits { - RxCfgWrap=0x80, - AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08, - AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01, -}; +#define RTL_STS_RXMULTICAST BIT(15) +#define RTL_STS_RXPHYSICAL BIT(14) +#define RTL_STS_RXBROADCAST BIT(13) +#define RTL_STS_RXBADSYMBOL BIT(5) +#define RTL_STS_RXRUNT BIT(4) +#define RTL_STS_RXTOOLONG BIT(3) +#define RTL_STS_RXCRCERR BIT(2) +#define RTL_STS_RXBADALIGN BIT(1) +#define RTL_STS_RXSTATUSOK BIT(0) static int ioaddr; static unsigned int cur_rx,cur_tx; @@ -251,7 +270,7 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis) ioaddr = dev->iobase; /* Bring the chip out of low-power mode. */ - outb(0x00, ioaddr + Config1); + outb(0x00, ioaddr + RTL_REG_CONFIG1); addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) @@ -259,7 +278,7 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis) rtl_reset(dev); - if (inb(ioaddr + MediaStatus) & MSRLinkFail) { + if (inb(ioaddr + RTL_REG_MEDIASTATUS) & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { printf("Cable not connected or other link failure\n"); return -1 ; } @@ -286,15 +305,15 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis) #define eeprom_delay() inl(ee_addr) /* The EEPROM commands include the alway-set leading bit. */ -#define EE_WRITE_CMD (5) -#define EE_READ_CMD (6) -#define EE_ERASE_CMD (7) +#define EE_WRITE_CMD 5 +#define EE_READ_CMD 6 +#define EE_ERASE_CMD 7 static int read_eeprom(int location, int addr_len) { int i; unsigned int retval = 0; - long ee_addr = ioaddr + Cfg9346; + long ee_addr = ioaddr + RTL_REG_CFG9346; int read_cmd = location | (EE_READ_CMD << addr_len); outb(EE_ENB & ~EE_CS, ee_addr); @@ -335,41 +354,46 @@ static void set_rx_mode(struct eth_device *dev) { unsigned int mc_filter[2]; int rx_mode; /* !IFF_PROMISC */ - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode = RTL_REG_RXCONFIG_ACCEPTBROADCAST | + RTL_REG_RXCONFIG_ACCEPTMULTICAST | + RTL_REG_RXCONFIG_ACCEPTMYPHYS; mc_filter[1] = mc_filter[0] = 0xffffffff; - outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig); + outl(rtl8139_rx_config | rx_mode, ioaddr + RTL_REG_RXCONFIG); - outl(mc_filter[0], ioaddr + MAR0 + 0); - outl(mc_filter[1], ioaddr + MAR0 + 4); + outl(mc_filter[0], ioaddr + RTL_REG_MAR0 + 0); + outl(mc_filter[1], ioaddr + RTL_REG_MAR0 + 4); } static void rtl_reset(struct eth_device *dev) { int i; - outb(CmdReset, ioaddr + ChipCmd); + outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); cur_rx = 0; cur_tx = 0; /* Give the chip 10ms to finish the reset. */ for (i=0; i<100; ++i){ - if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break; + if ((inb(ioaddr + RTL_REG_CHIPCMD) & + RTL_REG_CHIPCMD_CMDRESET) == 0) + break; udelay (100); /* wait 100us */ } for (i = 0; i < ETH_ALEN; i++) - outb(dev->enetaddr[i], ioaddr + MAC0 + i); + outb(dev->enetaddr[i], ioaddr + RTL_REG_MAC0 + i); /* Must enable Tx/Rx before setting transfer thresholds! */ - outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); + outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, + ioaddr + RTL_REG_CHIPCMD); outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8), - ioaddr + RxConfig); /* accept no frames yet! */ - outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig); + ioaddr + RTL_REG_RXCONFIG); /* accept no frames yet! */ + outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + RTL_REG_TXCONFIG); - /* The Linux driver changes Config1 here to use a different LED pattern + /* The Linux driver changes RTL_REG_CONFIG1 here to use a different LED pattern * for half duplex or full/autodetect duplex (for full/autodetect, the * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses * TX/RX, Link100, Link10). This is messy, because it doesn't match @@ -380,24 +404,25 @@ static void rtl_reset(struct eth_device *dev) debug_cond(DEBUG_RX, "rx ring address is %lX\n",(unsigned long)rx_ring); flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf); + outl(phys_to_bus((int)rx_ring), ioaddr + RTL_REG_RXBUF); - /* If we add multicast support, the MAR0 register would have to be + /* If we add multicast support, the RTL_REG_MAR0 register would have to be * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */ - outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); + outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, + ioaddr + RTL_REG_CHIPCMD); - outl(rtl8139_rx_config, ioaddr + RxConfig); + outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG); /* Start the chip's Tx and Rx process. */ - outl(0, ioaddr + RxMissed); + outl(0, ioaddr + RTL_REG_RXMISSED); /* set_rx_mode */ set_rx_mode(dev); /* Disable all known interrupts by setting the interrupt mask. */ - outw(0, ioaddr + IntrMask); + outw(0, ioaddr + RTL_REG_INTRMASK); } static int rtl_transmit(struct eth_device *dev, void *packet, int length) @@ -420,23 +445,32 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length) } flush_cache((unsigned long)tx_buffer, length); - outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4); + outl(phys_to_bus((int)tx_buffer), ioaddr + RTL_REG_TXADDR0 + cur_tx*4); outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len, - ioaddr + TxStatus0 + cur_tx*4); + ioaddr + RTL_REG_TXSTATUS0 + cur_tx*4); do { - status = inw(ioaddr + IntrStatus); - /* Only acknlowledge interrupt sources we can properly handle - * here - the RxOverflow/RxFIFOOver MUST be handled in the - * rtl_poll() function. */ - outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus); - if ((status & (TxOK | TxErr | PCIErr)) != 0) break; + status = inw(ioaddr + RTL_REG_INTRSTATUS); + /* + * Only acknlowledge interrupt sources we can properly + * handle here - the RTL_REG_INTRSTATUS_RXOVERFLOW/ + * RTL_REG_INTRSTATUS_RXFIFOOVER MUST be handled in the + * rtl_poll() function. + */ + outw(status & (RTL_REG_INTRSTATUS_TXOK | + RTL_REG_INTRSTATUS_TXERR | + RTL_REG_INTRSTATUS_PCIERR), + ioaddr + RTL_REG_INTRSTATUS); + if ((status & (RTL_REG_INTRSTATUS_TXOK | + RTL_REG_INTRSTATUS_TXERR | + RTL_REG_INTRSTATUS_PCIERR)) != 0) + break; udelay(10); } while (i++ < RTL_TIMEOUT); - txstatus = inl(ioaddr + TxStatus0 + cur_tx*4); + txstatus = inl(ioaddr + RTL_REG_TXSTATUS0 + cur_tx*4); - if (status & TxOK) { + if (status & RTL_REG_INTRSTATUS_TXOK) { cur_tx = (cur_tx + 1) % NUM_TX_DESC; debug_cond(DEBUG_TX, @@ -465,13 +499,16 @@ static int rtl_poll(struct eth_device *dev) ioaddr = dev->iobase; - if (inb(ioaddr + ChipCmd) & RxBufEmpty) { + if (inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) { return 0; } - status = inw(ioaddr + IntrStatus); + status = inw(ioaddr + RTL_REG_INTRSTATUS); /* See below for the rest of the interrupt acknowledges. */ - outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); + outw(status & ~(RTL_REG_INTRSTATUS_RXFIFOOVER | + RTL_REG_INTRSTATUS_RXOVERFLOW | + RTL_REG_INTRSTATUS_RXOK), + ioaddr + RTL_REG_INTRSTATUS); debug_cond(DEBUG_RX, "rtl_poll: int %hX ", status); @@ -481,7 +518,9 @@ static int rtl_poll(struct eth_device *dev) rx_size = rx_status >> 16; rx_status &= 0xffff; - if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) || + if ((rx_status & (RTL_STS_RXBADSYMBOL | RTL_STS_RXRUNT | + RTL_STS_RXTOOLONG | RTL_STS_RXCRCERR | + RTL_STS_RXBADALIGN)) || (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) { printf("rx error %hX\n", rx_status); rtl_reset(dev); /* this clears all interrupts still pending */ @@ -507,11 +546,13 @@ static int rtl_poll(struct eth_device *dev) flush_cache((unsigned long)rx_ring, RX_BUF_LEN); cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; - outw(cur_rx - 16, ioaddr + RxBufPtr); + outw(cur_rx - 16, ioaddr + RTL_REG_RXBUFPTR); /* See RTL8139 Programming Guide V0.1 for the official handling of * Rx overflow situations. The document itself contains basically no * usable information, except for a few exception handling rules. */ - outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); + outw(status & (RTL_REG_INTRSTATUS_RXFIFOOVER | + RTL_REG_INTRSTATUS_RXOVERFLOW | + RTL_REG_INTRSTATUS_RXOK), ioaddr + RTL_REG_INTRSTATUS); return length; } @@ -522,11 +563,11 @@ static void rtl_disable(struct eth_device *dev) ioaddr = dev->iobase; /* reset the chip */ - outb(CmdReset, ioaddr + ChipCmd); + outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); /* Give the chip 10ms to finish the reset. */ for (i=0; i<100; ++i){ - if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break; + if ((inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_CMDRESET) == 0) break; udelay (100); /* wait 100us */ } } -- cgit v1.1 From f80f4e4d729252eb6124e1afb5dde9f74c35c994 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 21:20:31 +0200 Subject: net: rtl8139: Rework eeprom_delay() macro The macro assumes ee_addr variable to be present when it's being used. Rework the macro into a function instead and pass it an argument specifying the register base address, to make it future proof for DM conversion. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 9898f20..ff014ad 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -73,6 +73,7 @@ #include #include +#include #include #include #include @@ -297,18 +298,20 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis) #define EE_DATA_READ 0x01 /* EEPROM chip data out. */ #define EE_ENB (0x80 | EE_CS) -/* - Delay between EEPROM clock transitions. - No extra delay is needed with 33MHz PCI, but 66MHz may change this. -*/ - -#define eeprom_delay() inl(ee_addr) - /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD 5 #define EE_READ_CMD 6 #define EE_ERASE_CMD 7 +static void rtl8139_eeprom_delay(uintptr_t regbase) +{ + /* + * Delay between EEPROM clock transitions. + * No extra delay is needed with 33MHz PCI, but 66MHz may change this. + */ + inl(regbase + RTL_REG_CFG9346); +} + static int read_eeprom(int location, int addr_len) { int i; @@ -318,30 +321,30 @@ static int read_eeprom(int location, int addr_len) outb(EE_ENB & ~EE_CS, ee_addr); outb(EE_ENB, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outb(EE_ENB | dataval, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); } outb(EE_ENB, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); for (i = 16; i > 0; i--) { outb(EE_ENB | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0); outb(EE_ENB, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); } /* Terminate the EEPROM access. */ outb(~EE_CS, ee_addr); - eeprom_delay(); + rtl8139_eeprom_delay(ioaddr); return retval; } -- cgit v1.1 From 17dc95e5277cdbad1281b6b5605b1eef74729463 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 21:28:30 +0200 Subject: net: rtl8139: Minor cleanup of read_eeprom() Rename the function to rtl8139_read_eeprom() to keep the naming consistent, keep the variables sorted in reverse xmas tree. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index ff014ad..90e9f12 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -199,7 +199,7 @@ static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4))); static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4))); static int rtl8139_probe(struct eth_device *dev, bd_t *bis); -static int read_eeprom(int location, int addr_len); +static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); static void rtl_reset(struct eth_device *dev); static int rtl_transmit(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); @@ -273,9 +273,9 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis) /* Bring the chip out of low-power mode. */ outb(0x00, ioaddr + RTL_REG_CONFIG1); - addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6; + addr_len = rtl8139_read_eeprom(0,8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu (read_eeprom(i + 7, addr_len)); + *ap++ = le16_to_cpu (rtl8139_read_eeprom(i + 7, addr_len)); rtl_reset(dev); @@ -312,12 +312,13 @@ static void rtl8139_eeprom_delay(uintptr_t regbase) inl(regbase + RTL_REG_CFG9346); } -static int read_eeprom(int location, int addr_len) +static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len) { - int i; + unsigned int read_cmd = location | (EE_READ_CMD << addr_len); + uintptr_t ee_addr = ioaddr + RTL_REG_CFG9346; unsigned int retval = 0; - long ee_addr = ioaddr + RTL_REG_CFG9346; - int read_cmd = location | (EE_READ_CMD << addr_len); + u8 dataval; + int i; outb(EE_ENB & ~EE_CS, ee_addr); outb(EE_ENB, ee_addr); @@ -325,19 +326,21 @@ static int read_eeprom(int location, int addr_len) /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { - int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + dataval = (read_cmd & BIT(i)) ? EE_DATA_WRITE : 0; outb(EE_ENB | dataval, ee_addr); rtl8139_eeprom_delay(ioaddr); outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); rtl8139_eeprom_delay(ioaddr); } + outb(EE_ENB, ee_addr); rtl8139_eeprom_delay(ioaddr); for (i = 16; i > 0; i--) { outb(EE_ENB | EE_SHIFT_CLK, ee_addr); rtl8139_eeprom_delay(ioaddr); - retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0); + retval <<= 1; + retval |= inb(ee_addr) & EE_DATA_READ; outb(EE_ENB, ee_addr); rtl8139_eeprom_delay(ioaddr); } @@ -345,6 +348,7 @@ static int read_eeprom(int location, int addr_len) /* Terminate the EEPROM access. */ outb(~EE_CS, ee_addr); rtl8139_eeprom_delay(ioaddr); + return retval; } -- cgit v1.1 From 198e6b571b58de54803a92743970c8f5dea77782 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 21:30:38 +0200 Subject: net: rtl8139: Consistently use rtl8139_rx_config This string of macros is exactly the same thing as rtl8139_rx_config, so just use rtl8139_rx_config. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 90e9f12..7a2829a 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -396,8 +396,8 @@ static void rtl_reset(struct eth_device *dev) /* Must enable Tx/Rx before setting transfer thresholds! */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, ioaddr + RTL_REG_CHIPCMD); - outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8), - ioaddr + RTL_REG_RXCONFIG); /* accept no frames yet! */ + /* accept no frames yet! */ + outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG); outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + RTL_REG_TXCONFIG); /* The Linux driver changes RTL_REG_CONFIG1 here to use a different LED pattern -- cgit v1.1 From 89f3facffb8b35f45d405716dce63f6bc944a082 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 21:35:12 +0200 Subject: net: rtl8139: Minor cleanup of set_rx_mode() Rename the function to rtl8139_set_rx_mode(), use unsigned variables where applicable and inline mc_filter[] values. No functional chanage. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 7a2829a..4dfb709 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -357,19 +357,17 @@ static const unsigned int rtl8139_rx_config = (RX_FIFO_THRESH << 13) | (RX_DMA_BURST << 8); -static void set_rx_mode(struct eth_device *dev) { - unsigned int mc_filter[2]; - int rx_mode; +static void rtl8139_set_rx_mode(struct eth_device *dev) +{ /* !IFF_PROMISC */ - rx_mode = RTL_REG_RXCONFIG_ACCEPTBROADCAST | - RTL_REG_RXCONFIG_ACCEPTMULTICAST | - RTL_REG_RXCONFIG_ACCEPTMYPHYS; - mc_filter[1] = mc_filter[0] = 0xffffffff; + unsigned int rx_mode = RTL_REG_RXCONFIG_ACCEPTBROADCAST | + RTL_REG_RXCONFIG_ACCEPTMULTICAST | + RTL_REG_RXCONFIG_ACCEPTMYPHYS; outl(rtl8139_rx_config | rx_mode, ioaddr + RTL_REG_RXCONFIG); - outl(mc_filter[0], ioaddr + RTL_REG_MAR0 + 0); - outl(mc_filter[1], ioaddr + RTL_REG_MAR0 + 4); + outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 0); + outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 4); } static void rtl_reset(struct eth_device *dev) @@ -425,8 +423,7 @@ static void rtl_reset(struct eth_device *dev) /* Start the chip's Tx and Rx process. */ outl(0, ioaddr + RTL_REG_RXMISSED); - /* set_rx_mode */ - set_rx_mode(dev); + rtl8139_set_rx_mode(dev); /* Disable all known interrupts by setting the interrupt mask. */ outw(0, ioaddr + RTL_REG_INTRMASK); -- cgit v1.1 From c7a3e35d768ddc6b6d3a9a0e061bba0741deaa52 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 21:41:56 +0200 Subject: net: rtl8139: Minor cleanup of rtl_reset() Rename the function to rtl8139_reset(), clean up the reset polling and various line-over-80 problems. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 61 ++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 4dfb709..d9d8aae 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -200,7 +200,7 @@ static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4))); static int rtl8139_probe(struct eth_device *dev, bd_t *bis); static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); -static void rtl_reset(struct eth_device *dev); +static void rtl8139_reset(struct eth_device *dev); static int rtl_transmit(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); @@ -277,7 +277,7 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis) for (i = 0; i < 3; i++) *ap++ = le16_to_cpu (rtl8139_read_eeprom(i + 7, addr_len)); - rtl_reset(dev); + rtl8139_reset(dev); if (inb(ioaddr + RTL_REG_MEDIASTATUS) & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { printf("Cable not connected or other link failure\n"); @@ -370,8 +370,9 @@ static void rtl8139_set_rx_mode(struct eth_device *dev) outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 4); } -static void rtl_reset(struct eth_device *dev) +static void rtl8139_reset(struct eth_device *dev) { + u8 reg; int i; outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); @@ -380,11 +381,12 @@ static void rtl_reset(struct eth_device *dev) cur_tx = 0; /* Give the chip 10ms to finish the reset. */ - for (i=0; i<100; ++i){ - if ((inb(ioaddr + RTL_REG_CHIPCMD) & - RTL_REG_CHIPCMD_CMDRESET) == 0) + for (i = 0; i < 100; i++) { + reg = inb(ioaddr + RTL_REG_CHIPCMD); + if (!(reg & RTL_REG_CHIPCMD_CMDRESET)) break; - udelay (100); /* wait 100us */ + + udelay(100); } @@ -393,30 +395,35 @@ static void rtl_reset(struct eth_device *dev) /* Must enable Tx/Rx before setting transfer thresholds! */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, - ioaddr + RTL_REG_CHIPCMD); + ioaddr + RTL_REG_CHIPCMD); + /* accept no frames yet! */ outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG); - outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + RTL_REG_TXCONFIG); - - /* The Linux driver changes RTL_REG_CONFIG1 here to use a different LED pattern - * for half duplex or full/autodetect duplex (for full/autodetect, the - * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses - * TX/RX, Link100, Link10). This is messy, because it doesn't match - * the inscription on the mounting bracket. It should not be changed - * from the configuration EEPROM default, because the card manufacturer - * should have set that to match the card. */ - - debug_cond(DEBUG_RX, - "rx ring address is %lX\n",(unsigned long)rx_ring); + outl((TX_DMA_BURST << 8) | 0x03000000, ioaddr + RTL_REG_TXCONFIG); + + /* + * The Linux driver changes RTL_REG_CONFIG1 here to use a different + * LED pattern for half duplex or full/autodetect duplex (for + * full/autodetect, the outputs are TX/RX, Link10/100, FULL, while + * for half duplex it uses TX/RX, Link100, Link10). This is messy, + * because it doesn't match the inscription on the mounting bracket. + * It should not be changed from the configuration EEPROM default, + * because the card manufacturer should have set that to match the + * card. + */ + debug_cond(DEBUG_RX, "rx ring address is %p\n", rx_ring); + flush_cache((unsigned long)rx_ring, RX_BUF_LEN); outl(phys_to_bus((int)rx_ring), ioaddr + RTL_REG_RXBUF); - /* If we add multicast support, the RTL_REG_MAR0 register would have to be - * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot - * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */ - + /* + * If we add multicast support, the RTL_REG_MAR0 register would have + * to be initialized to 0xffffffffffffffff (two 32 bit accesses). + * Etherboot only needs broadcast (for ARP/RARP/BOOTP/DHCP) and + * unicast. + */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, - ioaddr + RTL_REG_CHIPCMD); + ioaddr + RTL_REG_CHIPCMD); outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG); @@ -488,7 +495,7 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length) "tx timeout/error (%d usecs), status %hX txstatus %lX\n", 10*i, status, txstatus); - rtl_reset(dev); + rtl8139_reset(dev); return 0; } @@ -527,7 +534,7 @@ static int rtl_poll(struct eth_device *dev) RTL_STS_RXBADALIGN)) || (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) { printf("rx error %hX\n", rx_status); - rtl_reset(dev); /* this clears all interrupts still pending */ + rtl8139_reset(dev); /* this clears all interrupts still pending */ return 0; } -- cgit v1.1 From 67fdbc06be27728e41aa9682d6aaf5618d959765 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 22:40:45 +0200 Subject: net: rtl8139: Minor cleanup of rtl_transmit() Rename the function to rtl8139_send(), clean up the TX polling, the TX OK condition at the end, overuse of typecasts, and various line-over-80 problems. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 64 +++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index d9d8aae..cb1166e 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -201,7 +201,7 @@ static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4))); static int rtl8139_probe(struct eth_device *dev, bd_t *bis); static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); static void rtl8139_reset(struct eth_device *dev); -static int rtl_transmit(struct eth_device *dev, void *packet, int length); +static int rtl8139_send(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) @@ -246,7 +246,7 @@ int rtl8139_initialize(bd_t *bis) dev->iobase = (int)bus_to_phys(iobase); dev->init = rtl8139_probe; dev->halt = rtl_disable; - dev->send = rtl_transmit; + dev->send = rtl8139_send; dev->recv = rtl_poll; dev->mcast = rtl_bcast_addr; @@ -436,29 +436,31 @@ static void rtl8139_reset(struct eth_device *dev) outw(0, ioaddr + RTL_REG_INTRMASK); } -static int rtl_transmit(struct eth_device *dev, void *packet, int length) +static int rtl8139_send(struct eth_device *dev, void *packet, int length) { - unsigned int status; - unsigned long txstatus; unsigned int len = length; + unsigned long txstatus; + unsigned int status; int i = 0; ioaddr = dev->iobase; - memcpy((char *)tx_buffer, (char *)packet, (int)length); + memcpy(tx_buffer, packet, length); debug_cond(DEBUG_TX, "sending %d bytes\n", len); - /* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4 - * bytes are sent automatically for the FCS, totalling to 64 bytes). */ - while (len < ETH_ZLEN) { + /* + * Note: RTL8139 doesn't auto-pad, send minimum payload (another 4 + * bytes are sent automatically for the FCS, totalling to 64 bytes). + */ + while (len < ETH_ZLEN) tx_buffer[len++] = '\0'; - } flush_cache((unsigned long)tx_buffer, length); - outl(phys_to_bus((int)tx_buffer), ioaddr + RTL_REG_TXADDR0 + cur_tx*4); - outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len, - ioaddr + RTL_REG_TXSTATUS0 + cur_tx*4); + outl(phys_to_bus((unsigned long)tx_buffer), + ioaddr + RTL_REG_TXADDR0 + cur_tx * 4); + outl(((TX_FIFO_THRESH << 11) & 0x003f0000) | len, + ioaddr + RTL_REG_TXSTATUS0 + cur_tx * 4); do { status = inw(ioaddr + RTL_REG_INTRSTATUS); @@ -468,37 +470,33 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length) * RTL_REG_INTRSTATUS_RXFIFOOVER MUST be handled in the * rtl_poll() function. */ - outw(status & (RTL_REG_INTRSTATUS_TXOK | - RTL_REG_INTRSTATUS_TXERR | - RTL_REG_INTRSTATUS_PCIERR), - ioaddr + RTL_REG_INTRSTATUS); - if ((status & (RTL_REG_INTRSTATUS_TXOK | - RTL_REG_INTRSTATUS_TXERR | - RTL_REG_INTRSTATUS_PCIERR)) != 0) + status &= RTL_REG_INTRSTATUS_TXOK | RTL_REG_INTRSTATUS_TXERR | + RTL_REG_INTRSTATUS_PCIERR; + outw(status, ioaddr + RTL_REG_INTRSTATUS); + if (status) break; + udelay(10); } while (i++ < RTL_TIMEOUT); - txstatus = inl(ioaddr + RTL_REG_TXSTATUS0 + cur_tx*4); - - if (status & RTL_REG_INTRSTATUS_TXOK) { - cur_tx = (cur_tx + 1) % NUM_TX_DESC; + txstatus = inl(ioaddr + RTL_REG_TXSTATUS0 + cur_tx * 4); + if (!(status & RTL_REG_INTRSTATUS_TXOK)) { debug_cond(DEBUG_TX, - "tx done, status %hX txstatus %lX\n", - status, txstatus); - - return length; - } else { - - debug_cond(DEBUG_TX, - "tx timeout/error (%d usecs), status %hX txstatus %lX\n", - 10*i, status, txstatus); + "tx timeout/error (%d usecs), status %hX txstatus %lX\n", + 10 * i, status, txstatus); rtl8139_reset(dev); return 0; } + + cur_tx = (cur_tx + 1) % NUM_TX_DESC; + + debug_cond(DEBUG_TX, "tx done, status %hX txstatus %lX\n", + status, txstatus); + + return length; } static int rtl_poll(struct eth_device *dev) -- cgit v1.1 From 468fd955626b650ebb7975d061d415682c91f041 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 22:43:16 +0200 Subject: net: rtl8139: Minor cleanup of rtl_poll() Rename the function to rtl8139_recv(), clean up various checkpatch errors, line-over-80 conditions, and malformed comments. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 63 +++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index cb1166e..d942ccf 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -44,7 +44,7 @@ which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My interpretation of this "reserved" is that Etherboot may do whatever it likes, as long as its environment is kept intact (like the BIOS - variables). Hopefully fixed rtl_poll() once and for all. The symptoms + variables). Hopefully fixed rtl8139_recv() once and for all. The symptoms were that if Etherboot was left at the boot menu for several minutes, the first eth_poll failed. Seems like I am the only person who does this. First of all I fixed the debugging code and then set out for a long bug @@ -65,7 +65,7 @@ corruption because of exceeding 32K during runtime. 28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de) - rtl_poll was quite broken: it used the RxOK interrupt flag instead + rtl8139_recv was quite broken: it used the RxOK interrupt flag instead of the RxBufferEmpty flag which often resulted in very bad transmission performace - below 1kBytes/s. @@ -202,7 +202,7 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis); static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); static void rtl8139_reset(struct eth_device *dev); static int rtl8139_send(struct eth_device *dev, void *packet, int length); -static int rtl_poll(struct eth_device *dev); +static int rtl8139_recv(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) { @@ -247,7 +247,7 @@ int rtl8139_initialize(bd_t *bis) dev->init = rtl8139_probe; dev->halt = rtl_disable; dev->send = rtl8139_send; - dev->recv = rtl_poll; + dev->recv = rtl8139_recv; dev->mcast = rtl_bcast_addr; eth_register (dev); @@ -468,7 +468,7 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) * Only acknlowledge interrupt sources we can properly * handle here - the RTL_REG_INTRSTATUS_RXOVERFLOW/ * RTL_REG_INTRSTATUS_RXFIFOOVER MUST be handled in the - * rtl_poll() function. + * rtl8139_recv() function. */ status &= RTL_REG_INTRSTATUS_TXOK | RTL_REG_INTRSTATUS_TXERR | RTL_REG_INTRSTATUS_PCIERR; @@ -499,27 +499,26 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) return length; } -static int rtl_poll(struct eth_device *dev) +static int rtl8139_recv(struct eth_device *dev) { - unsigned int status; - unsigned int ring_offs; + const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER | + RTL_REG_INTRSTATUS_RXOVERFLOW | + RTL_REG_INTRSTATUS_RXOK; unsigned int rx_size, rx_status; - int length=0; + unsigned int ring_offs; + unsigned int status; + int length = 0; ioaddr = dev->iobase; - if (inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) { + if (inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) return 0; - } status = inw(ioaddr + RTL_REG_INTRSTATUS); /* See below for the rest of the interrupt acknowledges. */ - outw(status & ~(RTL_REG_INTRSTATUS_RXFIFOOVER | - RTL_REG_INTRSTATUS_RXOVERFLOW | - RTL_REG_INTRSTATUS_RXOK), - ioaddr + RTL_REG_INTRSTATUS); + outw(status & ~rxstat, ioaddr + RTL_REG_INTRSTATUS); - debug_cond(DEBUG_RX, "rtl_poll: int %hX ", status); + debug_cond(DEBUG_RX, "%s: int %hX ", __func__, status); ring_offs = cur_rx % RX_BUF_LEN; /* ring_offs is guaranteed being 4-byte aligned */ @@ -530,38 +529,42 @@ static int rtl_poll(struct eth_device *dev) if ((rx_status & (RTL_STS_RXBADSYMBOL | RTL_STS_RXRUNT | RTL_STS_RXTOOLONG | RTL_STS_RXCRCERR | RTL_STS_RXBADALIGN)) || - (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) { + (rx_size < ETH_ZLEN) || + (rx_size > ETH_FRAME_LEN + 4)) { printf("rx error %hX\n", rx_status); - rtl8139_reset(dev); /* this clears all interrupts still pending */ + /* this clears all interrupts still pending */ + rtl8139_reset(dev); return 0; } /* Received a good packet */ length = rx_size - 4; /* no one cares about the FCS */ - if (ring_offs+4+rx_size-4 > RX_BUF_LEN) { - int semi_count = RX_BUF_LEN - ring_offs - 4; + if (ring_offs + 4 + rx_size - 4 > RX_BUF_LEN) { unsigned char rxdata[RX_BUF_LEN]; + int semi_count = RX_BUF_LEN - ring_offs - 4; memcpy(rxdata, rx_ring + ring_offs + 4, semi_count); - memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count); + memcpy(&rxdata[semi_count], rx_ring, + rx_size - 4 - semi_count); net_process_received_packet(rxdata, length); debug_cond(DEBUG_RX, "rx packet %d+%d bytes", - semi_count, rx_size-4-semi_count); + semi_count, rx_size - 4 - semi_count); } else { net_process_received_packet(rx_ring + ring_offs + 4, length); - debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size-4); + debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size - 4); } flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; + cur_rx = ROUND(cur_rx + rx_size + 4, 4); outw(cur_rx - 16, ioaddr + RTL_REG_RXBUFPTR); - /* See RTL8139 Programming Guide V0.1 for the official handling of - * Rx overflow situations. The document itself contains basically no - * usable information, except for a few exception handling rules. */ - outw(status & (RTL_REG_INTRSTATUS_RXFIFOOVER | - RTL_REG_INTRSTATUS_RXOVERFLOW | - RTL_REG_INTRSTATUS_RXOK), ioaddr + RTL_REG_INTRSTATUS); + /* + * See RTL8139 Programming Guide V0.1 for the official handling of + * Rx overflow situations. The document itself contains basically + * no usable information, except for a few exception handling rules. + */ + outw(status & rxstat, ioaddr + RTL_REG_INTRSTATUS); + return length; } -- cgit v1.1 From 661479ffc1a0b7ea159dae1ca34d61d009896870 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 22:55:40 +0200 Subject: net: rtl8139: Minor cleanup of rtl_disable() Rename the function to rtl8139_stop(), clean up checkpatch errors in the stop polling function. No functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index d942ccf..6aed7bd 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -203,7 +203,7 @@ static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); static void rtl8139_reset(struct eth_device *dev); static int rtl8139_send(struct eth_device *dev, void *packet, int length); static int rtl8139_recv(struct eth_device *dev); -static void rtl_disable(struct eth_device *dev); +static void rtl8139_stop(struct eth_device *dev); static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) { return (0); @@ -245,7 +245,7 @@ int rtl8139_initialize(bd_t *bis) dev->priv = (void *) devno; dev->iobase = (int)bus_to_phys(iobase); dev->init = rtl8139_probe; - dev->halt = rtl_disable; + dev->halt = rtl8139_stop; dev->send = rtl8139_send; dev->recv = rtl8139_recv; dev->mcast = rtl_bcast_addr; @@ -568,8 +568,9 @@ static int rtl8139_recv(struct eth_device *dev) return length; } -static void rtl_disable(struct eth_device *dev) +static void rtl8139_stop(struct eth_device *dev) { + u8 reg; int i; ioaddr = dev->iobase; @@ -578,8 +579,10 @@ static void rtl_disable(struct eth_device *dev) outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); /* Give the chip 10ms to finish the reset. */ - for (i=0; i<100; ++i){ - if ((inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_CMDRESET) == 0) break; + for (i = 0; i < 100; i++) { + reg = inb(ioaddr + RTL_REG_CHIPCMD); + if (!(reg & RTL_REG_CHIPCMD_CMDRESET)) + break; udelay (100); /* wait 100us */ } } -- cgit v1.1 From 38b306db2334a6565b326874eb4ff536e28654ba Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 22:58:27 +0200 Subject: net: rtl8139: Factor out hardware reset This hardware reset and reset-wait implementation was twice in the driver, factor it out into a separate function. This really should use wait_for_bit() eventually and return -ETIMEDOUT, but thus far, handling of any of this is missing from the driver. This must be added later. Thus far, no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 6aed7bd..68ef9ee 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -370,16 +370,13 @@ static void rtl8139_set_rx_mode(struct eth_device *dev) outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 4); } -static void rtl8139_reset(struct eth_device *dev) +static void rtl8139_hw_reset(struct eth_device *dev) { u8 reg; int i; outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); - cur_rx = 0; - cur_tx = 0; - /* Give the chip 10ms to finish the reset. */ for (i = 0; i < 100; i++) { reg = inb(ioaddr + RTL_REG_CHIPCMD); @@ -388,7 +385,16 @@ static void rtl8139_reset(struct eth_device *dev) udelay(100); } +} + +static void rtl8139_reset(struct eth_device *dev) +{ + int i; + + cur_rx = 0; + cur_tx = 0; + rtl8139_hw_reset(dev); for (i = 0; i < ETH_ALEN; i++) outb(dev->enetaddr[i], ioaddr + RTL_REG_MAC0 + i); @@ -570,19 +576,7 @@ static int rtl8139_recv(struct eth_device *dev) static void rtl8139_stop(struct eth_device *dev) { - u8 reg; - int i; - ioaddr = dev->iobase; - /* reset the chip */ - outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); - - /* Give the chip 10ms to finish the reset. */ - for (i = 0; i < 100; i++) { - reg = inb(ioaddr + RTL_REG_CHIPCMD); - if (!(reg & RTL_REG_CHIPCMD_CMDRESET)) - break; - udelay (100); /* wait 100us */ - } + rtl8139_hw_reset(dev); } -- cgit v1.1 From 0e5a4117a58b8d47b502d7e5536ca6b36d568806 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 23:01:45 +0200 Subject: net: rtl8139: Finish cleanup Finish the checkpatch cleanup of the driver, fix the remaining issues in probe and init function and in global variables, rename the probe function to rtl8139_init(), no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 173 +++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 68ef9ee..b901e3a 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -8,68 +8,67 @@ */ /* rtl8139.c - etherboot driver for the Realtek 8139 chipset - - ported from the linux driver written by Donald Becker - by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999 - - This software may be used and distributed according to the terms - of the GNU Public License, incorporated herein by reference. - - changes to the original driver: - - removed support for interrupts, switching to polling mode (yuck!) - - removed support for the 8129 chip (external MII) - -*/ + * + * ported from the linux driver written by Donald Becker + * by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999 + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * changes to the original driver: + * - removed support for interrupts, switching to polling mode (yuck!) + * - removed support for the 8129 chip (external MII) + */ /*********************************************************************/ /* Revision History */ /*********************************************************************/ /* - 28 Dec 2002 ken_yap@users.sourceforge.net (Ken Yap) - Put in virt_to_bus calls to allow Etherboot relocation. - - 06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap) - Following email from Hyun-Joon Cha, added a disable routine, otherwise - NIC remains live and can crash the kernel later. - - 4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub) - Shuffled things around, removed the leftovers from the 8129 support - that was in the Linux driver and added a bit more 8139 definitions. - Moved the 8K receive buffer to a fixed, available address outside the - 0x98000-0x9ffff range. This is a bit of a hack, but currently the only - way to make room for the Etherboot features that need substantial amounts - of code like the ANSI console support. Currently the buffer is just below - 0x10000, so this even conforms to the tagged boot image specification, - which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My - interpretation of this "reserved" is that Etherboot may do whatever it - likes, as long as its environment is kept intact (like the BIOS - variables). Hopefully fixed rtl8139_recv() once and for all. The symptoms - were that if Etherboot was left at the boot menu for several minutes, the - first eth_poll failed. Seems like I am the only person who does this. - First of all I fixed the debugging code and then set out for a long bug - hunting session. It took me about a week full time work - poking around - various places in the driver, reading Don Becker's and Jeff Garzik's Linux - driver and even the FreeBSD driver (what a piece of crap!) - and - eventually spotted the nasty thing: the transmit routine was acknowledging - each and every interrupt pending, including the RxOverrun and RxFIFIOver - interrupts. This confused the RTL8139 thoroughly. It destroyed the - Rx ring contents by dumping the 2K FIFO contents right where we wanted to - get the next packet. Oh well, what fun. - - 18 Jan 2000 mdc@thinguin.org (Marty Connor) - Drastically simplified error handling. Basically, if any error - in transmission or reception occurs, the card is reset. - Also, pointed all transmit descriptors to the same buffer to - save buffer space. This should decrease driver size and avoid - corruption because of exceeding 32K during runtime. - - 28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de) - rtl8139_recv was quite broken: it used the RxOK interrupt flag instead - of the RxBufferEmpty flag which often resulted in very bad - transmission performace - below 1kBytes/s. - -*/ + * 28 Dec 2002 ken_yap@users.sourceforge.net (Ken Yap) + * Put in virt_to_bus calls to allow Etherboot relocation. + * + * 06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap) + * Following email from Hyun-Joon Cha, added a disable routine, otherwise + * NIC remains live and can crash the kernel later. + * + * 4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub) + * Shuffled things around, removed the leftovers from the 8129 support + * that was in the Linux driver and added a bit more 8139 definitions. + * Moved the 8K receive buffer to a fixed, available address outside the + * 0x98000-0x9ffff range. This is a bit of a hack, but currently the only + * way to make room for the Etherboot features that need substantial amounts + * of code like the ANSI console support. Currently the buffer is just below + * 0x10000, so this even conforms to the tagged boot image specification, + * which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My + * interpretation of this "reserved" is that Etherboot may do whatever it + * likes, as long as its environment is kept intact (like the BIOS + * variables). Hopefully fixed rtl8139_recv() once and for all. The symptoms + * were that if Etherboot was left at the boot menu for several minutes, the + * first eth_poll failed. Seems like I am the only person who does this. + * First of all I fixed the debugging code and then set out for a long bug + * hunting session. It took me about a week full time work - poking around + * various places in the driver, reading Don Becker's and Jeff Garzik's Linux + * driver and even the FreeBSD driver (what a piece of crap!) - and + * eventually spotted the nasty thing: the transmit routine was acknowledging + * each and every interrupt pending, including the RxOverrun and RxFIFIOver + * interrupts. This confused the RTL8139 thoroughly. It destroyed the + * Rx ring contents by dumping the 2K FIFO contents right where we wanted to + * get the next packet. Oh well, what fun. + * + * 18 Jan 2000 mdc@thinguin.org (Marty Connor) + * Drastically simplified error handling. Basically, if any error + * in transmission or reception occurs, the card is reset. + * Also, pointed all transmit descriptors to the same buffer to + * save buffer space. This should decrease driver size and avoid + * corruption because of exceeding 32K during runtime. + * + * 28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de) + * rtl8139_recv was quite broken: it used the RxOK interrupt flag instead + * of the RxBufferEmpty flag which often resulted in very bad + * transmission performace - below 1kBytes/s. + * + */ #include #include @@ -82,8 +81,8 @@ #define RTL_TIMEOUT 100000 -/* PCI Tuning Parameters - Threshold is bytes transferred to chip before transmission starts. */ +/* PCI Tuning Parameters */ +/* Threshold is bytes transferred to chip before transmission starts. */ #define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */ #define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */ @@ -192,13 +191,13 @@ #define RTL_STS_RXSTATUSOK BIT(0) static int ioaddr; -static unsigned int cur_rx,cur_tx; +static unsigned int cur_rx, cur_tx; /* The RTL8139 can only transmit from a contiguous, aligned memory block. */ -static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4))); -static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4))); +static unsigned char tx_buffer[TX_BUF_SIZE] __aligned(4); +static unsigned char rx_ring[RX_BUF_LEN + 16] __aligned(4); -static int rtl8139_probe(struct eth_device *dev, bd_t *bis); +static int rtl8139_init(struct eth_device *dev, bd_t *bis); static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); static void rtl8139_reset(struct eth_device *dev); static int rtl8139_send(struct eth_device *dev, void *packet, int length); @@ -206,82 +205,84 @@ static int rtl8139_recv(struct eth_device *dev); static void rtl8139_stop(struct eth_device *dev); static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) { - return (0); + return 0; } static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139}, - {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139}, - {} + { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139 }, + { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139 }, + { } }; int rtl8139_initialize(bd_t *bis) { - pci_dev_t devno; - int card_number = 0; struct eth_device *dev; + int card_number = 0; + pci_dev_t devno; + int idx = 0; u32 iobase; - int idx=0; - while(1){ + while (1) { /* Find RTL8139 */ - if ((devno = pci_find_devices(supported, idx++)) < 0) + devno = pci_find_devices(supported, idx++); + if (devno < 0) break; pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); iobase &= ~0xf; - debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); + debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); - dev = (struct eth_device *)malloc(sizeof *dev); + dev = (struct eth_device *)malloc(sizeof(*dev)); if (!dev) { printf("Can not allocate memory of rtl8139\n"); break; } memset(dev, 0, sizeof(*dev)); - sprintf (dev->name, "RTL8139#%d", card_number); + sprintf(dev->name, "RTL8139#%d", card_number); - dev->priv = (void *) devno; + dev->priv = (void *)devno; dev->iobase = (int)bus_to_phys(iobase); - dev->init = rtl8139_probe; + dev->init = rtl8139_init; dev->halt = rtl8139_stop; dev->send = rtl8139_send; dev->recv = rtl8139_recv; dev->mcast = rtl_bcast_addr; - eth_register (dev); + eth_register(dev); card_number++; - pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); + pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); - udelay (10 * 1000); + udelay(10 * 1000); } return card_number; } -static int rtl8139_probe(struct eth_device *dev, bd_t *bis) +static int rtl8139_init(struct eth_device *dev, bd_t *bis) { - int i; - int addr_len; unsigned short *ap = (unsigned short *)dev->enetaddr; + int addr_len, i; + u8 reg; ioaddr = dev->iobase; /* Bring the chip out of low-power mode. */ outb(0x00, ioaddr + RTL_REG_CONFIG1); - addr_len = rtl8139_read_eeprom(0,8) == 0x8129 ? 8 : 6; + addr_len = rtl8139_read_eeprom(0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu (rtl8139_read_eeprom(i + 7, addr_len)); + *ap++ = le16_to_cpu(rtl8139_read_eeprom(i + 7, addr_len)); rtl8139_reset(dev); - if (inb(ioaddr + RTL_REG_MEDIASTATUS) & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { + reg = inb(ioaddr + RTL_REG_MEDIASTATUS); + if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { printf("Cable not connected or other link failure\n"); - return -1 ; + return -1; } return 0; -- cgit v1.1 From 6ee6caaf035063dc376eeb3385f7f08f87549b1e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 23:12:11 +0200 Subject: net: rtl8139: Move functions around Just move functions around in preparation for easy DM conversion, rename rtl_bcast_addr() to rtl8139_bcast_addr(), no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 179 ++++++++++++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index b901e3a..66591d0 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -190,104 +190,13 @@ #define RTL_STS_RXBADALIGN BIT(1) #define RTL_STS_RXSTATUSOK BIT(0) -static int ioaddr; static unsigned int cur_rx, cur_tx; +static int ioaddr; /* The RTL8139 can only transmit from a contiguous, aligned memory block. */ static unsigned char tx_buffer[TX_BUF_SIZE] __aligned(4); static unsigned char rx_ring[RX_BUF_LEN + 16] __aligned(4); -static int rtl8139_init(struct eth_device *dev, bd_t *bis); -static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len); -static void rtl8139_reset(struct eth_device *dev); -static int rtl8139_send(struct eth_device *dev, void *packet, int length); -static int rtl8139_recv(struct eth_device *dev); -static void rtl8139_stop(struct eth_device *dev); -static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) -{ - return 0; -} - -static struct pci_device_id supported[] = { - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139 }, - { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139 }, - { } -}; - -int rtl8139_initialize(bd_t *bis) -{ - struct eth_device *dev; - int card_number = 0; - pci_dev_t devno; - int idx = 0; - u32 iobase; - - while (1) { - /* Find RTL8139 */ - devno = pci_find_devices(supported, idx++); - if (devno < 0) - break; - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); - iobase &= ~0xf; - - debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); - - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (!dev) { - printf("Can not allocate memory of rtl8139\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "RTL8139#%d", card_number); - - dev->priv = (void *)devno; - dev->iobase = (int)bus_to_phys(iobase); - dev->init = rtl8139_init; - dev->halt = rtl8139_stop; - dev->send = rtl8139_send; - dev->recv = rtl8139_recv; - dev->mcast = rtl_bcast_addr; - - eth_register(dev); - - card_number++; - - pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); - - udelay(10 * 1000); - } - - return card_number; -} - -static int rtl8139_init(struct eth_device *dev, bd_t *bis) -{ - unsigned short *ap = (unsigned short *)dev->enetaddr; - int addr_len, i; - u8 reg; - - ioaddr = dev->iobase; - - /* Bring the chip out of low-power mode. */ - outb(0x00, ioaddr + RTL_REG_CONFIG1); - - addr_len = rtl8139_read_eeprom(0, 8) == 0x8129 ? 8 : 6; - for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu(rtl8139_read_eeprom(i + 7, addr_len)); - - rtl8139_reset(dev); - - reg = inb(ioaddr + RTL_REG_MEDIASTATUS); - if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { - printf("Cable not connected or other link failure\n"); - return -1; - } - - return 0; -} - /* Serial EEPROM section. */ /* EEPROM_Ctrl bits. */ @@ -575,9 +484,95 @@ static int rtl8139_recv(struct eth_device *dev) return length; } +static int rtl8139_init(struct eth_device *dev, bd_t *bis) +{ + unsigned short *ap = (unsigned short *)dev->enetaddr; + int addr_len, i; + u8 reg; + + ioaddr = dev->iobase; + + /* Bring the chip out of low-power mode. */ + outb(0x00, ioaddr + RTL_REG_CONFIG1); + + addr_len = rtl8139_read_eeprom(0, 8) == 0x8129 ? 8 : 6; + for (i = 0; i < 3; i++) + *ap++ = le16_to_cpu(rtl8139_read_eeprom(i + 7, addr_len)); + + rtl8139_reset(dev); + + reg = inb(ioaddr + RTL_REG_MEDIASTATUS); + if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { + printf("Cable not connected or other link failure\n"); + return -1; + } + + return 0; +} + static void rtl8139_stop(struct eth_device *dev) { ioaddr = dev->iobase; rtl8139_hw_reset(dev); } + +static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, + int join) +{ + return 0; +} + +static struct pci_device_id supported[] = { + { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139 }, + { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139 }, + { } +}; + +int rtl8139_initialize(bd_t *bis) +{ + struct eth_device *dev; + int card_number = 0; + pci_dev_t devno; + int idx = 0; + u32 iobase; + + while (1) { + /* Find RTL8139 */ + devno = pci_find_devices(supported, idx++); + if (devno < 0) + break; + + pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); + iobase &= ~0xf; + + debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); + + dev = (struct eth_device *)malloc(sizeof(*dev)); + if (!dev) { + printf("Can not allocate memory of rtl8139\n"); + break; + } + memset(dev, 0, sizeof(*dev)); + + sprintf(dev->name, "RTL8139#%d", card_number); + + dev->priv = (void *)devno; + dev->iobase = (int)bus_to_phys(iobase); + dev->init = rtl8139_init; + dev->halt = rtl8139_stop; + dev->send = rtl8139_send; + dev->recv = rtl8139_recv; + dev->mcast = rtl8139_bcast_addr; + + eth_register(dev); + + card_number++; + + pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); + + udelay(10 * 1000); + } + + return card_number; +} -- cgit v1.1 From e7ab86d9b2f24c92552be62b0447abab4f8644a2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Apr 2020 23:49:25 +0200 Subject: net: rtl8139: Fill in SPDX tag The rtl8139 driver is derived from Etherboot driver, which is in turn derived from Linux 8139too driver added in Linux 2.2.18pre14. An undocumented change in Linux 2.4.10.2 added a new field to the driver, MODULE_LICENSE("GPL"); . According to current Linux kernel licensing rules, Documentation/process/license-rules.rst, quote: "GPL" Module is licensed under GPL version 2. This does not express any distinction between GPL-2.0-only or GPL-2.0-or-later. The exact license information can only be determined via the license information in the corresponding source files. And since the code does not contain any "future" clause, the tag is therefore GPL-2.0 only. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 66591d0..1f08397 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * rtl8139.c : U-Boot driver for the RealTek RTL8139 * @@ -12,9 +13,6 @@ * ported from the linux driver written by Donald Becker * by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999 * - * This software may be used and distributed according to the terms - * of the GNU Public License, incorporated herein by reference. - * * changes to the original driver: * - removed support for interrupts, switching to polling mode (yuck!) * - removed support for the 8129 chip (external MII) -- cgit v1.1 From 9c211e3b055ce809ac81ea4f849594ffb6f77df4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 00:08:31 +0100 Subject: net: smc911x: Remove pkt_data_{push,pull} These functions are never used and are likely a pre-DM remnant from times long past, just remove them. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 257b038..24b4eae 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -13,11 +13,6 @@ #include "smc911x.h" -u32 pkt_data_pull(struct eth_device *dev, u32 addr) \ - __attribute__ ((weak, alias ("smc911x_reg_read"))); -void pkt_data_push(struct eth_device *dev, u32 addr, u32 val) \ - __attribute__ ((weak, alias ("smc911x_reg_write"))); - static void smc911x_handle_mac_address(struct eth_device *dev) { unsigned long addrh, addrl; @@ -157,7 +152,7 @@ static int smc911x_send(struct eth_device *dev, void *packet, int length) tmplen = (length + 3) / 4; while (tmplen--) - pkt_data_push(dev, TX_DATA_FIFO, *data++); + smc911x_reg_write(dev, TX_DATA_FIFO, *data++); /* wait for transmission */ while (!((smc911x_reg_read(dev, TX_FIFO_INF) & @@ -203,7 +198,7 @@ static int smc911x_rx(struct eth_device *dev) tmplen = (pktlen + 3) / 4; while (tmplen--) - *data++ = pkt_data_pull(dev, RX_DATA_FIFO); + *data++ = smc911x_reg_read(dev, RX_DATA_FIFO); if (status & RX_STS_ES) printf(DRIVERNAME -- cgit v1.1 From 882d5f6983ff23b6f09899bb43d6dfd90ed7492f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 15:14:18 +0100 Subject: net: smc911x: Replace malloc()+memset() with calloc() Replace combination of malloc()+memset() with calloc() as the behavior is exactly the same and the amount of code is reduced. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 24b4eae..2c72e34 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -242,11 +242,9 @@ int smc911x_initialize(u8 dev_num, int base_addr) unsigned long addrl, addrh; struct eth_device *dev; - dev = malloc(sizeof(*dev)); - if (!dev) { - return -1; - } - memset(dev, 0, sizeof(*dev)); + dev = calloc(1, sizeof(*dev)); + if (!dev) + return -ENOMEM; dev->iobase = base_addr; -- cgit v1.1 From 49af0cb5a61c821d416ef069c6950d82523db585 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 15:40:15 +0100 Subject: net: smc911x: Rename smc911x_rx() to smc911x_recv() Rename the function to keep the naming scheme consistent, no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 2c72e34..6da6c89 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -184,7 +184,7 @@ static void smc911x_halt(struct eth_device *dev) smc911x_handle_mac_address(dev); } -static int smc911x_rx(struct eth_device *dev) +static int smc911x_recv(struct eth_device *dev) { u32 *data = (u32 *)net_rx_packets[0]; u32 pktlen, tmplen; @@ -269,7 +269,7 @@ int smc911x_initialize(u8 dev_num, int base_addr) dev->init = smc911x_init; dev->halt = smc911x_halt; dev->send = smc911x_send; - dev->recv = smc911x_rx; + dev->recv = smc911x_recv; sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num); eth_register(dev); -- cgit v1.1 From 6f6cf0083f466c49c97c175b0169a0cd31c35d63 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 15:43:20 +0100 Subject: net: smc911x: Invert the logic in smc911x_miiphy_{read,write}() Invert the logic in the aforementioned functions to reduce indent, no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 6da6c89..ceb4f81 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -216,24 +216,29 @@ static int smc911x_recv(struct eth_device *dev) static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad, int reg) { - u16 val = 0; struct eth_device *dev = eth_get_dev_by_name(bus->name); - if (dev) { - int retval = smc911x_eth_phy_read(dev, phy, reg, &val); - if (retval < 0) - return retval; - return val; - } - return -ENODEV; + u16 val = 0; + int ret; + + if (!dev) + return -ENODEV; + + ret = smc911x_eth_phy_read(dev, phy, reg, &val); + if (ret < 0) + return ret; + + return val; } /* wrapper for smc911x_eth_phy_write */ static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad, int reg, u16 val) { struct eth_device *dev = eth_get_dev_by_name(bus->name); - if (dev) - return smc911x_eth_phy_write(dev, phy, reg, val); - return -ENODEV; + + if (!dev) + return -ENODEV; + + return smc911x_eth_phy_write(dev, phy, reg, val); } #endif -- cgit v1.1 From 9741795408d2fb907256899cd9403dd57b917358 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 15:57:14 +0100 Subject: net: smc911x: Fix potential memleak() in init fail path Fix memleak in the init fail path, where if allocation or registration of MDIO bus fails, then ethernet interface is not unregistered and the private data are not freed, yet the probe function reports a failure. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index ceb4f81..4459da5 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -282,15 +282,23 @@ int smc911x_initialize(u8 dev_num, int base_addr) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) int retval; struct mii_dev *mdiodev = mdio_alloc(); - if (!mdiodev) + if (!mdiodev) { + eth_unregister(dev); + free(dev); return -ENOMEM; + } + strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); mdiodev->read = smc911x_miiphy_read; mdiodev->write = smc911x_miiphy_write; retval = mdio_register(mdiodev); - if (retval < 0) + if (retval < 0) { + mdio_free(mdiodev); + eth_unregister(dev); + free(dev); return retval; + } #endif return 1; -- cgit v1.1 From f51a2f84969a1c88fb96414835a3b04883f3d8eb Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 21 Mar 2020 17:25:41 +0100 Subject: net: smc911x: Pull MII registration into separate function Pull the MII interface registration into separate function to avoid the ifdeffery in smc911x_initialize(). Moreover, adjust the fail path such that we use goto labels. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 64 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 4459da5..65c25f3 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -240,12 +240,39 @@ static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad, return smc911x_eth_phy_write(dev, phy, reg, val); } + +static int smc911x_initialize_mii(struct eth_device *dev) +{ + struct mii_dev *mdiodev = mdio_alloc(); + int ret; + + if (!mdiodev) + return -ENOMEM; + + strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + mdiodev->read = smc911x_miiphy_read; + mdiodev->write = smc911x_miiphy_write; + + ret = mdio_register(mdiodev); + if (ret < 0) { + mdio_free(mdiodev); + return ret; + } + + return 0; +} +#else +static int smc911x_initialize_mii(struct eth_device *dev) +{ + return 0; +} #endif int smc911x_initialize(u8 dev_num, int base_addr) { unsigned long addrl, addrh; struct eth_device *dev; + int ret; dev = calloc(1, sizeof(*dev)); if (!dev) @@ -254,9 +281,10 @@ int smc911x_initialize(u8 dev_num, int base_addr) dev->iobase = base_addr; /* Try to detect chip. Will fail if not present. */ - if (smc911x_detect_chip(dev)) { - free(dev); - return 0; + ret = smc911x_detect_chip(dev); + if (ret) { + ret = 0; /* Card not detected is not an error */ + goto err_detect; } addrh = smc911x_get_mac_csr(dev, ADDRH); @@ -279,27 +307,15 @@ int smc911x_initialize(u8 dev_num, int base_addr) eth_register(dev); -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - int retval; - struct mii_dev *mdiodev = mdio_alloc(); - if (!mdiodev) { - eth_unregister(dev); - free(dev); - return -ENOMEM; - } - - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); - mdiodev->read = smc911x_miiphy_read; - mdiodev->write = smc911x_miiphy_write; - - retval = mdio_register(mdiodev); - if (retval < 0) { - mdio_free(mdiodev); - eth_unregister(dev); - free(dev); - return retval; - } -#endif + ret = smc911x_initialize_mii(dev); + if (ret) + goto err_mii; return 1; + +err_mii: + eth_unregister(dev); +err_detect: + free(dev); + return ret; } -- cgit v1.1 From eb46efa381d6dedb03af77d74b896ff40f1591b8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 15:03:07 +0100 Subject: net: smc911x: Inline all functions from header file Inline all the functions from the header file, as they are not used outside of the driver or the standalone EEPROM example. Note that this does introduce considerable amount of duplication in the standalone EEPROM example, however that one has to be rewritten anyway, roughly such that the SMC911x driver would expose DM EEPROM interface and the standalone example would use that. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++- drivers/net/smc911x.h | 157 -------------------------------------------------- 2 files changed, 156 insertions(+), 158 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 65c25f3..ff285f1 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -10,9 +10,165 @@ #include #include #include +#include #include "smc911x.h" +struct chip_id { + u16 id; + char *name; +}; + +static const struct chip_id chip_ids[] = { + { CHIP_89218, "LAN89218" }, + { CHIP_9115, "LAN9115" }, + { CHIP_9116, "LAN9116" }, + { CHIP_9117, "LAN9117" }, + { CHIP_9118, "LAN9118" }, + { CHIP_9211, "LAN9211" }, + { CHIP_9215, "LAN9215" }, + { CHIP_9216, "LAN9216" }, + { CHIP_9217, "LAN9217" }, + { CHIP_9218, "LAN9218" }, + { CHIP_9220, "LAN9220" }, + { CHIP_9221, "LAN9221" }, + { 0, NULL }, +}; + +#define DRIVERNAME "smc911x" + +#if defined (CONFIG_SMC911X_32_BIT) && \ + defined (CONFIG_SMC911X_16_BIT) +#error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \ + CONFIG_SMC911X_16_BIT shall be set" +#endif + +#if defined (CONFIG_SMC911X_32_BIT) +static inline u32 __smc911x_reg_read(struct eth_device *dev, u32 offset) +{ + return *(volatile u32*)(dev->iobase + offset); +} +u32 smc911x_reg_read(struct eth_device *dev, u32 offset) + __attribute__((weak, alias("__smc911x_reg_read"))); + +static inline void __smc911x_reg_write(struct eth_device *dev, + u32 offset, u32 val) +{ + *(volatile u32*)(dev->iobase + offset) = val; +} +void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) + __attribute__((weak, alias("__smc911x_reg_write"))); +#elif defined (CONFIG_SMC911X_16_BIT) +static inline u32 smc911x_reg_read(struct eth_device *dev, u32 offset) +{ + volatile u16 *addr_16 = (u16 *)(dev->iobase + offset); + return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); +} +static inline void smc911x_reg_write(struct eth_device *dev, + u32 offset, u32 val) +{ + *(volatile u16 *)(dev->iobase + offset) = (u16)val; + *(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16); +} +#else +#error "SMC911X: undefined bus width" +#endif /* CONFIG_SMC911X_16_BIT */ + +static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg) +{ + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + ; + smc911x_reg_write(dev, MAC_CSR_CMD, + MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + ; + + return smc911x_reg_read(dev, MAC_CSR_DATA); +} + +static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data) +{ + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + ; + smc911x_reg_write(dev, MAC_CSR_DATA, data); + smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + ; +} + +static int smc911x_detect_chip(struct eth_device *dev) +{ + unsigned long val, i; + + val = smc911x_reg_read(dev, BYTE_TEST); + if (val == 0xffffffff) { + /* Special case -- no chip present */ + return -1; + } else if (val != 0x87654321) { + printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val); + return -1; + } + + val = smc911x_reg_read(dev, ID_REV) >> 16; + for (i = 0; chip_ids[i].id != 0; i++) { + if (chip_ids[i].id == val) break; + } + if (!chip_ids[i].id) { + printf(DRIVERNAME ": Unknown chip ID %04lx\n", val); + return -1; + } + + dev->priv = (void *)&chip_ids[i]; + + return 0; +} + +static void smc911x_reset(struct eth_device *dev) +{ + int timeout; + + /* + * Take out of PM setting first + * Device is already wake up if PMT_CTRL_READY bit is set + */ + if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) { + /* Write to the bytetest will take out of powerdown */ + smc911x_reg_write(dev, BYTE_TEST, 0x0); + + timeout = 10; + + while (timeout-- && + !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY)) + udelay(10); + if (timeout < 0) { + printf(DRIVERNAME + ": timeout waiting for PM restore\n"); + return; + } + } + + /* Disable interrupts */ + smc911x_reg_write(dev, INT_EN, 0); + + smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST); + + timeout = 1000; + while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) + udelay(10); + + if (timeout < 0) { + printf(DRIVERNAME ": reset timeout\n"); + return; + } + + /* Reset the FIFO level and flow control settings */ + smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN); + smc911x_reg_write(dev, AFC_CFG, 0x0050287F); + + /* Set to LED outputs */ + smc911x_reg_write(dev, GPIO_CFG, 0x70070000); +} + static void smc911x_handle_mac_address(struct eth_device *dev) { unsigned long addrh, addrl; @@ -117,7 +273,6 @@ static void smc911x_enable(struct eth_device *dev) smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); - } static int smc911x_init(struct eth_device *dev, bd_t * bd) diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h index 3145fbd..ce66900 100644 --- a/drivers/net/smc911x.h +++ b/drivers/net/smc911x.h @@ -8,47 +8,6 @@ #ifndef _SMC911X_H_ #define _SMC911X_H_ -#include - -#define DRIVERNAME "smc911x" - -#if defined (CONFIG_SMC911X_32_BIT) && \ - defined (CONFIG_SMC911X_16_BIT) -#error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \ - CONFIG_SMC911X_16_BIT shall be set" -#endif - -#if defined (CONFIG_SMC911X_32_BIT) -static inline u32 __smc911x_reg_read(struct eth_device *dev, u32 offset) -{ - return *(volatile u32*)(dev->iobase + offset); -} -u32 smc911x_reg_read(struct eth_device *dev, u32 offset) - __attribute__((weak, alias("__smc911x_reg_read"))); - -static inline void __smc911x_reg_write(struct eth_device *dev, - u32 offset, u32 val) -{ - *(volatile u32*)(dev->iobase + offset) = val; -} -void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) - __attribute__((weak, alias("__smc911x_reg_write"))); -#elif defined (CONFIG_SMC911X_16_BIT) -static inline u32 smc911x_reg_read(struct eth_device *dev, u32 offset) -{ - volatile u16 *addr_16 = (u16 *)(dev->iobase + offset); - return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); -} -static inline void smc911x_reg_write(struct eth_device *dev, - u32 offset, u32 val) -{ - *(volatile u16 *)(dev->iobase + offset) = (u16)val; - *(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16); -} -#else -#error "SMC911X: undefined bus width" -#endif /* CONFIG_SMC911X_16_BIT */ - /* Below are the register offsets and bit definitions * of the Lan911x memory space */ @@ -380,120 +339,4 @@ static inline void smc911x_reg_write(struct eth_device *dev, #define CHIP_9220 0x9220 #define CHIP_9221 0x9221 -struct chip_id { - u16 id; - char *name; -}; - -static const struct chip_id chip_ids[] = { - { CHIP_89218, "LAN89218" }, - { CHIP_9115, "LAN9115" }, - { CHIP_9116, "LAN9116" }, - { CHIP_9117, "LAN9117" }, - { CHIP_9118, "LAN9118" }, - { CHIP_9211, "LAN9211" }, - { CHIP_9215, "LAN9215" }, - { CHIP_9216, "LAN9216" }, - { CHIP_9217, "LAN9217" }, - { CHIP_9218, "LAN9218" }, - { CHIP_9220, "LAN9220" }, - { CHIP_9221, "LAN9221" }, - { 0, NULL }, -}; - -static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg) -{ - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; - smc911x_reg_write(dev, MAC_CSR_CMD, - MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; - - return smc911x_reg_read(dev, MAC_CSR_DATA); -} - -static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data) -{ - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; - smc911x_reg_write(dev, MAC_CSR_DATA, data); - smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; -} - -static int smc911x_detect_chip(struct eth_device *dev) -{ - unsigned long val, i; - - val = smc911x_reg_read(dev, BYTE_TEST); - if (val == 0xffffffff) { - /* Special case -- no chip present */ - return -1; - } else if (val != 0x87654321) { - printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val); - return -1; - } - - val = smc911x_reg_read(dev, ID_REV) >> 16; - for (i = 0; chip_ids[i].id != 0; i++) { - if (chip_ids[i].id == val) break; - } - if (!chip_ids[i].id) { - printf(DRIVERNAME ": Unknown chip ID %04lx\n", val); - return -1; - } - - dev->priv = (void *)&chip_ids[i]; - - return 0; -} - -static void smc911x_reset(struct eth_device *dev) -{ - int timeout; - - /* - * Take out of PM setting first - * Device is already wake up if PMT_CTRL_READY bit is set - */ - if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) { - /* Write to the bytetest will take out of powerdown */ - smc911x_reg_write(dev, BYTE_TEST, 0x0); - - timeout = 10; - - while (timeout-- && - !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY)) - udelay(10); - if (timeout < 0) { - printf(DRIVERNAME - ": timeout waiting for PM restore\n"); - return; - } - } - - /* Disable interrupts */ - smc911x_reg_write(dev, INT_EN, 0); - - smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST); - - timeout = 1000; - while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) - udelay(10); - - if (timeout < 0) { - printf(DRIVERNAME ": reset timeout\n"); - return; - } - - /* Reset the FIFO level and flow control settings */ - smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN); - smc911x_reg_write(dev, AFC_CFG, 0x0050287F); - - /* Set to LED outputs */ - smc911x_reg_write(dev, GPIO_CFG, 0x70070000); -} - #endif -- cgit v1.1 From f0d73f5cd0ec0967fffcdf130a8c016262a216c4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 14:38:59 +0100 Subject: net: smc911x: Drop weak alias from 32bit accessors These accessors are not overridden by any board, and even if they were, this is something which should be handled via DM now, so remove the weak alias option. Moreover, drop the inline keyword, as the compiler can decide better. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index ff285f1..effee53 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -44,28 +44,22 @@ static const struct chip_id chip_ids[] = { #endif #if defined (CONFIG_SMC911X_32_BIT) -static inline u32 __smc911x_reg_read(struct eth_device *dev, u32 offset) +static u32 smc911x_reg_read(struct eth_device *dev, u32 offset) { return *(volatile u32*)(dev->iobase + offset); } -u32 smc911x_reg_read(struct eth_device *dev, u32 offset) - __attribute__((weak, alias("__smc911x_reg_read"))); -static inline void __smc911x_reg_write(struct eth_device *dev, - u32 offset, u32 val) +static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) { *(volatile u32*)(dev->iobase + offset) = val; } -void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) - __attribute__((weak, alias("__smc911x_reg_write"))); #elif defined (CONFIG_SMC911X_16_BIT) -static inline u32 smc911x_reg_read(struct eth_device *dev, u32 offset) +static u32 smc911x_reg_read(struct eth_device *dev, u32 offset) { volatile u16 *addr_16 = (u16 *)(dev->iobase + offset); return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); } -static inline void smc911x_reg_write(struct eth_device *dev, - u32 offset, u32 val) +static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) { *(volatile u16 *)(dev->iobase + offset) = (u16)val; *(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16); -- cgit v1.1 From ba267c781da73ab0df4a7a57c05ef21c19aee609 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 14:42:23 +0100 Subject: net: smc911x: Convert IO accessors to {read,write}{w,l}() Convert the IO accessors to standard ones instead of using volatile void pointers, as those do not cover all the bus access details. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index effee53..364f8c5 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "smc911x.h" @@ -46,23 +47,23 @@ static const struct chip_id chip_ids[] = { #if defined (CONFIG_SMC911X_32_BIT) static u32 smc911x_reg_read(struct eth_device *dev, u32 offset) { - return *(volatile u32*)(dev->iobase + offset); + return readl(dev->iobase + offset); } static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) { - *(volatile u32*)(dev->iobase + offset) = val; + writel(val, dev->iobase + offset); } #elif defined (CONFIG_SMC911X_16_BIT) static u32 smc911x_reg_read(struct eth_device *dev, u32 offset) { - volatile u16 *addr_16 = (u16 *)(dev->iobase + offset); - return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); + return (readw(dev->iobase + offset) & 0xffff) | + (readw(dev->iobase + offset + 2) << 16); } static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) { - *(volatile u16 *)(dev->iobase + offset) = (u16)val; - *(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16); + writew(val & 0xffff, dev->iobase + offset); + writew(val >> 16, dev->iobase + offset + 2); } #else #error "SMC911X: undefined bus width" -- cgit v1.1 From 3dbab926031fe77d794670c05d6c7badcfa77291 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 15:36:09 +0100 Subject: net: smc911x: Pass around driver private data Introduce a private data structure for this driver with embedded struct eth_device and pass it around. This prepares the driver to work with both DM and non-DM systems. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 232 +++++++++++++++++++++++++++----------------------- 1 file changed, 124 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 364f8c5..07066ce 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -20,6 +20,13 @@ struct chip_id { char *name; }; +struct smc911x_priv { + struct eth_device dev; + phys_addr_t iobase; + const struct chip_id *chipid; + unsigned char enetaddr[6]; +}; + static const struct chip_id chip_ids[] = { { CHIP_89218, "LAN89218" }, { CHIP_9115, "LAN9115" }, @@ -45,57 +52,57 @@ static const struct chip_id chip_ids[] = { #endif #if defined (CONFIG_SMC911X_32_BIT) -static u32 smc911x_reg_read(struct eth_device *dev, u32 offset) +static u32 smc911x_reg_read(struct smc911x_priv *priv, u32 offset) { - return readl(dev->iobase + offset); + return readl(priv->iobase + offset); } -static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) +static void smc911x_reg_write(struct smc911x_priv *priv, u32 offset, u32 val) { - writel(val, dev->iobase + offset); + writel(val, priv->iobase + offset); } #elif defined (CONFIG_SMC911X_16_BIT) -static u32 smc911x_reg_read(struct eth_device *dev, u32 offset) +static u32 smc911x_reg_read(struct smc911x_priv *priv, u32 offset) { - return (readw(dev->iobase + offset) & 0xffff) | - (readw(dev->iobase + offset + 2) << 16); + return (readw(priv->iobase + offset) & 0xffff) | + (readw(priv->iobase + offset + 2) << 16); } -static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) +static void smc911x_reg_write(struct smc911x_priv *priv, u32 offset, u32 val) { - writew(val & 0xffff, dev->iobase + offset); - writew(val >> 16, dev->iobase + offset + 2); + writew(val & 0xffff, priv->iobase + offset); + writew(val >> 16, priv->iobase + offset + 2); } #else #error "SMC911X: undefined bus width" #endif /* CONFIG_SMC911X_16_BIT */ -static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg) +static u32 smc911x_get_mac_csr(struct smc911x_priv *priv, u8 reg) { - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - smc911x_reg_write(dev, MAC_CSR_CMD, + smc911x_reg_write(priv, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - return smc911x_reg_read(dev, MAC_CSR_DATA); + return smc911x_reg_read(priv, MAC_CSR_DATA); } -static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data) +static void smc911x_set_mac_csr(struct smc911x_priv *priv, u8 reg, u32 data) { - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - smc911x_reg_write(dev, MAC_CSR_DATA, data); - smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + smc911x_reg_write(priv, MAC_CSR_DATA, data); + smc911x_reg_write(priv, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); + while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; } -static int smc911x_detect_chip(struct eth_device *dev) +static int smc911x_detect_chip(struct smc911x_priv *priv) { unsigned long val, i; - val = smc911x_reg_read(dev, BYTE_TEST); + val = smc911x_reg_read(priv, BYTE_TEST); if (val == 0xffffffff) { /* Special case -- no chip present */ return -1; @@ -104,7 +111,7 @@ static int smc911x_detect_chip(struct eth_device *dev) return -1; } - val = smc911x_reg_read(dev, ID_REV) >> 16; + val = smc911x_reg_read(priv, ID_REV) >> 16; for (i = 0; chip_ids[i].id != 0; i++) { if (chip_ids[i].id == val) break; } @@ -113,12 +120,12 @@ static int smc911x_detect_chip(struct eth_device *dev) return -1; } - dev->priv = (void *)&chip_ids[i]; + priv->chipid = &chip_ids[i]; return 0; } -static void smc911x_reset(struct eth_device *dev) +static void smc911x_reset(struct smc911x_priv *priv) { int timeout; @@ -126,14 +133,14 @@ static void smc911x_reset(struct eth_device *dev) * Take out of PM setting first * Device is already wake up if PMT_CTRL_READY bit is set */ - if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) { + if ((smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY) == 0) { /* Write to the bytetest will take out of powerdown */ - smc911x_reg_write(dev, BYTE_TEST, 0x0); + smc911x_reg_write(priv, BYTE_TEST, 0x0); timeout = 10; while (timeout-- && - !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY)) + !(smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY)) udelay(10); if (timeout < 0) { printf(DRIVERNAME @@ -143,12 +150,12 @@ static void smc911x_reset(struct eth_device *dev) } /* Disable interrupts */ - smc911x_reg_write(dev, INT_EN, 0); + smc911x_reg_write(priv, INT_EN, 0); - smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST); + smc911x_reg_write(priv, HW_CFG, HW_CFG_SRST); timeout = 1000; - while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) + while (timeout-- && smc911x_reg_read(priv, E2P_CMD) & E2P_CMD_EPC_BUSY) udelay(10); if (timeout < 0) { @@ -157,83 +164,83 @@ static void smc911x_reset(struct eth_device *dev) } /* Reset the FIFO level and flow control settings */ - smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN); - smc911x_reg_write(dev, AFC_CFG, 0x0050287F); + smc911x_set_mac_csr(priv, FLOW, FLOW_FCPT | FLOW_FCEN); + smc911x_reg_write(priv, AFC_CFG, 0x0050287F); /* Set to LED outputs */ - smc911x_reg_write(dev, GPIO_CFG, 0x70070000); + smc911x_reg_write(priv, GPIO_CFG, 0x70070000); } -static void smc911x_handle_mac_address(struct eth_device *dev) +static void smc911x_handle_mac_address(struct smc911x_priv *priv) { unsigned long addrh, addrl; - uchar *m = dev->enetaddr; + unsigned char *m = priv->enetaddr; addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24); addrh = m[4] | (m[5] << 8); - smc911x_set_mac_csr(dev, ADDRL, addrl); - smc911x_set_mac_csr(dev, ADDRH, addrh); + smc911x_set_mac_csr(priv, ADDRL, addrl); + smc911x_set_mac_csr(priv, ADDRH, addrh); printf(DRIVERNAME ": MAC %pM\n", m); } -static int smc911x_eth_phy_read(struct eth_device *dev, +static int smc911x_eth_phy_read(struct smc911x_priv *priv, u8 phy, u8 reg, u16 *val) { - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) + while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY) ; - smc911x_set_mac_csr(dev, MII_ACC, phy << 11 | reg << 6 | + smc911x_set_mac_csr(priv, MII_ACC, phy << 11 | reg << 6 | MII_ACC_MII_BUSY); - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) + while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY) ; - *val = smc911x_get_mac_csr(dev, MII_DATA); + *val = smc911x_get_mac_csr(priv, MII_DATA); return 0; } -static int smc911x_eth_phy_write(struct eth_device *dev, +static int smc911x_eth_phy_write(struct smc911x_priv *priv, u8 phy, u8 reg, u16 val) { - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) + while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY) ; - smc911x_set_mac_csr(dev, MII_DATA, val); - smc911x_set_mac_csr(dev, MII_ACC, + smc911x_set_mac_csr(priv, MII_DATA, val); + smc911x_set_mac_csr(priv, MII_ACC, phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE); - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) + while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY) ; return 0; } -static int smc911x_phy_reset(struct eth_device *dev) +static int smc911x_phy_reset(struct smc911x_priv *priv) { u32 reg; - reg = smc911x_reg_read(dev, PMT_CTRL); + reg = smc911x_reg_read(priv, PMT_CTRL); reg &= ~0xfffff030; reg |= PMT_CTRL_PHY_RST; - smc911x_reg_write(dev, PMT_CTRL, reg); + smc911x_reg_write(priv, PMT_CTRL, reg); mdelay(100); return 0; } -static void smc911x_phy_configure(struct eth_device *dev) +static void smc911x_phy_configure(struct smc911x_priv *priv) { int timeout; u16 status; - smc911x_phy_reset(dev); + smc911x_phy_reset(priv); - smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_RESET); + smc911x_eth_phy_write(priv, 1, MII_BMCR, BMCR_RESET); mdelay(1); - smc911x_eth_phy_write(dev, 1, MII_ADVERTISE, 0x01e1); - smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_ANENABLE | + smc911x_eth_phy_write(priv, 1, MII_ADVERTISE, 0x01e1); + smc911x_eth_phy_write(priv, 1, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); timeout = 5000; @@ -242,7 +249,7 @@ static void smc911x_phy_configure(struct eth_device *dev) if ((timeout--) == 0) goto err_out; - if (smc911x_eth_phy_read(dev, 1, MII_BMSR, &status) != 0) + if (smc911x_eth_phy_read(priv, 1, MII_BMSR, &status) != 0) goto err_out; } while (!(status & BMSR_LSTATUS)); @@ -254,64 +261,66 @@ err_out: printf(DRIVERNAME ": autonegotiation timed out\n"); } -static void smc911x_enable(struct eth_device *dev) +static void smc911x_enable(struct smc911x_priv *priv) { /* Enable TX */ - smc911x_reg_write(dev, HW_CFG, 8 << 16 | HW_CFG_SF); + smc911x_reg_write(priv, HW_CFG, 8 << 16 | HW_CFG_SF); - smc911x_reg_write(dev, GPT_CFG, GPT_CFG_TIMER_EN | 10000); + smc911x_reg_write(priv, GPT_CFG, GPT_CFG_TIMER_EN | 10000); - smc911x_reg_write(dev, TX_CFG, TX_CFG_TX_ON); + smc911x_reg_write(priv, TX_CFG, TX_CFG_TX_ON); /* no padding to start of packets */ - smc911x_reg_write(dev, RX_CFG, 0); + smc911x_reg_write(priv, RX_CFG, 0); - smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | + smc911x_set_mac_csr(priv, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); } static int smc911x_init(struct eth_device *dev, bd_t * bd) { - struct chip_id *id = dev->priv; + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); + const struct chip_id *id = priv->chipid; printf(DRIVERNAME ": detected %s controller\n", id->name); - smc911x_reset(dev); + smc911x_reset(priv); /* Configure the PHY, initialize the link state */ - smc911x_phy_configure(dev); + smc911x_phy_configure(priv); - smc911x_handle_mac_address(dev); + smc911x_handle_mac_address(priv); /* Turn on Tx + Rx */ - smc911x_enable(dev); + smc911x_enable(priv); return 0; } static int smc911x_send(struct eth_device *dev, void *packet, int length) { + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); u32 *data = (u32*)packet; u32 tmplen; u32 status; - smc911x_reg_write(dev, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | + smc911x_reg_write(priv, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); - smc911x_reg_write(dev, TX_DATA_FIFO, length); + smc911x_reg_write(priv, TX_DATA_FIFO, length); tmplen = (length + 3) / 4; while (tmplen--) - smc911x_reg_write(dev, TX_DATA_FIFO, *data++); + smc911x_reg_write(priv, TX_DATA_FIFO, *data++); /* wait for transmission */ - while (!((smc911x_reg_read(dev, TX_FIFO_INF) & + while (!((smc911x_reg_read(priv, TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16)); /* get status. Ignore 'no carrier' error, it has no meaning for * full duplex operation */ - status = smc911x_reg_read(dev, TX_STATUS_FIFO) & + status = smc911x_reg_read(priv, TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL | TX_STS_MANY_DEFER | TX_STS_UNDERRUN); @@ -330,25 +339,28 @@ static int smc911x_send(struct eth_device *dev, void *packet, int length) static void smc911x_halt(struct eth_device *dev) { - smc911x_reset(dev); - smc911x_handle_mac_address(dev); + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); + + smc911x_reset(priv); + smc911x_handle_mac_address(priv); } static int smc911x_recv(struct eth_device *dev) { + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); u32 *data = (u32 *)net_rx_packets[0]; u32 pktlen, tmplen; u32 status; - if ((smc911x_reg_read(dev, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { - status = smc911x_reg_read(dev, RX_STATUS_FIFO); + if ((smc911x_reg_read(priv, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { + status = smc911x_reg_read(priv, RX_STATUS_FIFO); pktlen = (status & RX_STS_PKT_LEN) >> 16; - smc911x_reg_write(dev, RX_CFG, 0); + smc911x_reg_write(priv, RX_CFG, 0); tmplen = (pktlen + 3) / 4; while (tmplen--) - *data++ = smc911x_reg_read(dev, RX_DATA_FIFO); + *data++ = smc911x_reg_read(priv, RX_DATA_FIFO); if (status & RX_STS_ES) printf(DRIVERNAME @@ -367,31 +379,34 @@ static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad, int reg) { struct eth_device *dev = eth_get_dev_by_name(bus->name); + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); u16 val = 0; int ret; - if (!dev) + if (!dev || !priv) return -ENODEV; - ret = smc911x_eth_phy_read(dev, phy, reg, &val); + ret = smc911x_eth_phy_read(priv, phy, reg, &val); if (ret < 0) return ret; return val; } + /* wrapper for smc911x_eth_phy_write */ static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad, int reg, u16 val) { struct eth_device *dev = eth_get_dev_by_name(bus->name); + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); - if (!dev) + if (!dev || !priv) return -ENODEV; - return smc911x_eth_phy_write(dev, phy, reg, val); + return smc911x_eth_phy_write(priv, phy, reg, val); } -static int smc911x_initialize_mii(struct eth_device *dev) +static int smc911x_initialize_mii(struct smc911x_priv *priv) { struct mii_dev *mdiodev = mdio_alloc(); int ret; @@ -399,7 +414,7 @@ static int smc911x_initialize_mii(struct eth_device *dev) if (!mdiodev) return -ENOMEM; - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + strncpy(mdiodev->name, priv->dev.name, MDIO_NAME_LEN); mdiodev->read = smc911x_miiphy_read; mdiodev->write = smc911x_miiphy_write; @@ -412,7 +427,7 @@ static int smc911x_initialize_mii(struct eth_device *dev) return 0; } #else -static int smc911x_initialize_mii(struct eth_device *dev) +static int smc911x_initialize_mii(struct smc911x_priv *priv) { return 0; } @@ -421,51 +436,52 @@ static int smc911x_initialize_mii(struct eth_device *dev) int smc911x_initialize(u8 dev_num, int base_addr) { unsigned long addrl, addrh; - struct eth_device *dev; + struct smc911x_priv *priv; int ret; - dev = calloc(1, sizeof(*dev)); - if (!dev) + priv = calloc(1, sizeof(*priv)); + if (!priv) return -ENOMEM; - dev->iobase = base_addr; + priv->iobase = base_addr; + priv->dev.iobase = base_addr; /* Try to detect chip. Will fail if not present. */ - ret = smc911x_detect_chip(dev); + ret = smc911x_detect_chip(priv); if (ret) { ret = 0; /* Card not detected is not an error */ goto err_detect; } - addrh = smc911x_get_mac_csr(dev, ADDRH); - addrl = smc911x_get_mac_csr(dev, ADDRL); + addrh = smc911x_get_mac_csr(priv, ADDRH); + addrl = smc911x_get_mac_csr(priv, ADDRL); if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) { /* address is obtained from optional eeprom */ - dev->enetaddr[0] = addrl; - dev->enetaddr[1] = addrl >> 8; - dev->enetaddr[2] = addrl >> 16; - dev->enetaddr[3] = addrl >> 24; - dev->enetaddr[4] = addrh; - dev->enetaddr[5] = addrh >> 8; + priv->enetaddr[0] = addrl; + priv->enetaddr[1] = addrl >> 8; + priv->enetaddr[2] = addrl >> 16; + priv->enetaddr[3] = addrl >> 24; + priv->enetaddr[4] = addrh; + priv->enetaddr[5] = addrh >> 8; } - dev->init = smc911x_init; - dev->halt = smc911x_halt; - dev->send = smc911x_send; - dev->recv = smc911x_recv; - sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num); + priv->dev.init = smc911x_init; + priv->dev.halt = smc911x_halt; + priv->dev.send = smc911x_send; + priv->dev.recv = smc911x_recv; + sprintf(priv->dev.name, "%s-%hu", DRIVERNAME, dev_num); - eth_register(dev); + eth_register(&priv->dev); - ret = smc911x_initialize_mii(dev); + ret = smc911x_initialize_mii(priv); if (ret) goto err_mii; return 1; err_mii: - eth_unregister(dev); + eth_unregister(&priv->dev); err_detect: - free(dev); + free(priv); return ret; } -- cgit v1.1 From b11c8bbfafa998e90fe93ab4e9b08c1a4959bd65 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 17:02:05 +0100 Subject: net: smc911x: Clean up the status handling in smc911x_recv() Invert the status handling logic in smc911x_recv(), to make the function easier to read, no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/smc911x.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 07066ce..2d1a9e0 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -352,23 +352,25 @@ static int smc911x_recv(struct eth_device *dev) u32 pktlen, tmplen; u32 status; - if ((smc911x_reg_read(priv, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { - status = smc911x_reg_read(priv, RX_STATUS_FIFO); - pktlen = (status & RX_STS_PKT_LEN) >> 16; + status = smc911x_reg_read(priv, RX_FIFO_INF); + if (!(status & RX_FIFO_INF_RXSUSED)) + return 0; - smc911x_reg_write(priv, RX_CFG, 0); + status = smc911x_reg_read(priv, RX_STATUS_FIFO); + pktlen = (status & RX_STS_PKT_LEN) >> 16; - tmplen = (pktlen + 3) / 4; - while (tmplen--) - *data++ = smc911x_reg_read(priv, RX_DATA_FIFO); + smc911x_reg_write(priv, RX_CFG, 0); - if (status & RX_STS_ES) - printf(DRIVERNAME - ": dropped bad packet. Status: 0x%08x\n", - status); - else - net_process_received_packet(net_rx_packets[0], pktlen); - } + tmplen = (pktlen + 3) / 4; + while (tmplen--) + *data++ = smc911x_reg_read(priv, RX_DATA_FIFO); + + if (status & RX_STS_ES) + printf(DRIVERNAME + ": dropped bad packet. Status: 0x%08x\n", + status); + else + net_process_received_packet(net_rx_packets[0], pktlen); return 0; } -- cgit v1.1 From 8eb4fef11b5420020518486ef0305aada0a02467 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 17:25:27 +0100 Subject: net: smc911x: Split non-DM specific bits from common code Split network handling functions into non-DM specific parts and common code in preparation for conversion to DM. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada Acked-by: Joe Hershberger --- drivers/net/smc911x.c | 57 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 2d1a9e0..95f955f 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -277,9 +277,8 @@ static void smc911x_enable(struct smc911x_priv *priv) MAC_CR_HBDIS); } -static int smc911x_init(struct eth_device *dev, bd_t * bd) +static int smc911x_init_common(struct smc911x_priv *priv) { - struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); const struct chip_id *id = priv->chipid; printf(DRIVERNAME ": detected %s controller\n", id->name); @@ -297,9 +296,9 @@ static int smc911x_init(struct eth_device *dev, bd_t * bd) return 0; } -static int smc911x_send(struct eth_device *dev, void *packet, int length) +static int smc911x_send_common(struct smc911x_priv *priv, + void *packet, int length) { - struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); u32 *data = (u32*)packet; u32 tmplen; u32 status; @@ -337,18 +336,14 @@ static int smc911x_send(struct eth_device *dev, void *packet, int length) return -1; } -static void smc911x_halt(struct eth_device *dev) +static void smc911x_halt_common(struct smc911x_priv *priv) { - struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); - smc911x_reset(priv); smc911x_handle_mac_address(priv); } -static int smc911x_recv(struct eth_device *dev) +static int smc911x_recv_common(struct smc911x_priv *priv, u32 *data) { - struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); - u32 *data = (u32 *)net_rx_packets[0]; u32 pktlen, tmplen; u32 status; @@ -365,14 +360,14 @@ static int smc911x_recv(struct eth_device *dev) while (tmplen--) *data++ = smc911x_reg_read(priv, RX_DATA_FIFO); - if (status & RX_STS_ES) + if (status & RX_STS_ES) { printf(DRIVERNAME ": dropped bad packet. Status: 0x%08x\n", status); - else - net_process_received_packet(net_rx_packets[0], pktlen); + return 0; + } - return 0; + return pktlen; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) @@ -435,6 +430,40 @@ static int smc911x_initialize_mii(struct smc911x_priv *priv) } #endif +static int smc911x_init(struct eth_device *dev, bd_t *bd) +{ + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); + + return smc911x_init_common(priv); +} + +static void smc911x_halt(struct eth_device *dev) +{ + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); + + smc911x_halt_common(priv); +} + +static int smc911x_send(struct eth_device *dev, void *packet, int length) +{ + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); + + return smc911x_send_common(priv, packet, length); +} + +static int smc911x_recv(struct eth_device *dev) +{ + struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev); + u32 *data = (u32 *)net_rx_packets[0]; + int ret; + + ret = smc911x_recv_common(priv, data); + if (ret) + net_process_received_packet(net_rx_packets[0], ret); + + return ret; +} + int smc911x_initialize(u8 dev_num, int base_addr) { unsigned long addrl, addrh; -- cgit v1.1 From 8148693b988fb36463dbc12cef4b7947acae9846 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Mar 2020 17:39:01 +0100 Subject: net: smc911x: Add DM support Add support for U-Boot DM and DT probing. Furthermore, build the SMC911x standalone EEPROM example only for the non-DM case, as it is not converted yet. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Masahiro Yamada --- drivers/net/Kconfig | 2 + drivers/net/smc911x.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index bc518f2..a2587a2 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -388,11 +388,13 @@ config SMC911X if SMC911X +if !DM_ETH config SMC911X_BASE hex "SMC911X Base Address" help Define this to hold the physical address of the device (I/O space) +endif #DM_ETH choice prompt "SMC911X bus width" diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 95f955f..45ecd6a 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -21,7 +21,9 @@ struct chip_id { }; struct smc911x_priv { +#ifndef CONFIG_DM_ETH struct eth_device dev; +#endif phys_addr_t iobase; const struct chip_id *chipid; unsigned char enetaddr[6]; @@ -370,6 +372,8 @@ static int smc911x_recv_common(struct smc911x_priv *priv, u32 *data) return pktlen; } +#ifndef CONFIG_DM_ETH + #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) /* wrapper for smc911x_eth_phy_read */ static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad, @@ -494,6 +498,7 @@ int smc911x_initialize(u8 dev_num, int base_addr) priv->enetaddr[3] = addrl >> 24; priv->enetaddr[4] = addrh; priv->enetaddr[5] = addrh >> 8; + memcpy(priv->dev.enetaddr, priv->enetaddr, 6); } priv->dev.init = smc911x_init; @@ -516,3 +521,113 @@ err_detect: free(priv); return ret; } + +#else /* ifdef CONFIG_DM_ETH */ + +static int smc911x_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct smc911x_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + return smc911x_init_common(priv); +} + +static void smc911x_stop(struct udevice *dev) +{ + struct smc911x_priv *priv = dev_get_priv(dev); + + smc911x_halt_common(priv); +} + +static int smc911x_send(struct udevice *dev, void *packet, int length) +{ + struct smc911x_priv *priv = dev_get_priv(dev); + int ret; + + ret = smc911x_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int smc911x_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct smc911x_priv *priv = dev_get_priv(dev); + u32 *data = (u32 *)net_rx_packets[0]; + int ret; + + ret = smc911x_recv_common(priv, data); + if (ret) + *packetp = (void *)data; + + return ret ? ret : -EAGAIN; +} + +static int smc911x_bind(struct udevice *dev) +{ + return device_set_name(dev, dev->name); +} + +static int smc911x_probe(struct udevice *dev) +{ + struct smc911x_priv *priv = dev_get_priv(dev); + unsigned long addrh, addrl; + int ret; + + /* Try to detect chip. Will fail if not present. */ + ret = smc911x_detect_chip(priv); + if (ret) + return ret; + + addrh = smc911x_get_mac_csr(priv, ADDRH); + addrl = smc911x_get_mac_csr(priv, ADDRL); + if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) { + /* address is obtained from optional eeprom */ + priv->enetaddr[0] = addrl; + priv->enetaddr[1] = addrl >> 8; + priv->enetaddr[2] = addrl >> 16; + priv->enetaddr[3] = addrl >> 24; + priv->enetaddr[4] = addrh; + priv->enetaddr[5] = addrh >> 8; + } + + return 0; +} + +static int smc911x_ofdata_to_platdata(struct udevice *dev) +{ + struct smc911x_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + + pdata->iobase = devfdt_get_addr(dev); + priv->iobase = pdata->iobase; + + return 0; +} + +static const struct eth_ops smc911x_ops = { + .start = smc911x_start, + .send = smc911x_send, + .recv = smc911x_recv, + .stop = smc911x_stop, +}; + +static const struct udevice_id smc911x_ids[] = { + { .compatible = "smsc,lan9115" }, + { } +}; + +U_BOOT_DRIVER(smc911x) = { + .name = "eth_smc911x", + .id = UCLASS_ETH, + .of_match = smc911x_ids, + .bind = smc911x_bind, + .ofdata_to_platdata = smc911x_ofdata_to_platdata, + .probe = smc911x_probe, + .ops = &smc911x_ops, + .priv_auto_alloc_size = sizeof(struct smc911x_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif -- cgit v1.1