[U-Boot] [PATCH V2 0/5] DM9000 support for multiple interfaces

This is a rework of the DM9000 driver to support registering interfaces dynamically (i.e. determine how many ethernet chips we have at boot and register 0, 1, 2, or more). It was tested on a yet-to-be-submitted board which is based on the PXA270 + 0, 1, or 2 DM9000 chips.
To maintain backwards compatibility with older board files, we add a new initialize function taking the io address, data address, and availability of a SROM chip. The old initialize function is now a shim around this new initialize function but provides the parameters based on the old DM9000 preprocessor symbols.
I have compile-tested this on the following:
at91sam9261ek_dataflash_cs0_defconfig davinci_dm355evm_defconfig davinci_dm355leopard_defconfig lp8x4x_defconfig pm9261_defconfig scb9328_defconfig devkit8000_defconfig colibri_pxa270_defconfig trizepsiv_defconfig vpac270_nor_128_defconfig
I have not compile-tested the following:
M5253DEMO ip04
I have board tested this on a yet-to-be-upstreamed port of a pxa270 board that reads an i2c eeprom to determine which (and how many) ethernet chips are enabled.
Cc: Joe Hershberger joe.hershberger@gmail.com
Andrew Ruder (5): dm9000: whitespace cleanups dm9000: mark dump_regs() function as unused dm9000: Add struct eth_device * to SROM functions dm9000: dm9000_initialize stub dm9000: rework dm9000 to support multiple devices
board/altera/nios2-generic/nios2-generic.c | 3 +- board/atmel/at91sam9261ek/at91sam9261ek.c | 2 +- board/davinci/dm355evm/dm355evm.c | 2 +- board/davinci/dm355leopard/dm355leopard.c | 2 +- board/freescale/m5253demo/m5253demo.c | 2 +- board/icpdas/lp8x4x/lp8x4x.c | 2 +- board/ip04/ip04.c | 2 +- board/ronetix/pm9261/pm9261.c | 2 +- board/scb9328/scb9328.c | 2 +- board/timll/devkit8000/devkit8000.c | 2 +- board/toradex/colibri_pxa270/colibri_pxa270.c | 2 +- board/trizepsiv/conxs.c | 2 +- board/trizepsiv/eeprom.c | 5 +- board/vpac270/vpac270.c | 2 +- drivers/net/dm9000x.c | 457 +++++++++++++++----------- include/configs/M5253DEMO.h | 1 + include/configs/at91sam9261ek.h | 3 +- include/configs/colibri_pxa270.h | 1 + include/configs/davinci_dm355evm.h | 1 + include/configs/davinci_dm355leopard.h | 1 + include/configs/devkit8000.h | 3 +- include/configs/ip04.h | 2 +- include/configs/lp8x4x.h | 2 + include/configs/pm9261.h | 2 +- include/configs/scb9328.h | 1 + include/configs/trizepsiv.h | 1 + include/configs/vpac270.h | 1 + include/dm9000.h | 8 +- include/netdev.h | 2 +- 29 files changed, 290 insertions(+), 228 deletions(-)

Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com --- drivers/net/dm9000x.c | 108 ++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 56 deletions(-)
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 3c41cec..415c4b7 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -29,7 +29,7 @@ v1.2 03/18/2003 Weilun Huang weilun_huang@davicom.com.tw: --------------------------------------
12/15/2003 Initial port to u-boot by - Sascha Hauer saschahauer@web.de + Sascha Hauer saschahauer@web.de
06/03/2008 Remy Bohmer linux@bohmer.net - Fixed the driver to work with DM9000A. @@ -46,7 +46,6 @@ v1.2 03/18/2003 Weilun Huang weilun_huang@davicom.com.tw: - some minor code cleanups These changes are tested with DM9000{A,EP,E} together with a 200MHz Atmel AT91SAM9261 core - TODO: external MII is not functional, only internal at the moment. */
@@ -63,20 +62,20 @@ TODO: external MII is not functional, only internal at the moment. /* #define CONFIG_DM9000_DEBUG */
#ifdef CONFIG_DM9000_DEBUG -#define DM9000_DBG(fmt,args...) printf(fmt, ##args) -#define DM9000_DMP_PACKET(func,packet,length) \ +#define DM9000_DBG(fmt, args...) printf(fmt, ##args) +#define DM9000_DMP_PACKET(func, packet, length) \ do { \ - int i; \ + int i; \ printf("%s: length: %d\n", func, length); \ for (i = 0; i < length; i++) { \ if (i % 8 == 0) \ printf("\n%s: %02x: ", func, i); \ - printf("%02x ", ((unsigned char *) packet)[i]); \ + printf("%02x ", ((unsigned char *)packet)[i]); \ } printf("\n"); \ - } while(0) + } while (0) #else -#define DM9000_DBG(fmt,args...) -#define DM9000_DMP_PACKET(func,packet,length) +#define DM9000_DBG(fmt, args...) do {} while (0) +#define DM9000_DMP_PACKET(func, packet, length) do {} while (0) #endif
/* Structure/enum declaration ------------------------------- */ @@ -92,9 +91,9 @@ typedef struct board_info { u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128]; - void (*outblk)(volatile void *data_ptr, int count); + void (*outblk)(void *data_ptr, int count); void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *RxStatus, u16 *RxLen); + void (*rx_status)(u16 *rx_status, u16 *rx_len); struct eth_device netdev; } board_info_t; static board_info_t dm9000_info; @@ -109,12 +108,12 @@ static void DM9000_iow(int reg, u8 value);
/* DM9000 network board routine ---------------------------- */ #ifndef CONFIG_DM9000_BYTE_SWAPPED -#define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r)) -#define DM9000_outw(d,r) writew(d, (volatile u16 *)(r)) -#define DM9000_outl(d,r) writel(d, (volatile u32 *)(r)) -#define DM9000_inb(r) readb((volatile u8 *)(r)) -#define DM9000_inw(r) readw((volatile u16 *)(r)) -#define DM9000_inl(r) readl((volatile u32 *)(r)) +#define DM9000_outb(d, r) writeb(d, (u8 *)(r)) +#define DM9000_outw(d, r) writew(d, (u16 *)(r)) +#define DM9000_outl(d, r) writel(d, (u32 *)(r)) +#define DM9000_inb(r) readb((u8 *)(r)) +#define DM9000_inw(r) readw((u16 *)(r)) +#define DM9000_inl(r) readl((u32 *)(r)) #else #define DM9000_outb(d, r) __raw_writeb(d, r) #define DM9000_outw(d, r) __raw_writew(d, r) @@ -141,35 +140,35 @@ dump_regs(void) } #endif
-static void dm9000_outblk_8bit(volatile void *data_ptr, int count) +static void dm9000_outblk_8bit(void *data_ptr, int count) { int i; for (i = 0; i < count; i++) - DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA); + DM9000_outb((((u8 *)data_ptr)[i] & 0xff), DM9000_DATA); }
-static void dm9000_outblk_16bit(volatile void *data_ptr, int count) +static void dm9000_outblk_16bit(void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2;
for (i = 0; i < tmplen; i++) - DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); + DM9000_outw(((u16 *)data_ptr)[i], DM9000_DATA); } -static void dm9000_outblk_32bit(volatile void *data_ptr, int count) +static void dm9000_outblk_32bit(void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4;
for (i = 0; i < tmplen; i++) - DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); + DM9000_outl(((u32 *)data_ptr)[i], DM9000_DATA); }
static void dm9000_inblk_8bit(void *data_ptr, int count) { int i; for (i = 0; i < count; i++) - ((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA); + ((u8 *)data_ptr)[i] = DM9000_inb(DM9000_DATA); }
static void dm9000_inblk_16bit(void *data_ptr, int count) @@ -178,7 +177,7 @@ static void dm9000_inblk_16bit(void *data_ptr, int count) u32 tmplen = (count + 1) / 2;
for (i = 0; i < tmplen; i++) - ((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA); + ((u16 *)data_ptr)[i] = DM9000_inw(DM9000_DATA); } static void dm9000_inblk_32bit(void *data_ptr, int count) { @@ -186,36 +185,36 @@ static void dm9000_inblk_32bit(void *data_ptr, int count) u32 tmplen = (count + 3) / 4;
for (i = 0; i < tmplen; i++) - ((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA); + ((u32 *)data_ptr)[i] = DM9000_inl(DM9000_DATA); }
-static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen) +static void dm9000_rx_status_32bit(u16 *rx_status, u16 *rx_len) { u32 tmpdata;
DM9000_outb(DM9000_MRCMD, DM9000_IO);
tmpdata = DM9000_inl(DM9000_DATA); - *RxStatus = __le16_to_cpu(tmpdata); - *RxLen = __le16_to_cpu(tmpdata >> 16); + *rx_status = __le16_to_cpu(tmpdata); + *rx_len = __le16_to_cpu(tmpdata >> 16); }
-static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen) +static void dm9000_rx_status_16bit(u16 *rx_status, u16 *rx_len) { DM9000_outb(DM9000_MRCMD, DM9000_IO);
- *RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA)); - *RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA)); + *rx_status = __le16_to_cpu(DM9000_inw(DM9000_DATA)); + *rx_len = __le16_to_cpu(DM9000_inw(DM9000_DATA)); }
-static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen) +static void dm9000_rx_status_8bit(u16 *rx_status, u16 *rx_len) { DM9000_outb(DM9000_MRCMD, DM9000_IO);
- *RxStatus = + *rx_status = __le16_to_cpu(DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8)); - *RxLen = + *rx_len = __le16_to_cpu(DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8)); } @@ -232,7 +231,7 @@ dm9000_probe(void) id_val |= DM9000_ior(DM9000_PIDL) << 16; id_val |= DM9000_ior(DM9000_PIDH) << 24; if (id_val == DM9000_ID) { - printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE, + printf("dm9000 i/o: 0x%x, id: 0x%x\n", CONFIG_DM9000_BASE, id_val); return 0; } else { @@ -264,7 +263,8 @@ dm9000_reset(void) } while (DM9000_ior(DM9000_NCR) & 1);
DM9000_iow(DM9000_NCR, 0); - DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */ + /* Issue a second reset */ + DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
do { DM9000_DBG("resetting the DM9000, 2nd reset\n"); @@ -425,8 +425,8 @@ static int dm9000_send(struct eth_device *netdev, void *packet, int length)
/* wait for end of transmission */ tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; - while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || - !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { + while (!(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || + !(DM9000_ior(DM9000_ISR) & IMR_PTM)) { if (get_timer(0) >= tmo) { printf("transmission timeout\n"); break; @@ -460,7 +460,7 @@ static int dm9000_rx(struct eth_device *netdev) { u8 rxbyte; u8 *rdptr = (u8 *)net_rx_packets[0]; - u16 RxStatus, RxLen = 0; + u16 rx_status, rx_len = 0; struct board_info *db = &dm9000_info;
/* Check packet ready or not, we must check @@ -483,7 +483,7 @@ static int dm9000_rx(struct eth_device *netdev) DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ printf("DM9000 error: status check fail: 0x%x\n", - rxbyte); + rxbyte); return 0; }
@@ -493,34 +493,31 @@ static int dm9000_rx(struct eth_device *netdev) DM9000_DBG("receiving packet\n");
/* A packet ready now & Get status/length */ - (db->rx_status)(&RxStatus, &RxLen); + (db->rx_status)(&rx_status, &rx_len);
- DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); + DM9000_DBG("rx status: 0x%04x rx len: %d\n", rx_status, rx_len);
/* Move data from DM9000 */ /* Read received packet from RX SRAM */ - (db->inblk)(rdptr, RxLen); + (db->inblk)(rdptr, rx_len);
- if ((RxStatus & 0xbf00) || (RxLen < 0x40) - || (RxLen > DM9000_PKT_MAX)) { - if (RxStatus & 0x100) { + if ((rx_status & 0xbf00) || (rx_len < 0x40) || + (rx_len > DM9000_PKT_MAX)) { + if (rx_status & 0x100) printf("rx fifo error\n"); - } - if (RxStatus & 0x200) { + if (rx_status & 0x200) printf("rx crc error\n"); - } - if (RxStatus & 0x8000) { + if (rx_status & 0x8000) printf("rx length error\n"); - } - if (RxLen > DM9000_PKT_MAX) { + if (rx_len > DM9000_PKT_MAX) { printf("rx length too big\n"); dm9000_reset(); } } else { - DM9000_DMP_PACKET(__func__ , rdptr, RxLen); + DM9000_DMP_PACKET(__func__ , rdptr, rx_len);
DM9000_DBG("passing packet to upper layer\n"); - net_process_received_packet(net_rx_packets[0], RxLen); + net_process_received_packet(net_rx_packets[0], rx_len); } } return 0; @@ -606,7 +603,6 @@ dm9000_phy_read(int reg) static void dm9000_phy_write(int reg, u16 value) { - /* Fill the phyxcer register into REG_0C */ DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);

Hi Andrew,
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

dump_regs() is a handy function to keep around for bringing up a new dm9000-based board, but defining CONFIG_DM9000_DEBUG only adds the function - nowhere currently uses it. Rather than remove a potentially useful function, let's just tell gcc to not emit a warning when it is unused.
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com --- drivers/net/dm9000x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 415c4b7..258c8a3 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -54,6 +54,7 @@ TODO: external MII is not functional, only internal at the moment. #include <net.h> #include <asm/io.h> #include <dm9000.h> +#include <linux/compiler.h>
#include "dm9000x.h"
@@ -124,7 +125,7 @@ static void DM9000_iow(int reg, u8 value); #endif
#ifdef CONFIG_DM9000_DEBUG -static void +static __maybe_unused void dump_regs(void) { DM9000_DBG("\n");

Hi Andrew,
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
dump_regs() is a handy function to keep around for bringing up a new dm9000-based board, but defining CONFIG_DM9000_DEBUG only adds the function - nowhere currently uses it. Rather than remove a potentially useful function, let's just tell gcc to not emit a warning when it is unused.
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

Currently this argument is not used. To eventually support multiple DM9000's these public-facing functions will need a new argument - the ethernet device. Fix-up the one board using this part of the DM9000 API. Compile-tested only.
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com --- board/trizepsiv/eeprom.c | 5 +++-- drivers/net/dm9000x.c | 6 +++--- include/dm9000.h | 6 ++++-- 3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/board/trizepsiv/eeprom.c b/board/trizepsiv/eeprom.c index 1318edc..d9045dd 100644 --- a/board/trizepsiv/eeprom.c +++ b/board/trizepsiv/eeprom.c @@ -8,6 +8,7 @@ #include <common.h> #include <command.h> #include <dm9000.h> +#include <net.h>
static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int i; @@ -16,7 +17,7 @@ static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * for (i=0; i < 0x40; i++) { if (!(i % 0x10)) printf("\n%08x:", i); - dm9000_read_srom_word(i, data); + dm9000_read_srom_word(eth_get_dev_by_index(0), i, data); printf(" %02x%02x", data[1], data[0]); } printf ("\n"); @@ -35,7 +36,7 @@ static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * printf("Wrong offset : 0x%x\n",offset); return cmd_usage(cmdtp); } - dm9000_write_srom_word(offset, value); + dm9000_write_srom_word(eth_get_dev_by_index(0), offset, value); return (0); }
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 258c8a3..e1a10b5 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -528,7 +528,7 @@ static int dm9000_rx(struct eth_device *netdev) Read a word data from SROM */ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_read_srom_word(int offset, u8 *to) +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPCR, 0x4); @@ -538,7 +538,7 @@ void dm9000_read_srom_word(int offset, u8 *to) to[1] = DM9000_ior(DM9000_EPDRH); }
-void dm9000_write_srom_word(int offset, u16 val) +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); @@ -554,7 +554,7 @@ static void dm9000_get_enetaddr(struct eth_device *dev) #if !defined(CONFIG_DM9000_NO_SROM) int i; for (i = 0; i < 3; i++) - dm9000_read_srom_word(i, dev->enetaddr + (2 * i)); + dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i)); #endif }
diff --git a/include/dm9000.h b/include/dm9000.h index 42b04fa..7a7e629 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -10,8 +10,10 @@
/****************** function prototypes **********************/ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); +struct eth_device; + +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to); #endif
#endif /* __DM9000_H__ */

Hi Andrew,
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
Currently this argument is not used. To eventually support multiple DM9000's these public-facing functions will need a new argument - the ethernet device. Fix-up the one board using this part of the DM9000 API. Compile-tested only.
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com
board/trizepsiv/eeprom.c | 5 +++-- drivers/net/dm9000x.c | 6 +++--- include/dm9000.h | 6 ++++-- 3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/board/trizepsiv/eeprom.c b/board/trizepsiv/eeprom.c index 1318edc..d9045dd 100644 --- a/board/trizepsiv/eeprom.c +++ b/board/trizepsiv/eeprom.c @@ -8,6 +8,7 @@ #include <common.h> #include <command.h> #include <dm9000.h> +#include <net.h>
static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int i; @@ -16,7 +17,7 @@ static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * for (i=0; i < 0x40; i++) { if (!(i % 0x10)) printf("\n%08x:", i);
dm9000_read_srom_word(i, data);
dm9000_read_srom_word(eth_get_dev_by_index(0), i, data); printf(" %02x%02x", data[1], data[0]); } printf ("\n");
@@ -35,7 +36,7 @@ static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * printf("Wrong offset : 0x%x\n",offset); return cmd_usage(cmdtp); }
dm9000_write_srom_word(offset, value);
dm9000_write_srom_word(eth_get_dev_by_index(0), offset, value); return (0);
}
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 258c8a3..e1a10b5 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -528,7 +528,7 @@ static int dm9000_rx(struct eth_device *netdev) Read a word data from SROM */ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_read_srom_word(int offset, u8 *to) +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPCR, 0x4); @@ -538,7 +538,7 @@ void dm9000_read_srom_word(int offset, u8 *to) to[1] = DM9000_ior(DM9000_EPDRH); }
-void dm9000_write_srom_word(int offset, u16 val) +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); @@ -554,7 +554,7 @@ static void dm9000_get_enetaddr(struct eth_device *dev) #if !defined(CONFIG_DM9000_NO_SROM) int i; for (i = 0; i < 3; i++)
dm9000_read_srom_word(i, dev->enetaddr + (2 * i));
dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i));
#endif }
diff --git a/include/dm9000.h b/include/dm9000.h index 42b04fa..7a7e629 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -10,8 +10,10 @@
/****************** function prototypes **********************/ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); +struct eth_device;
+void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to);
It will be better to pass the dm9000_priv* instead. See patch 5 for details.
#endif
#endif /* __DM9000_H__ */
2.1.4

On Wed, Aug 12, 2015 at 02:07:20PM -0500, Joe Hershberger wrote:
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
/****************** function prototypes **********************/ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); +struct eth_device;
+void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to);
It will be better to pass the dm9000_priv* instead. See patch 5 for details.
Even on the "public"-facing functions?
Thanks, Andrew

Hi Andrew,
On Fri, Aug 21, 2015 at 6:25 AM, Andrew Ruder andy@aeruder.net wrote:
On Wed, Aug 12, 2015 at 02:07:20PM -0500, Joe Hershberger wrote:
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
/****************** function prototypes **********************/ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); +struct eth_device;
+void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to);
It will be better to pass the dm9000_priv* instead. See patch 5 for details.
Even on the "public"-facing functions?
Your question got me looking closer at why are these public. These are public just so that a command (presumably only available on one board - trizepsiv) can access the eeprom of a dm9000. It also currently assumes that there is only one dm9000 on that board.
I think it should not expose any internal dm9000 struct. Here's what I mocked up:
diff --git a/board/trizepsiv/eeprom.c b/board/trizepsiv/eeprom.c index 1318edc..93c5733 100644 --- a/board/trizepsiv/eeprom.c +++ b/board/trizepsiv/eeprom.c @@ -16,7 +16,7 @@ static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * for (i=0; i < 0x40; i++) { if (!(i % 0x10)) printf("\n%08x:", i); - dm9000_read_srom_word(i, data); + dm9000_read_srom_word(0, i, data); printf(" %02x%02x", data[1], data[0]); } printf ("\n"); @@ -35,7 +35,7 @@ static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * printf("Wrong offset : 0x%x\n",offset); return cmd_usage(cmdtp); } - dm9000_write_srom_word(offset, value); + dm9000_write_srom_word(0, offset, value); return (0); }
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 3c41cec..8299f55 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -530,8 +530,10 @@ static int dm9000_rx(struct eth_device *netdev) Read a word data from SROM */ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_read_srom_word(int offset, u8 *to) +void dm9000_read_srom_word(int adapter_no, int offset, u8 *to) { + struct eth_device *dev = eth_get_dev_by_index(adapter_no); + DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPCR, 0x4); udelay(8000); @@ -540,8 +542,10 @@ void dm9000_read_srom_word(int offset, u8 *to) to[1] = DM9000_ior(DM9000_EPDRH); }
-void dm9000_write_srom_word(int offset, u16 val) +void dm9000_write_srom_word(int adapter_no, int offset, u16 val) { + struct eth_device *dev = eth_get_dev_by_index(adapter_no); + DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); DM9000_iow(DM9000_EPDRL, (val & 0xff)); diff --git a/include/dm9000.h b/include/dm9000.h index 42b04fa..27d69cf 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -10,8 +10,8 @@
/****************** function prototypes **********************/ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); +void dm9000_write_srom_word(int adapter_no, int offset, u16 val); +void dm9000_read_srom_word(int adapter_no, int offset, u8 *to); #endif
#endif /* __DM9000_H__ */
Naturally the dev variable will be unused so it would need to not actually be added until the patch that adds the used to the macro.
-Joe

Change the dm9000_initialize function to taking arguments for io address, data address, and availability of srom. Right now we aren't actually using any of this inside of drivers/net/dm9000x.c but we are making way for support for boards that have multiple (or discovered) numbers of dm9000 devices.
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com --- board/altera/nios2-generic/nios2-generic.c | 3 +-- board/atmel/at91sam9261ek/at91sam9261ek.c | 2 +- board/davinci/dm355evm/dm355evm.c | 2 +- board/davinci/dm355leopard/dm355leopard.c | 2 +- board/freescale/m5253demo/m5253demo.c | 2 +- board/icpdas/lp8x4x/lp8x4x.c | 2 +- board/ip04/ip04.c | 2 +- board/ronetix/pm9261/pm9261.c | 2 +- board/scb9328/scb9328.c | 2 +- board/timll/devkit8000/devkit8000.c | 2 +- board/toradex/colibri_pxa270/colibri_pxa270.c | 2 +- board/trizepsiv/conxs.c | 2 +- board/vpac270/vpac270.c | 2 +- drivers/net/dm9000x.c | 2 +- include/configs/M5253DEMO.h | 1 + include/configs/at91sam9261ek.h | 3 +-- include/configs/colibri_pxa270.h | 1 + include/configs/davinci_dm355evm.h | 1 + include/configs/davinci_dm355leopard.h | 1 + include/configs/devkit8000.h | 3 +-- include/configs/ip04.h | 2 +- include/configs/lp8x4x.h | 2 ++ include/configs/pm9261.h | 2 +- include/configs/scb9328.h | 1 + include/configs/trizepsiv.h | 1 + include/configs/vpac270.h | 1 + include/netdev.h | 2 +- 27 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c index 834cbeb..d6ed636 100644 --- a/board/altera/nios2-generic/nios2-generic.c +++ b/board/altera/nios2-generic/nios2-generic.c @@ -61,8 +61,7 @@ int board_eth_init(bd_t *bis) rc += smc91111_initialize(0, CONFIG_SMC91111_BASE); #endif #ifdef CONFIG_DRIVER_DM9000 - rc += dm9000_initialize(bis); -#endif + rc += dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); #ifdef CONFIG_ALTERA_TSE rc += altera_tse_initialize(0, CONFIG_SYS_ALTERA_TSE_MAC_BASE, diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c index 5250474..551f612 100644 --- a/board/atmel/at91sam9261ek/at91sam9261ek.c +++ b/board/atmel/at91sam9261ek/at91sam9261ek.c @@ -255,7 +255,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/davinci/dm355evm/dm355evm.c b/board/davinci/dm355evm/dm355evm.c index e5a958f..c37595d 100644 --- a/board/davinci/dm355evm/dm355evm.c +++ b/board/davinci/dm355evm/dm355evm.c @@ -74,7 +74,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/davinci/dm355leopard/dm355leopard.c b/board/davinci/dm355leopard/dm355leopard.c index 53902f9..e8c99f0 100644 --- a/board/davinci/dm355leopard/dm355leopard.c +++ b/board/davinci/dm355leopard/dm355leopard.c @@ -72,7 +72,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/freescale/m5253demo/m5253demo.c b/board/freescale/m5253demo/m5253demo.c index 7e516bf..dfe3c0c 100644 --- a/board/freescale/m5253demo/m5253demo.c +++ b/board/freescale/m5253demo/m5253demo.c @@ -135,6 +135,6 @@ void ide_set_reset(int idereset) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/icpdas/lp8x4x/lp8x4x.c b/board/icpdas/lp8x4x/lp8x4x.c index a136dc4..88099fe 100644 --- a/board/icpdas/lp8x4x/lp8x4x.c +++ b/board/icpdas/lp8x4x/lp8x4x.c @@ -123,6 +123,6 @@ int board_usb_cleanup(int index, enum usb_init_type init) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/ip04/ip04.c b/board/ip04/ip04.c index 70765bc..0de71aa 100644 --- a/board/ip04/ip04.c +++ b/board/ip04/ip04.c @@ -24,6 +24,6 @@ int checkboard(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/ronetix/pm9261/pm9261.c b/board/ronetix/pm9261/pm9261.c index b96f745..a5f1781 100644 --- a/board/ronetix/pm9261/pm9261.c +++ b/board/ronetix/pm9261/pm9261.c @@ -262,7 +262,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/scb9328/scb9328.c b/board/scb9328/scb9328.c index 3463f52..93f843e 100644 --- a/board/scb9328/scb9328.c +++ b/board/scb9328/scb9328.c @@ -49,6 +49,6 @@ void show_boot_progress (int status) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 4d07313..ff0b43b 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -151,7 +151,7 @@ void board_mmc_power_init(void) */ int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/toradex/colibri_pxa270/colibri_pxa270.c b/board/toradex/colibri_pxa270/colibri_pxa270.c index 3def0a6..a5039eb 100644 --- a/board/toradex/colibri_pxa270/colibri_pxa270.c +++ b/board/toradex/colibri_pxa270/colibri_pxa270.c @@ -94,7 +94,7 @@ void usb_board_stop(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/trizepsiv/conxs.c b/board/trizepsiv/conxs.c index 1ddf05d..e174861 100644 --- a/board/trizepsiv/conxs.c +++ b/board/trizepsiv/conxs.c @@ -135,7 +135,7 @@ void dram_init_banksize(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif
diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c index 8d777df..76ed3be 100644 --- a/board/vpac270/vpac270.c +++ b/board/vpac270/vpac270.c @@ -121,6 +121,6 @@ void usb_board_stop(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index e1a10b5..9778ef9 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -616,7 +616,7 @@ dm9000_phy_write(int reg, u16 value) DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value); }
-int dm9000_initialize(bd_t *bis) +int dm9000_initialize(u8 dev_num, ulong addr, ulong data, u8 has_srom) { struct eth_device *dev = &(dm9000_info.netdev);
diff --git a/include/configs/M5253DEMO.h b/include/configs/M5253DEMO.h index ddb5cda..02adb79 100644 --- a/include/configs/M5253DEMO.h +++ b/include/configs/M5253DEMO.h @@ -71,6 +71,7 @@ # define CONFIG_DM9000_BASE (CONFIG_SYS_CS1_BASE | 0x300) # define DM9000_IO CONFIG_DM9000_BASE # define DM9000_DATA (CONFIG_DM9000_BASE + 4) +# define DM9000_HAS_SROM 1 # undef CONFIG_DM9000_DEBUG # define CONFIG_DM9000_BYTE_SWAPPED
diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index 42461d2..7b4e63d 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -131,8 +131,7 @@ #define CONFIG_DM9000_BASE 0x30000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 4) -#define CONFIG_DM9000_USE_16BIT -#define CONFIG_DM9000_NO_SROM +#define DM9000_HAS_SROM 0 #define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_RESET_PHY_R
diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index e3f0ab0..e7db8cf 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -67,6 +67,7 @@ #define CONFIG_DM9000_BASE 0x08000000 #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define DM9000_HAS_SROM 1 #define CONFIG_NET_RETRY_COUNT 10
#define CONFIG_BOOTP_BOOTFILESIZE diff --git a/include/configs/davinci_dm355evm.h b/include/configs/davinci_dm355evm.h index e873fa4..b3f5a28 100644 --- a/include/configs/davinci_dm355evm.h +++ b/include/configs/davinci_dm355evm.h @@ -38,6 +38,7 @@ #define CONFIG_DM9000_BASE 0x04014000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 2) +#define DM9000_HAS_SROM 1
/* I2C */ #define CONFIG_SYS_I2C diff --git a/include/configs/davinci_dm355leopard.h b/include/configs/davinci_dm355leopard.h index d4b994a..0f27e86 100644 --- a/include/configs/davinci_dm355leopard.h +++ b/include/configs/davinci_dm355leopard.h @@ -37,6 +37,7 @@ #define CONFIG_DM9000_BASE 0x04000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 16) +#define DM9000_HAS_SROM 1
/* I2C */ #define CONFIG_SYS_I2C diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 215dc30..78f7f11 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -61,8 +61,7 @@ #define CONFIG_DM9000_BASE 0x2c000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 0x400) -#define CONFIG_DM9000_USE_16BIT 1 -#define CONFIG_DM9000_NO_SROM 1 +#define DM9000_HAS_SROM 0 #undef CONFIG_DM9000_DEBUG
/* SPI */ diff --git a/include/configs/ip04.h b/include/configs/ip04.h index dd2a618..1ae92af 100644 --- a/include/configs/ip04.h +++ b/include/configs/ip04.h @@ -72,10 +72,10 @@ #define CONFIG_HOSTNAME IP04
#define CONFIG_DRIVER_DM9000 1 -#define CONFIG_DM9000_NO_SROM #define CONFIG_DM9000_BASE 0x20100000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 2) +#define DM9000_HAS_SROM 0
/* diff --git a/include/configs/lp8x4x.h b/include/configs/lp8x4x.h index e9ee3fb..17f8558 100644 --- a/include/configs/lp8x4x.h +++ b/include/configs/lp8x4x.h @@ -62,8 +62,10 @@ #define CONFIG_DM9000_BASE 0x0C000000 #define DM9000_IO 0x0C000000 #define DM9000_DATA 0x0C004000 +#define DM9000_HAS_SROM 1 #define DM9000_IO_2 0x0D000000 #define DM9000_DATA_2 0x0D004000 +#define DM9000_HAS_SROM_2 1 #define CONFIG_NET_RETRY_COUNT 10
#define CONFIG_BOOTP_BOOTFILESIZE diff --git a/include/configs/pm9261.h b/include/configs/pm9261.h index f9a1d51..41c540d 100644 --- a/include/configs/pm9261.h +++ b/include/configs/pm9261.h @@ -229,7 +229,7 @@ #define CONFIG_DM9000_BASE 0x30000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 4) -#define CONFIG_DM9000_USE_16BIT 1 +#define DM9000_HAS_SROM 1 #define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_RESET_PHY_R 1
diff --git a/include/configs/scb9328.h b/include/configs/scb9328.h index f367d62..091c0ee 100644 --- a/include/configs/scb9328.h +++ b/include/configs/scb9328.h @@ -214,6 +214,7 @@ #define CONFIG_DM9000_BASE 0x16000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+4) +#define DM9000_HAS_SROM 1
/* f_{dpll}=2*f{ref}*(MFI+MFN/(MFD+1))/(PD+1) f_ref=16,777MHz diff --git a/include/configs/trizepsiv.h b/include/configs/trizepsiv.h index 8368931..1dcc03e 100644 --- a/include/configs/trizepsiv.h +++ b/include/configs/trizepsiv.h @@ -263,6 +263,7 @@
#define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+0x8004) +#define DM9000_HAS_SROM 1
#define CONFIG_USB_OHCI_NEW 1 #define CONFIG_SYS_USB_OHCI_BOARD_INIT 1 diff --git a/include/configs/vpac270.h b/include/configs/vpac270.h index 95a69b3..2a765f9 100644 --- a/include/configs/vpac270.h +++ b/include/configs/vpac270.h @@ -91,6 +91,7 @@ #define CONFIG_DM9000_BASE 0x08000300 /* CS2 */ #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define DM9000_HAS_SROM 1 #define CONFIG_NET_RETRY_COUNT 10
#define CONFIG_BOOTP_BOOTFILESIZE diff --git a/include/netdev.h b/include/netdev.h index 662d173..971fde1 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -38,7 +38,7 @@ int cs8900_initialize(u8 dev_num, int base_addr); int davinci_emac_initialize(void); int dc21x4x_initialize(bd_t *bis); int designware_initialize(ulong base_addr, u32 interface); -int dm9000_initialize(bd_t *bis); +int dm9000_initialize(u8 dev_num, ulong addr, ulong data, u8 has_srom); int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr); int e1000_initialize(bd_t *bis); int eepro100_initialize(bd_t *bis);

Hi Andrew,
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
Change the dm9000_initialize function to taking arguments for io address, data address, and availability of srom. Right now we aren't actually using any of this inside of drivers/net/dm9000x.c but we are making way for support for boards that have multiple (or discovered) numbers of dm9000 devices.
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com
board/altera/nios2-generic/nios2-generic.c | 3 +-- board/atmel/at91sam9261ek/at91sam9261ek.c | 2 +- board/davinci/dm355evm/dm355evm.c | 2 +- board/davinci/dm355leopard/dm355leopard.c | 2 +- board/freescale/m5253demo/m5253demo.c | 2 +- board/icpdas/lp8x4x/lp8x4x.c | 2 +- board/ip04/ip04.c | 2 +- board/ronetix/pm9261/pm9261.c | 2 +- board/scb9328/scb9328.c | 2 +- board/timll/devkit8000/devkit8000.c | 2 +- board/toradex/colibri_pxa270/colibri_pxa270.c | 2 +- board/trizepsiv/conxs.c | 2 +- board/vpac270/vpac270.c | 2 +- drivers/net/dm9000x.c | 2 +- include/configs/M5253DEMO.h | 1 + include/configs/at91sam9261ek.h | 3 +-- include/configs/colibri_pxa270.h | 1 + include/configs/davinci_dm355evm.h | 1 + include/configs/davinci_dm355leopard.h | 1 + include/configs/devkit8000.h | 3 +-- include/configs/ip04.h | 2 +- include/configs/lp8x4x.h | 2 ++ include/configs/pm9261.h | 2 +- include/configs/scb9328.h | 1 + include/configs/trizepsiv.h | 1 + include/configs/vpac270.h | 1 + include/netdev.h | 2 +- 27 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c index 834cbeb..d6ed636 100644 --- a/board/altera/nios2-generic/nios2-generic.c +++ b/board/altera/nios2-generic/nios2-generic.c @@ -61,8 +61,7 @@ int board_eth_init(bd_t *bis) rc += smc91111_initialize(0, CONFIG_SMC91111_BASE); #endif #ifdef CONFIG_DRIVER_DM9000
rc += dm9000_initialize(bis);
-#endif
It appears you are removing the closing #endif. Surely this breaks the nios2 build, right?
rc += dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
#ifdef CONFIG_ALTERA_TSE rc += altera_tse_initialize(0, CONFIG_SYS_ALTERA_TSE_MAC_BASE, diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c index 5250474..551f612 100644 --- a/board/atmel/at91sam9261ek/at91sam9261ek.c +++ b/board/atmel/at91sam9261ek/at91sam9261ek.c @@ -255,7 +255,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/davinci/dm355evm/dm355evm.c b/board/davinci/dm355evm/dm355evm.c index e5a958f..c37595d 100644 --- a/board/davinci/dm355evm/dm355evm.c +++ b/board/davinci/dm355evm/dm355evm.c @@ -74,7 +74,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/davinci/dm355leopard/dm355leopard.c b/board/davinci/dm355leopard/dm355leopard.c index 53902f9..e8c99f0 100644 --- a/board/davinci/dm355leopard/dm355leopard.c +++ b/board/davinci/dm355leopard/dm355leopard.c @@ -72,7 +72,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/freescale/m5253demo/m5253demo.c b/board/freescale/m5253demo/m5253demo.c index 7e516bf..dfe3c0c 100644 --- a/board/freescale/m5253demo/m5253demo.c +++ b/board/freescale/m5253demo/m5253demo.c @@ -135,6 +135,6 @@ void ide_set_reset(int idereset) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif diff --git a/board/icpdas/lp8x4x/lp8x4x.c b/board/icpdas/lp8x4x/lp8x4x.c index a136dc4..88099fe 100644 --- a/board/icpdas/lp8x4x/lp8x4x.c +++ b/board/icpdas/lp8x4x/lp8x4x.c @@ -123,6 +123,6 @@ int board_usb_cleanup(int index, enum usb_init_type init) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif diff --git a/board/ip04/ip04.c b/board/ip04/ip04.c index 70765bc..0de71aa 100644 --- a/board/ip04/ip04.c +++ b/board/ip04/ip04.c @@ -24,6 +24,6 @@ int checkboard(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif diff --git a/board/ronetix/pm9261/pm9261.c b/board/ronetix/pm9261/pm9261.c index b96f745..a5f1781 100644 --- a/board/ronetix/pm9261/pm9261.c +++ b/board/ronetix/pm9261/pm9261.c @@ -262,7 +262,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/scb9328/scb9328.c b/board/scb9328/scb9328.c index 3463f52..93f843e 100644 --- a/board/scb9328/scb9328.c +++ b/board/scb9328/scb9328.c @@ -49,6 +49,6 @@ void show_boot_progress (int status) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 4d07313..ff0b43b 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -151,7 +151,7 @@ void board_mmc_power_init(void) */ int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/toradex/colibri_pxa270/colibri_pxa270.c b/board/toradex/colibri_pxa270/colibri_pxa270.c index 3def0a6..a5039eb 100644 --- a/board/toradex/colibri_pxa270/colibri_pxa270.c +++ b/board/toradex/colibri_pxa270/colibri_pxa270.c @@ -94,7 +94,7 @@ void usb_board_stop(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/trizepsiv/conxs.c b/board/trizepsiv/conxs.c index 1ddf05d..e174861 100644 --- a/board/trizepsiv/conxs.c +++ b/board/trizepsiv/conxs.c @@ -135,7 +135,7 @@ void dram_init_banksize(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif
diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c index 8d777df..76ed3be 100644 --- a/board/vpac270/vpac270.c +++ b/board/vpac270/vpac270.c @@ -121,6 +121,6 @@ void usb_board_stop(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) {
return dm9000_initialize(bis);
return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM);
} #endif diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index e1a10b5..9778ef9 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -616,7 +616,7 @@ dm9000_phy_write(int reg, u16 value) DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value); }
-int dm9000_initialize(bd_t *bis) +int dm9000_initialize(u8 dev_num, ulong addr, ulong data, u8 has_srom) { struct eth_device *dev = &(dm9000_info.netdev);
diff --git a/include/configs/M5253DEMO.h b/include/configs/M5253DEMO.h index ddb5cda..02adb79 100644 --- a/include/configs/M5253DEMO.h +++ b/include/configs/M5253DEMO.h @@ -71,6 +71,7 @@ # define CONFIG_DM9000_BASE (CONFIG_SYS_CS1_BASE | 0x300) # define DM9000_IO CONFIG_DM9000_BASE # define DM9000_DATA (CONFIG_DM9000_BASE + 4) +# define DM9000_HAS_SROM 1 # undef CONFIG_DM9000_DEBUG # define CONFIG_DM9000_BYTE_SWAPPED
diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index 42461d2..7b4e63d 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -131,8 +131,7 @@ #define CONFIG_DM9000_BASE 0x30000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 4) -#define CONFIG_DM9000_USE_16BIT -#define CONFIG_DM9000_NO_SROM +#define DM9000_HAS_SROM 0 #define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_RESET_PHY_R
diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index e3f0ab0..e7db8cf 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -67,6 +67,7 @@ #define CONFIG_DM9000_BASE 0x08000000 #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define DM9000_HAS_SROM 1 #define CONFIG_NET_RETRY_COUNT 10
#define CONFIG_BOOTP_BOOTFILESIZE diff --git a/include/configs/davinci_dm355evm.h b/include/configs/davinci_dm355evm.h index e873fa4..b3f5a28 100644 --- a/include/configs/davinci_dm355evm.h +++ b/include/configs/davinci_dm355evm.h @@ -38,6 +38,7 @@ #define CONFIG_DM9000_BASE 0x04014000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 2) +#define DM9000_HAS_SROM 1
/* I2C */ #define CONFIG_SYS_I2C diff --git a/include/configs/davinci_dm355leopard.h b/include/configs/davinci_dm355leopard.h index d4b994a..0f27e86 100644 --- a/include/configs/davinci_dm355leopard.h +++ b/include/configs/davinci_dm355leopard.h @@ -37,6 +37,7 @@ #define CONFIG_DM9000_BASE 0x04000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 16) +#define DM9000_HAS_SROM 1
/* I2C */ #define CONFIG_SYS_I2C diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 215dc30..78f7f11 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -61,8 +61,7 @@ #define CONFIG_DM9000_BASE 0x2c000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 0x400) -#define CONFIG_DM9000_USE_16BIT 1 -#define CONFIG_DM9000_NO_SROM 1 +#define DM9000_HAS_SROM 0 #undef CONFIG_DM9000_DEBUG
/* SPI */ diff --git a/include/configs/ip04.h b/include/configs/ip04.h index dd2a618..1ae92af 100644 --- a/include/configs/ip04.h +++ b/include/configs/ip04.h @@ -72,10 +72,10 @@ #define CONFIG_HOSTNAME IP04
#define CONFIG_DRIVER_DM9000 1 -#define CONFIG_DM9000_NO_SROM #define CONFIG_DM9000_BASE 0x20100000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 2) +#define DM9000_HAS_SROM 0
/* diff --git a/include/configs/lp8x4x.h b/include/configs/lp8x4x.h index e9ee3fb..17f8558 100644 --- a/include/configs/lp8x4x.h +++ b/include/configs/lp8x4x.h @@ -62,8 +62,10 @@ #define CONFIG_DM9000_BASE 0x0C000000 #define DM9000_IO 0x0C000000 #define DM9000_DATA 0x0C004000 +#define DM9000_HAS_SROM 1 #define DM9000_IO_2 0x0D000000 #define DM9000_DATA_2 0x0D004000 +#define DM9000_HAS_SROM_2 1 #define CONFIG_NET_RETRY_COUNT 10
#define CONFIG_BOOTP_BOOTFILESIZE diff --git a/include/configs/pm9261.h b/include/configs/pm9261.h index f9a1d51..41c540d 100644 --- a/include/configs/pm9261.h +++ b/include/configs/pm9261.h @@ -229,7 +229,7 @@ #define CONFIG_DM9000_BASE 0x30000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 4) -#define CONFIG_DM9000_USE_16BIT 1 +#define DM9000_HAS_SROM 1 #define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_RESET_PHY_R 1
diff --git a/include/configs/scb9328.h b/include/configs/scb9328.h index f367d62..091c0ee 100644 --- a/include/configs/scb9328.h +++ b/include/configs/scb9328.h @@ -214,6 +214,7 @@ #define CONFIG_DM9000_BASE 0x16000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+4) +#define DM9000_HAS_SROM 1
/* f_{dpll}=2*f{ref}*(MFI+MFN/(MFD+1))/(PD+1) f_ref=16,777MHz diff --git a/include/configs/trizepsiv.h b/include/configs/trizepsiv.h index 8368931..1dcc03e 100644 --- a/include/configs/trizepsiv.h +++ b/include/configs/trizepsiv.h @@ -263,6 +263,7 @@
#define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+0x8004) +#define DM9000_HAS_SROM 1
#define CONFIG_USB_OHCI_NEW 1 #define CONFIG_SYS_USB_OHCI_BOARD_INIT 1 diff --git a/include/configs/vpac270.h b/include/configs/vpac270.h index 95a69b3..2a765f9 100644 --- a/include/configs/vpac270.h +++ b/include/configs/vpac270.h @@ -91,6 +91,7 @@ #define CONFIG_DM9000_BASE 0x08000300 /* CS2 */ #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define DM9000_HAS_SROM 1 #define CONFIG_NET_RETRY_COUNT 10
#define CONFIG_BOOTP_BOOTFILESIZE diff --git a/include/netdev.h b/include/netdev.h index 662d173..971fde1 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -38,7 +38,7 @@ int cs8900_initialize(u8 dev_num, int base_addr); int davinci_emac_initialize(void); int dc21x4x_initialize(bd_t *bis); int designware_initialize(ulong base_addr, u32 interface); -int dm9000_initialize(bd_t *bis); +int dm9000_initialize(u8 dev_num, ulong addr, ulong data, u8 has_srom); int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr); int e1000_initialize(bd_t *bis); int eepro100_initialize(bd_t *bis); -- 2.1.4

On Wed, 2015-08-12 at 12:24 -0500, Andrew Ruder wrote:
Just one nitty-gritty detail:
diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index e3f0ab0..e7db8cf 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -67,6 +67,7 @@ #define CONFIG_DM9000_BASE 0x08000000 #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define DM9000_HAS_SROM 1
Colibri PXA270 do not actually have any SROM so this should be defined to 0 instead.
#define CONFIG_NET_RETRY_COUNT 10
Otherwise for the whole series.
Signed-off-by: Marcel Ziswiler marcel@ziswiler.com
Tested-by: Marcel Ziswiler marcel@ziswiler.com Tested-on: Colibri PXA270 V1.2C, V1.2D, V2.2B, V2.4A on Colibri Evaluation Board V3.1A Note: I only tested the one default on-module Ethernet instance and while it all still works OK it feels like the transfer speed is slightly lower (e.g. from the previous 1.3 MiB/s I now get 1.2 MiB/s).

On Sun, 2015-08-16 at 02:51 +0200, Marcel Ziswiler wrote:
On Wed, 2015-08-12 at 12:24 -0500, Andrew Ruder wrote:
Just one nitty-gritty detail:
diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index e3f0ab0..e7db8cf 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -67,6 +67,7 @@ #define CONFIG_DM9000_BASE 0x08000000 #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define DM9000_HAS_SROM 1
Colibri PXA270 do not actually have any SROM so this should be defined to 0 instead.
#define CONFIG_NET_RETRY_COUNT 10
Otherwise for the whole series.
Signed-off-by: Marcel Ziswiler marcel@ziswiler.com
This should of course have been an Acked-by, sorry. Will by you some Guinness in Dublin (;-p).
Tested-by: Marcel Ziswiler marcel@ziswiler.com Tested-on: Colibri PXA270 V1.2C, V1.2D, V2.2B, V2.4A on Colibri Evaluation Board V3.1A Note: I only tested the one default on-module Ethernet instance and while it all still works OK it feels like the transfer speed is slightly lower (e.g. from the previous 1.3 MiB/s I now get 1.2 MiB/s).

The DM9000 was hard-coded to only support one DM9000 device. This patch changes the initialization function - dm9000_initialize - to support registering multiple (and possibly dynamic) numbers of dm9000 devices. This patch consists of:
* Change the board_info struct to a private struct under eth_device. * Add io address/data address/srom availability information to this private struct. * Replace all uses of DM9000_IO/DM9000_DATA with new members, ensure that the eth_device struct propagates down to all helper functions. * Call dm9000_initialize_ex() with filled in information from the old preprocessor symbols (DM9000_IO, DM9000_DATA, etc.)
Overall the following parameters have been moved over to being a per-chip setting:
DM9000_IO, DM9000_DATA, CONFIG_DM9000_NO_SROM
while the following is still a global setting affecting all chips:
CONFIG_DM9000_BYTE_SWAPPED
And the following has been removed entirely:
CONFIG_DM9000_BASE (was only used in a single printf)
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com --- drivers/net/dm9000x.c | 382 +++++++++++++++++++++++++++++--------------------- include/dm9000.h | 2 - 2 files changed, 220 insertions(+), 164 deletions(-)
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 9778ef9..d0ea5d7 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -55,6 +55,7 @@ TODO: external MII is not functional, only internal at the moment. #include <asm/io.h> #include <dm9000.h> #include <linux/compiler.h> +#include <malloc.h>
#include "dm9000x.h"
@@ -80,7 +81,9 @@ TODO: external MII is not functional, only internal at the moment. #endif
/* Structure/enum declaration ------------------------------- */ -typedef struct board_info { +struct dm9000_priv { + ulong data_base; + ulong io_base; u32 runt_length_counter; /* counter: RX length < 64byte */ u32 long_length_counter; /* counter: RX length > 1514byte */ u32 reset_counter; /* counter: RESET */ @@ -89,23 +92,22 @@ typedef struct board_info { u16 tx_pkt_cnt; u16 queue_start_addr; u16 dbug_cnt; + u8 has_srom; u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128]; - void (*outblk)(void *data_ptr, int count); - void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *rx_status, u16 *rx_len); - struct eth_device netdev; -} board_info_t; -static board_info_t dm9000_info; + void (*outblk)(struct eth_device *dev, void *data_ptr, int count); + void (*inblk)(struct eth_device *dev, void *data_ptr, int count); + void (*rx_status)(struct eth_device *dev, u16 *rx_status, u16 *rx_len); +};
/* function declaration ------------------------------------- */ -static int dm9000_probe(void); -static u16 dm9000_phy_read(int); -static void dm9000_phy_write(int, u16); -static u8 DM9000_ior(int); -static void DM9000_iow(int reg, u8 value); +static int dm9000_probe(struct eth_device *); +static u16 dm9000_phy_read(struct eth_device *, int); +static void dm9000_phy_write(struct eth_device *, int, u16); +static u8 DM9000_ior(struct eth_device *, int); +static void DM9000_iow(struct eth_device *, int reg, u8 value);
/* DM9000 network board routine ---------------------------- */ #ifndef CONFIG_DM9000_BYTE_SWAPPED @@ -126,125 +128,147 @@ static void DM9000_iow(int reg, u8 value);
#ifdef CONFIG_DM9000_DEBUG static __maybe_unused void -dump_regs(void) +dump_regs(struct eth_device *dev) { DM9000_DBG("\n"); - DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); - DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1)); - DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2)); - DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3)); - DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); - DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); - DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); - DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); + DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(dev, 0)); + DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(dev, 1)); + DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(dev, 2)); + DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(dev, 3)); + DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(dev, 4)); + DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(dev, 5)); + DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(dev, 6)); + DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(dev, DM9000_ISR)); DM9000_DBG("\n"); } #endif
-static void dm9000_outblk_8bit(void *data_ptr, int count) +static void +dm9000_outblk_8bit(struct eth_device *dev, void *data_ptr, int count) { int i; + struct dm9000_priv *priv = dev->priv; for (i = 0; i < count; i++) - DM9000_outb((((u8 *)data_ptr)[i] & 0xff), DM9000_DATA); + DM9000_outb((((u8 *)data_ptr)[i] & 0xff), priv->data_base); }
-static void dm9000_outblk_16bit(void *data_ptr, int count) +static void +dm9000_outblk_16bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2; + struct dm9000_priv *priv = dev->priv;
for (i = 0; i < tmplen; i++) - DM9000_outw(((u16 *)data_ptr)[i], DM9000_DATA); + DM9000_outw(((u16 *)data_ptr)[i], priv->data_base); } -static void dm9000_outblk_32bit(void *data_ptr, int count) +static void +dm9000_outblk_32bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4; + struct dm9000_priv *priv = dev->priv;
for (i = 0; i < tmplen; i++) - DM9000_outl(((u32 *)data_ptr)[i], DM9000_DATA); + DM9000_outl(((u32 *)data_ptr)[i], priv->data_base); }
-static void dm9000_inblk_8bit(void *data_ptr, int count) +static void +dm9000_inblk_8bit(struct eth_device *dev, void *data_ptr, int count) { int i; + struct dm9000_priv *priv = dev->priv; + for (i = 0; i < count; i++) - ((u8 *)data_ptr)[i] = DM9000_inb(DM9000_DATA); + ((u8 *)data_ptr)[i] = DM9000_inb(priv->data_base); }
-static void dm9000_inblk_16bit(void *data_ptr, int count) +static void +dm9000_inblk_16bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2; + struct dm9000_priv *priv = dev->priv;
for (i = 0; i < tmplen; i++) - ((u16 *)data_ptr)[i] = DM9000_inw(DM9000_DATA); + ((u16 *)data_ptr)[i] = DM9000_inw(priv->data_base); } -static void dm9000_inblk_32bit(void *data_ptr, int count) +static void +dm9000_inblk_32bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4; + struct dm9000_priv *priv = dev->priv;
for (i = 0; i < tmplen; i++) - ((u32 *)data_ptr)[i] = DM9000_inl(DM9000_DATA); + ((u32 *)data_ptr)[i] = DM9000_inl(priv->data_base); }
-static void dm9000_rx_status_32bit(u16 *rx_status, u16 *rx_len) +static void +dm9000_rx_status_32bit(struct eth_device *dev, u16 *rx_status, u16 *rx_len) { u32 tmpdata; + struct dm9000_priv *priv = dev->priv;
- DM9000_outb(DM9000_MRCMD, DM9000_IO); + DM9000_outb(DM9000_MRCMD, priv->io_base);
- tmpdata = DM9000_inl(DM9000_DATA); + tmpdata = DM9000_inl(priv->data_base); *rx_status = __le16_to_cpu(tmpdata); *rx_len = __le16_to_cpu(tmpdata >> 16); }
-static void dm9000_rx_status_16bit(u16 *rx_status, u16 *rx_len) +static void +dm9000_rx_status_16bit(struct eth_device *dev, u16 *rx_status, u16 *rx_len) { - DM9000_outb(DM9000_MRCMD, DM9000_IO); + struct dm9000_priv *priv = dev->priv;
- *rx_status = __le16_to_cpu(DM9000_inw(DM9000_DATA)); - *rx_len = __le16_to_cpu(DM9000_inw(DM9000_DATA)); + DM9000_outb(DM9000_MRCMD, priv->io_base); + + *rx_status = __le16_to_cpu(DM9000_inw(priv->data_base)); + *rx_len = __le16_to_cpu(DM9000_inw(priv->data_base)); }
-static void dm9000_rx_status_8bit(u16 *rx_status, u16 *rx_len) +static void +dm9000_rx_status_8bit(struct eth_device *dev, u16 *rx_status, u16 *rx_len) { - DM9000_outb(DM9000_MRCMD, DM9000_IO); + struct dm9000_priv *priv = dev->priv; + + DM9000_outb(DM9000_MRCMD, priv->io_base);
*rx_status = - __le16_to_cpu(DM9000_inb(DM9000_DATA) + - (DM9000_inb(DM9000_DATA) << 8)); + __le16_to_cpu(DM9000_inb(priv->data_base) + + (DM9000_inb(priv->data_base) << 8)); *rx_len = - __le16_to_cpu(DM9000_inb(DM9000_DATA) + - (DM9000_inb(DM9000_DATA) << 8)); + __le16_to_cpu(DM9000_inb(priv->data_base) + + (DM9000_inb(priv->data_base) << 8)); }
/* Search DM9000 board, allocate space and register it */ int -dm9000_probe(void) +dm9000_probe(struct eth_device *dev) { + struct dm9000_priv *priv = dev->priv; u32 id_val; - id_val = DM9000_ior(DM9000_VIDL); - id_val |= DM9000_ior(DM9000_VIDH) << 8; - id_val |= DM9000_ior(DM9000_PIDL) << 16; - id_val |= DM9000_ior(DM9000_PIDH) << 24; + id_val = DM9000_ior(dev, DM9000_VIDL); + id_val |= DM9000_ior(dev, DM9000_VIDH) << 8; + id_val |= DM9000_ior(dev, DM9000_PIDL) << 16; + id_val |= DM9000_ior(dev, DM9000_PIDH) << 24; if (id_val == DM9000_ID) { - printf("dm9000 i/o: 0x%x, id: 0x%x\n", CONFIG_DM9000_BASE, + printf("dm9000 i/o: 0x%lx, id: 0x%x\n", priv->io_base, id_val); return 0; } else { - printf("dm9000 not found at 0x%08x id: 0x%08x\n", - CONFIG_DM9000_BASE, id_val); + printf("dm9000 not found at 0x%08lx id: 0x%08x\n", + priv->io_base, id_val); return -1; } }
/* General Purpose dm9000 reset routine */ static void -dm9000_reset(void) +dm9000_reset(struct eth_device *dev) { DM9000_DBG("resetting DM9000\n");
@@ -252,29 +276,29 @@ dm9000_reset(void) see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */
/* DEBUG: Make all GPIO0 outputs, all others inputs */ - DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT); + DM9000_iow(dev, DM9000_GPCR, GPCR_GPIO0_OUT); /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */ - DM9000_iow(DM9000_GPR, 0); + DM9000_iow(dev, DM9000_GPR, 0); /* Step 2: Software reset */ - DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); + DM9000_iow(dev, DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
do { DM9000_DBG("resetting the DM9000, 1st reset\n"); udelay(25); /* Wait at least 20 us */ - } while (DM9000_ior(DM9000_NCR) & 1); + } while (DM9000_ior(dev, DM9000_NCR) & 1);
- DM9000_iow(DM9000_NCR, 0); + DM9000_iow(dev, DM9000_NCR, 0); /* Issue a second reset */ - DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); + DM9000_iow(dev, DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
do { DM9000_DBG("resetting the DM9000, 2nd reset\n"); udelay(25); /* Wait at least 20 us */ - } while (DM9000_ior(DM9000_NCR) & 1); + } while (DM9000_ior(dev, DM9000_NCR) & 1);
/* Check whether the ethernet controller is present */ - if ((DM9000_ior(DM9000_PIDL) != 0x0) || - (DM9000_ior(DM9000_PIDH) != 0x90)) + if ((DM9000_ior(dev, DM9000_PIDL) != 0x0) || + (DM9000_ior(dev, DM9000_PIDH) != 0x90)) printf("ERROR: resetting DM9000 -> not responding\n"); }
@@ -284,63 +308,63 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) { int i, oft, lnk; u8 io_mode; - struct board_info *db = &dm9000_info; + struct dm9000_priv *priv = dev->priv;
DM9000_DBG("%s\n", __func__);
/* RESET device */ - dm9000_reset(); + dm9000_reset(dev);
- if (dm9000_probe() < 0) + if (dm9000_probe(dev) < 0) return -1;
/* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ - io_mode = DM9000_ior(DM9000_ISR) >> 6; + io_mode = DM9000_ior(dev, DM9000_ISR) >> 6;
switch (io_mode) { case 0x0: /* 16-bit mode */ printf("DM9000: running in 16 bit mode\n"); - db->outblk = dm9000_outblk_16bit; - db->inblk = dm9000_inblk_16bit; - db->rx_status = dm9000_rx_status_16bit; + priv->outblk = dm9000_outblk_16bit; + priv->inblk = dm9000_inblk_16bit; + priv->rx_status = dm9000_rx_status_16bit; break; case 0x01: /* 32-bit mode */ printf("DM9000: running in 32 bit mode\n"); - db->outblk = dm9000_outblk_32bit; - db->inblk = dm9000_inblk_32bit; - db->rx_status = dm9000_rx_status_32bit; + priv->outblk = dm9000_outblk_32bit; + priv->inblk = dm9000_inblk_32bit; + priv->rx_status = dm9000_rx_status_32bit; break; case 0x02: /* 8 bit mode */ printf("DM9000: running in 8 bit mode\n"); - db->outblk = dm9000_outblk_8bit; - db->inblk = dm9000_inblk_8bit; - db->rx_status = dm9000_rx_status_8bit; + priv->outblk = dm9000_outblk_8bit; + priv->inblk = dm9000_inblk_8bit; + priv->rx_status = dm9000_rx_status_8bit; break; default: /* Assume 8 bit mode, will probably not work anyway */ printf("DM9000: Undefined IO-mode:0x%x\n", io_mode); - db->outblk = dm9000_outblk_8bit; - db->inblk = dm9000_inblk_8bit; - db->rx_status = dm9000_rx_status_8bit; + priv->outblk = dm9000_outblk_8bit; + priv->inblk = dm9000_inblk_8bit; + priv->rx_status = dm9000_rx_status_8bit; break; }
/* Program operating register, only internal phy supported */ - DM9000_iow(DM9000_NCR, 0x0); + DM9000_iow(dev, DM9000_NCR, 0x0); /* TX Polling clear */ - DM9000_iow(DM9000_TCR, 0); + DM9000_iow(dev, DM9000_TCR, 0); /* Less 3Kb, 200us */ - DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US); + DM9000_iow(dev, DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US); /* Flow Control : High/Low Water */ - DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); + DM9000_iow(dev, DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* SH FIXME: This looks strange! Flow Control */ - DM9000_iow(DM9000_FCR, 0x0); + DM9000_iow(dev, DM9000_FCR, 0x0); /* Special Mode */ - DM9000_iow(DM9000_SMCR, 0); + DM9000_iow(dev, DM9000_SMCR, 0); /* clear TX status */ - DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); + DM9000_iow(dev, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* Clear interrupt status */ - DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); + DM9000_iow(dev, DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
printf("MAC: %pM\n", dev->enetaddr); if (!is_valid_ethaddr(dev->enetaddr)) { @@ -349,23 +373,24 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd)
/* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) - DM9000_iow(oft, dev->enetaddr[i]); + DM9000_iow(dev, oft, dev->enetaddr[i]); for (i = 0, oft = 0x16; i < 8; i++, oft++) - DM9000_iow(oft, 0xff); + DM9000_iow(dev, oft, 0xff);
/* read back mac, just to be sure */ for (i = 0, oft = 0x10; i < 6; i++, oft++) - DM9000_DBG("%02x:", DM9000_ior(oft)); + DM9000_DBG("%02x:", DM9000_ior(dev, oft)); DM9000_DBG("\n");
/* Activate DM9000 */ /* RX enable */ - DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); + DM9000_iow(dev, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* Enable TX/RX interrupt mask */ - DM9000_iow(DM9000_IMR, IMR_PAR); + DM9000_iow(dev, DM9000_IMR, IMR_PAR);
i = 0; - while (!(dm9000_phy_read(1) & 0x20)) { /* autonegation complete bit */ + while (!(dm9000_phy_read(dev, 1) & 0x20)) { + /* autonegation complete bit */ udelay(1000); i++; if (i == 10000) { @@ -375,7 +400,7 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) }
/* see what we've got */ - lnk = dm9000_phy_read(17) >> 12; + lnk = dm9000_phy_read(dev, 17) >> 12; printf("operating at "); switch (lnk) { case 1: @@ -402,38 +427,38 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) Hardware start transmission. Send a packet to media from the upper layer. */ -static int dm9000_send(struct eth_device *netdev, void *packet, int length) +static int dm9000_send(struct eth_device *dev, void *packet, int length) { int tmo; - struct board_info *db = &dm9000_info; + struct dm9000_priv *priv = dev->priv;
DM9000_DMP_PACKET(__func__ , packet, length);
- DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ + DM9000_iow(dev, DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
/* Move data to DM9000 TX RAM */ - DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ + DM9000_outb(DM9000_MWCMD, priv->io_base); /* Prepare for TX-data */
/* push the data to the TX-fifo */ - (db->outblk)(packet, length); + (priv->outblk)(dev, packet, length);
/* Set TX length to DM9000 */ - DM9000_iow(DM9000_TXPLL, length & 0xff); - DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); + DM9000_iow(dev, DM9000_TXPLL, length & 0xff); + DM9000_iow(dev, DM9000_TXPLH, (length >> 8) & 0xff);
/* Issue TX polling command */ - DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ + DM9000_iow(dev, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
/* wait for end of transmission */ tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; - while (!(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || - !(DM9000_ior(DM9000_ISR) & IMR_PTM)) { + while (!(DM9000_ior(dev, DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || + !(DM9000_ior(dev, DM9000_ISR) & IMR_PTM)) { if (get_timer(0) >= tmo) { printf("transmission timeout\n"); break; } } - DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ + DM9000_iow(dev, DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
DM9000_DBG("transmit done\n\n"); return 0; @@ -443,46 +468,49 @@ static int dm9000_send(struct eth_device *netdev, void *packet, int length) Stop the interface. The interface is stopped when it is brought. */ -static void dm9000_halt(struct eth_device *netdev) +static void dm9000_halt(struct eth_device *dev) { DM9000_DBG("%s\n", __func__);
/* RESET devie */ - dm9000_phy_write(0, 0x8000); /* PHY RESET */ - DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */ - DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */ - DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */ + dm9000_phy_write(dev, 0, 0x8000); /* PHY RESET */ + DM9000_iow(dev, DM9000_GPR, 0x01); /* Power-Down PHY */ + DM9000_iow(dev, DM9000_IMR, 0x80); /* Disable all interrupt */ + DM9000_iow(dev, DM9000_RCR, 0x00); /* Disable RX */ }
/* Received a packet and pass to upper layer */ -static int dm9000_rx(struct eth_device *netdev) +static int dm9000_rx(struct eth_device *dev) { u8 rxbyte; u8 *rdptr = (u8 *)net_rx_packets[0]; u16 rx_status, rx_len = 0; - struct board_info *db = &dm9000_info; + struct dm9000_priv *priv = dev->priv;
/* Check packet ready or not, we must check the ISR status first for DM9000A */ - if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */ + if (!(DM9000_ior(dev, DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */ return 0;
- DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */ + /* clear PR status latched in bit 0 */ + DM9000_iow(dev, DM9000_ISR, 0x01);
/* There is _at least_ 1 package in the fifo, read them all */ for (;;) { - DM9000_ior(DM9000_MRCMDX); /* Dummy read */ + DM9000_ior(dev, DM9000_MRCMDX); /* Dummy read */
/* Get most updated data, only look at bits 0:1, See application notes DM9000 */ - rxbyte = DM9000_inb(DM9000_DATA) & 0x03; + rxbyte = DM9000_inb(priv->data_base) & 0x03;
/* Status check: this byte must be 0 or 1 */ if (rxbyte > DM9000_PKT_RDY) { - DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ - DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ + /* Stop Device */ + DM9000_iow(dev, DM9000_RCR, 0x00); + /* Stop INT request */ + DM9000_iow(dev, DM9000_ISR, 0x80); printf("DM9000 error: status check fail: 0x%x\n", rxbyte); return 0; @@ -494,13 +522,13 @@ static int dm9000_rx(struct eth_device *netdev) DM9000_DBG("receiving packet\n");
/* A packet ready now & Get status/length */ - (db->rx_status)(&rx_status, &rx_len); + (priv->rx_status)(dev, &rx_status, &rx_len);
DM9000_DBG("rx status: 0x%04x rx len: %d\n", rx_status, rx_len);
/* Move data from DM9000 */ /* Read received packet from RX SRAM */ - (db->inblk)(rdptr, rx_len); + (priv->inblk)(dev, rdptr, rx_len);
if ((rx_status & 0xbf00) || (rx_len < 0x40) || (rx_len > DM9000_PKT_MAX)) { @@ -512,7 +540,7 @@ static int dm9000_rx(struct eth_device *netdev) printf("rx length error\n"); if (rx_len > DM9000_PKT_MAX) { printf("rx length too big\n"); - dm9000_reset(); + dm9000_reset(dev); } } else { DM9000_DMP_PACKET(__func__ , rdptr, rx_len); @@ -530,68 +558,77 @@ static int dm9000_rx(struct eth_device *netdev) #if !defined(CONFIG_DM9000_NO_SROM) void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to) { - DM9000_iow(DM9000_EPAR, offset); - DM9000_iow(DM9000_EPCR, 0x4); + DM9000_iow(dev, DM9000_EPAR, offset); + DM9000_iow(dev, DM9000_EPCR, 0x4); udelay(8000); - DM9000_iow(DM9000_EPCR, 0x0); - to[0] = DM9000_ior(DM9000_EPDRL); - to[1] = DM9000_ior(DM9000_EPDRH); + DM9000_iow(dev, DM9000_EPCR, 0x0); + to[0] = DM9000_ior(dev, DM9000_EPDRL); + to[1] = DM9000_ior(dev, DM9000_EPDRH); }
void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val) { - DM9000_iow(DM9000_EPAR, offset); - DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); - DM9000_iow(DM9000_EPDRL, (val & 0xff)); - DM9000_iow(DM9000_EPCR, 0x12); + DM9000_iow(dev, DM9000_EPAR, offset); + DM9000_iow(dev, DM9000_EPDRH, ((val >> 8) & 0xff)); + DM9000_iow(dev, DM9000_EPDRL, (val & 0xff)); + DM9000_iow(dev, DM9000_EPCR, 0x12); udelay(8000); - DM9000_iow(DM9000_EPCR, 0); + DM9000_iow(dev, DM9000_EPCR, 0); } #endif
static void dm9000_get_enetaddr(struct eth_device *dev) { -#if !defined(CONFIG_DM9000_NO_SROM) - int i; - for (i = 0; i < 3; i++) - dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i)); -#endif + struct dm9000_priv *priv = dev->priv; + if (priv->has_srom) { + int i; + for (i = 0; i < 3; i++) + dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i)); + } }
/* Read a byte from I/O port */ static u8 -DM9000_ior(int reg) +DM9000_ior(struct eth_device *dev, int reg) { - DM9000_outb(reg, DM9000_IO); - return DM9000_inb(DM9000_DATA); + struct dm9000_priv *priv = dev->priv; + + DM9000_outb(reg, priv->io_base); + return DM9000_inb(priv->data_base); }
/* Write a byte to I/O port */ static void -DM9000_iow(int reg, u8 value) +DM9000_iow(struct eth_device *dev, int reg, u8 value) { - DM9000_outb(reg, DM9000_IO); - DM9000_outb(value, DM9000_DATA); + struct dm9000_priv *priv = dev->priv; + + DM9000_outb(reg, priv->io_base); + DM9000_outb(value, priv->data_base); }
/* Read a word from phyxcer */ static u16 -dm9000_phy_read(int reg) +dm9000_phy_read(struct eth_device *dev, int reg) { u16 val;
/* Fill the phyxcer register into REG_0C */ - DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); - DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */ - udelay(100); /* Wait read complete */ - DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */ - val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL); + DM9000_iow(dev, DM9000_EPAR, DM9000_PHY | reg); + /* Issue phyxcer read command */ + DM9000_iow(dev, DM9000_EPCR, 0xc); + /* Wait read complete */ + udelay(100); + /* Clear phyxcer read command */ + DM9000_iow(dev, DM9000_EPCR, 0x0); + val = (DM9000_ior(dev, DM9000_EPDRH) << 8) | + DM9000_ior(dev, DM9000_EPDRL);
/* The read data keeps on REG_0D & REG_0E */ DM9000_DBG("dm9000_phy_read(0x%x): 0x%x\n", reg, val); @@ -602,34 +639,55 @@ dm9000_phy_read(int reg) Write a word to phyxcer */ static void -dm9000_phy_write(int reg, u16 value) +dm9000_phy_write(struct eth_device *dev, int reg, u16 value) { /* Fill the phyxcer register into REG_0C */ - DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); + DM9000_iow(dev, DM9000_EPAR, DM9000_PHY | reg);
/* Fill the written data into REG_0D & REG_0E */ - DM9000_iow(DM9000_EPDRL, (value & 0xff)); - DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff)); - DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */ - udelay(500); /* Wait write complete */ - DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ + DM9000_iow(dev, DM9000_EPDRL, (value & 0xff)); + DM9000_iow(dev, DM9000_EPDRH, ((value >> 8) & 0xff)); + /* Issue phyxcer write command */ + DM9000_iow(dev, DM9000_EPCR, 0xa); + /* Wait write complete */ + udelay(500); + /* Clear phyxcer write command */ + DM9000_iow(dev, DM9000_EPCR, 0x0); DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value); }
int dm9000_initialize(u8 dev_num, ulong addr, ulong data, u8 has_srom) { - struct eth_device *dev = &(dm9000_info.netdev); + struct eth_device *dev; + struct dm9000_priv *priv; + + priv = malloc(sizeof(*priv)); + if (!priv) + return 1; + dev = malloc(sizeof(*dev)); + if (!dev) { + free(priv); + return 2; + }
- /* Load MAC address from EEPROM */ - dm9000_get_enetaddr(dev); + memset(dev, 0, sizeof(*dev)); + memset(priv, 0, sizeof(*priv));
+ priv->io_base = addr; + priv->data_base = data; + priv->has_srom = has_srom; + dev->priv = priv; dev->init = dm9000_init; dev->halt = dm9000_halt; dev->send = dm9000_send; dev->recv = dm9000_rx; - sprintf(dev->name, "dm9000"); + if (dev_num > 0) + sprintf(dev->name, "dm9000-%hu", dev_num); + else + sprintf(dev->name, "dm9000");
- eth_register(dev); + /* Load MAC address from EEPROM */ + dm9000_get_enetaddr(dev);
- return 0; + return eth_register(dev); } diff --git a/include/dm9000.h b/include/dm9000.h index 7a7e629..c3c13ce 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -9,11 +9,9 @@ #define __DM9000_H__
/****************** function prototypes **********************/ -#if !defined(CONFIG_DM9000_NO_SROM) struct eth_device;
void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to); -#endif
#endif /* __DM9000_H__ */

Hi Andrew,
On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder andrew.ruder@elecsyscorp.com wrote:
The DM9000 was hard-coded to only support one DM9000 device. This patch changes the initialization function - dm9000_initialize - to support registering multiple (and possibly dynamic) numbers of dm9000 devices. This patch consists of:
- Change the board_info struct to a private struct under eth_device.
- Add io address/data address/srom availability information to this private struct.
- Replace all uses of DM9000_IO/DM9000_DATA with new members, ensure that the eth_device struct propagates down to all helper functions.
- Call dm9000_initialize_ex() with filled in information from the old preprocessor symbols (DM9000_IO, DM9000_DATA, etc.)
Overall the following parameters have been moved over to being a per-chip setting:
DM9000_IO, DM9000_DATA, CONFIG_DM9000_NO_SROM
while the following is still a global setting affecting all chips:
CONFIG_DM9000_BYTE_SWAPPED
And the following has been removed entirely:
CONFIG_DM9000_BASE (was only used in a single printf)
Signed-off-by: Andrew Ruder andrew.ruder@elecsyscorp.com Cc: Joe Hershberger joe.hershberger@gmail.com
drivers/net/dm9000x.c | 382 +++++++++++++++++++++++++++++--------------------- include/dm9000.h | 2 - 2 files changed, 220 insertions(+), 164 deletions(-)
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 9778ef9..d0ea5d7 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -55,6 +55,7 @@ TODO: external MII is not functional, only internal at the moment. #include <asm/io.h> #include <dm9000.h> #include <linux/compiler.h> +#include <malloc.h>
#include "dm9000x.h"
@@ -80,7 +81,9 @@ TODO: external MII is not functional, only internal at the moment. #endif
/* Structure/enum declaration ------------------------------- */ -typedef struct board_info { +struct dm9000_priv {
ulong data_base;
ulong io_base; u32 runt_length_counter; /* counter: RX length < 64byte */ u32 long_length_counter; /* counter: RX length > 1514byte */ u32 reset_counter; /* counter: RESET */
@@ -89,23 +92,22 @@ typedef struct board_info { u16 tx_pkt_cnt; u16 queue_start_addr; u16 dbug_cnt;
u8 has_srom; u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128];
void (*outblk)(void *data_ptr, int count);
void (*inblk)(void *data_ptr, int count);
void (*rx_status)(u16 *rx_status, u16 *rx_len);
struct eth_device netdev;
-} board_info_t; -static board_info_t dm9000_info;
void (*outblk)(struct eth_device *dev, void *data_ptr, int count);
void (*inblk)(struct eth_device *dev, void *data_ptr, int count);
void (*rx_status)(struct eth_device *dev, u16 *rx_status, u16 *rx_len);
It will be much better to pass the priv ptr to all the functions instead of eth_device. It appears that every place you added it you simply dereference dev->priv. For the cases where you actually need a member of eth_device you should pas that as a separate parameter pointer.
The reason for this is the eth_device structure is going away. In the driver model implementation everything is a udevice pointer. You still have your priv inside there, so that's the thing to pass around. It will make far less churn when adding driver model support to DM9000.
+};
/* function declaration ------------------------------------- */ -static int dm9000_probe(void); -static u16 dm9000_phy_read(int); -static void dm9000_phy_write(int, u16); -static u8 DM9000_ior(int); -static void DM9000_iow(int reg, u8 value); +static int dm9000_probe(struct eth_device *); +static u16 dm9000_phy_read(struct eth_device *, int); +static void dm9000_phy_write(struct eth_device *, int, u16); +static u8 DM9000_ior(struct eth_device *, int); +static void DM9000_iow(struct eth_device *, int reg, u8 value);
Please include the parameter names in the prototypes.
/* DM9000 network board routine ---------------------------- */ #ifndef CONFIG_DM9000_BYTE_SWAPPED @@ -126,125 +128,147 @@ static void DM9000_iow(int reg, u8 value);
#ifdef CONFIG_DM9000_DEBUG static __maybe_unused void -dump_regs(void) +dump_regs(struct eth_device *dev) { DM9000_DBG("\n");
DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0));
DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1));
DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2));
DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3));
DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5));
DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6));
DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR));
DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(dev, 0));
DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(dev, 1));
DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(dev, 2));
DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(dev, 3));
DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(dev, 4));
DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(dev, 5));
DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(dev, 6));
DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(dev, DM9000_ISR)); DM9000_DBG("\n");
} #endif
-static void dm9000_outblk_8bit(void *data_ptr, int count) +static void +dm9000_outblk_8bit(struct eth_device *dev, void *data_ptr, int count) { int i;
struct dm9000_priv *priv = dev->priv; for (i = 0; i < count; i++)
DM9000_outb((((u8 *)data_ptr)[i] & 0xff), DM9000_DATA);
DM9000_outb((((u8 *)data_ptr)[i] & 0xff), priv->data_base);
}
-static void dm9000_outblk_16bit(void *data_ptr, int count) +static void +dm9000_outblk_16bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2;
struct dm9000_priv *priv = dev->priv; for (i = 0; i < tmplen; i++)
DM9000_outw(((u16 *)data_ptr)[i], DM9000_DATA);
DM9000_outw(((u16 *)data_ptr)[i], priv->data_base);
} -static void dm9000_outblk_32bit(void *data_ptr, int count) +static void +dm9000_outblk_32bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4;
struct dm9000_priv *priv = dev->priv; for (i = 0; i < tmplen; i++)
DM9000_outl(((u32 *)data_ptr)[i], DM9000_DATA);
DM9000_outl(((u32 *)data_ptr)[i], priv->data_base);
}
-static void dm9000_inblk_8bit(void *data_ptr, int count) +static void +dm9000_inblk_8bit(struct eth_device *dev, void *data_ptr, int count) { int i;
struct dm9000_priv *priv = dev->priv;
for (i = 0; i < count; i++)
((u8 *)data_ptr)[i] = DM9000_inb(DM9000_DATA);
((u8 *)data_ptr)[i] = DM9000_inb(priv->data_base);
}
-static void dm9000_inblk_16bit(void *data_ptr, int count) +static void +dm9000_inblk_16bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2;
struct dm9000_priv *priv = dev->priv; for (i = 0; i < tmplen; i++)
((u16 *)data_ptr)[i] = DM9000_inw(DM9000_DATA);
((u16 *)data_ptr)[i] = DM9000_inw(priv->data_base);
} -static void dm9000_inblk_32bit(void *data_ptr, int count) +static void +dm9000_inblk_32bit(struct eth_device *dev, void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4;
struct dm9000_priv *priv = dev->priv; for (i = 0; i < tmplen; i++)
((u32 *)data_ptr)[i] = DM9000_inl(DM9000_DATA);
((u32 *)data_ptr)[i] = DM9000_inl(priv->data_base);
}
-static void dm9000_rx_status_32bit(u16 *rx_status, u16 *rx_len) +static void +dm9000_rx_status_32bit(struct eth_device *dev, u16 *rx_status, u16 *rx_len) { u32 tmpdata;
struct dm9000_priv *priv = dev->priv;
DM9000_outb(DM9000_MRCMD, DM9000_IO);
DM9000_outb(DM9000_MRCMD, priv->io_base);
tmpdata = DM9000_inl(DM9000_DATA);
tmpdata = DM9000_inl(priv->data_base); *rx_status = __le16_to_cpu(tmpdata); *rx_len = __le16_to_cpu(tmpdata >> 16);
}
-static void dm9000_rx_status_16bit(u16 *rx_status, u16 *rx_len) +static void +dm9000_rx_status_16bit(struct eth_device *dev, u16 *rx_status, u16 *rx_len) {
DM9000_outb(DM9000_MRCMD, DM9000_IO);
struct dm9000_priv *priv = dev->priv;
*rx_status = __le16_to_cpu(DM9000_inw(DM9000_DATA));
*rx_len = __le16_to_cpu(DM9000_inw(DM9000_DATA));
DM9000_outb(DM9000_MRCMD, priv->io_base);
*rx_status = __le16_to_cpu(DM9000_inw(priv->data_base));
*rx_len = __le16_to_cpu(DM9000_inw(priv->data_base));
}
-static void dm9000_rx_status_8bit(u16 *rx_status, u16 *rx_len) +static void +dm9000_rx_status_8bit(struct eth_device *dev, u16 *rx_status, u16 *rx_len) {
DM9000_outb(DM9000_MRCMD, DM9000_IO);
struct dm9000_priv *priv = dev->priv;
DM9000_outb(DM9000_MRCMD, priv->io_base); *rx_status =
__le16_to_cpu(DM9000_inb(DM9000_DATA) +
(DM9000_inb(DM9000_DATA) << 8));
__le16_to_cpu(DM9000_inb(priv->data_base) +
(DM9000_inb(priv->data_base) << 8)); *rx_len =
__le16_to_cpu(DM9000_inb(DM9000_DATA) +
(DM9000_inb(DM9000_DATA) << 8));
__le16_to_cpu(DM9000_inb(priv->data_base) +
(DM9000_inb(priv->data_base) << 8));
}
/* Search DM9000 board, allocate space and register it */ int -dm9000_probe(void) +dm9000_probe(struct eth_device *dev) {
struct dm9000_priv *priv = dev->priv; u32 id_val;
id_val = DM9000_ior(DM9000_VIDL);
id_val |= DM9000_ior(DM9000_VIDH) << 8;
id_val |= DM9000_ior(DM9000_PIDL) << 16;
id_val |= DM9000_ior(DM9000_PIDH) << 24;
id_val = DM9000_ior(dev, DM9000_VIDL);
id_val |= DM9000_ior(dev, DM9000_VIDH) << 8;
id_val |= DM9000_ior(dev, DM9000_PIDL) << 16;
id_val |= DM9000_ior(dev, DM9000_PIDH) << 24; if (id_val == DM9000_ID) {
printf("dm9000 i/o: 0x%x, id: 0x%x\n", CONFIG_DM9000_BASE,
printf("dm9000 i/o: 0x%lx, id: 0x%x\n", priv->io_base, id_val); return 0; } else {
printf("dm9000 not found at 0x%08x id: 0x%08x\n",
CONFIG_DM9000_BASE, id_val);
printf("dm9000 not found at 0x%08lx id: 0x%08x\n",
priv->io_base, id_val); return -1; }
}
/* General Purpose dm9000 reset routine */ static void -dm9000_reset(void) +dm9000_reset(struct eth_device *dev) { DM9000_DBG("resetting DM9000\n");
@@ -252,29 +276,29 @@ dm9000_reset(void) see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */
/* DEBUG: Make all GPIO0 outputs, all others inputs */
DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);
DM9000_iow(dev, DM9000_GPCR, GPCR_GPIO0_OUT); /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */
DM9000_iow(DM9000_GPR, 0);
DM9000_iow(dev, DM9000_GPR, 0); /* Step 2: Software reset */
DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
DM9000_iow(dev, DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); do { DM9000_DBG("resetting the DM9000, 1st reset\n"); udelay(25); /* Wait at least 20 us */
} while (DM9000_ior(DM9000_NCR) & 1);
} while (DM9000_ior(dev, DM9000_NCR) & 1);
DM9000_iow(DM9000_NCR, 0);
DM9000_iow(dev, DM9000_NCR, 0); /* Issue a second reset */
DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
DM9000_iow(dev, DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); do { DM9000_DBG("resetting the DM9000, 2nd reset\n"); udelay(25); /* Wait at least 20 us */
} while (DM9000_ior(DM9000_NCR) & 1);
} while (DM9000_ior(dev, DM9000_NCR) & 1); /* Check whether the ethernet controller is present */
if ((DM9000_ior(DM9000_PIDL) != 0x0) ||
(DM9000_ior(DM9000_PIDH) != 0x90))
if ((DM9000_ior(dev, DM9000_PIDL) != 0x0) ||
(DM9000_ior(dev, DM9000_PIDH) != 0x90)) printf("ERROR: resetting DM9000 -> not responding\n");
}
@@ -284,63 +308,63 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) { int i, oft, lnk; u8 io_mode;
struct board_info *db = &dm9000_info;
struct dm9000_priv *priv = dev->priv; DM9000_DBG("%s\n", __func__); /* RESET device */
dm9000_reset();
dm9000_reset(dev);
if (dm9000_probe() < 0)
if (dm9000_probe(dev) < 0) return -1; /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */
io_mode = DM9000_ior(DM9000_ISR) >> 6;
io_mode = DM9000_ior(dev, DM9000_ISR) >> 6; switch (io_mode) { case 0x0: /* 16-bit mode */ printf("DM9000: running in 16 bit mode\n");
db->outblk = dm9000_outblk_16bit;
db->inblk = dm9000_inblk_16bit;
db->rx_status = dm9000_rx_status_16bit;
priv->outblk = dm9000_outblk_16bit;
priv->inblk = dm9000_inblk_16bit;
priv->rx_status = dm9000_rx_status_16bit; break; case 0x01: /* 32-bit mode */ printf("DM9000: running in 32 bit mode\n");
db->outblk = dm9000_outblk_32bit;
db->inblk = dm9000_inblk_32bit;
db->rx_status = dm9000_rx_status_32bit;
priv->outblk = dm9000_outblk_32bit;
priv->inblk = dm9000_inblk_32bit;
priv->rx_status = dm9000_rx_status_32bit; break; case 0x02: /* 8 bit mode */ printf("DM9000: running in 8 bit mode\n");
db->outblk = dm9000_outblk_8bit;
db->inblk = dm9000_inblk_8bit;
db->rx_status = dm9000_rx_status_8bit;
priv->outblk = dm9000_outblk_8bit;
priv->inblk = dm9000_inblk_8bit;
priv->rx_status = dm9000_rx_status_8bit; break; default: /* Assume 8 bit mode, will probably not work anyway */ printf("DM9000: Undefined IO-mode:0x%x\n", io_mode);
db->outblk = dm9000_outblk_8bit;
db->inblk = dm9000_inblk_8bit;
db->rx_status = dm9000_rx_status_8bit;
priv->outblk = dm9000_outblk_8bit;
priv->inblk = dm9000_inblk_8bit;
priv->rx_status = dm9000_rx_status_8bit; break; } /* Program operating register, only internal phy supported */
DM9000_iow(DM9000_NCR, 0x0);
DM9000_iow(dev, DM9000_NCR, 0x0); /* TX Polling clear */
DM9000_iow(DM9000_TCR, 0);
DM9000_iow(dev, DM9000_TCR, 0); /* Less 3Kb, 200us */
DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US);
DM9000_iow(dev, DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US); /* Flow Control : High/Low Water */
DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));
DM9000_iow(dev, DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* SH FIXME: This looks strange! Flow Control */
DM9000_iow(DM9000_FCR, 0x0);
DM9000_iow(dev, DM9000_FCR, 0x0); /* Special Mode */
DM9000_iow(DM9000_SMCR, 0);
DM9000_iow(dev, DM9000_SMCR, 0); /* clear TX status */
DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
DM9000_iow(dev, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* Clear interrupt status */
DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
DM9000_iow(dev, DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); printf("MAC: %pM\n", dev->enetaddr); if (!is_valid_ethaddr(dev->enetaddr)) {
@@ -349,23 +373,24 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd)
/* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
DM9000_iow(oft, dev->enetaddr[i]);
DM9000_iow(dev, oft, dev->enetaddr[i]); for (i = 0, oft = 0x16; i < 8; i++, oft++)
DM9000_iow(oft, 0xff);
DM9000_iow(dev, oft, 0xff); /* read back mac, just to be sure */ for (i = 0, oft = 0x10; i < 6; i++, oft++)
DM9000_DBG("%02x:", DM9000_ior(oft));
DM9000_DBG("%02x:", DM9000_ior(dev, oft)); DM9000_DBG("\n");
All this MAC address handling should be implemented in the write_hwaddr() op in the eth_device structure. If you feel like adding a patch to the end of this series to move it that would be great!
You may also want to move the reset to the _initialize() function instead of the init() op. I assume that resetting will clear the ethaddr that's configured. If you decide to leave the reset in the init() op, you'll need to call the new write_hwaddr() op yourself here as well as register it. Hopefully this will all get better when the network stack is smarter and doesn't call the init() op for each command.
/* Activate DM9000 */ /* RX enable */
DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
DM9000_iow(dev, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* Enable TX/RX interrupt mask */
DM9000_iow(DM9000_IMR, IMR_PAR);
DM9000_iow(dev, DM9000_IMR, IMR_PAR); i = 0;
while (!(dm9000_phy_read(1) & 0x20)) { /* autonegation complete bit */
while (!(dm9000_phy_read(dev, 1) & 0x20)) {
/* autonegation complete bit */ udelay(1000); i++; if (i == 10000) {
@@ -375,7 +400,7 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) }
/* see what we've got */
lnk = dm9000_phy_read(17) >> 12;
lnk = dm9000_phy_read(dev, 17) >> 12; printf("operating at "); switch (lnk) { case 1:
@@ -402,38 +427,38 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) Hardware start transmission. Send a packet to media from the upper layer. */ -static int dm9000_send(struct eth_device *netdev, void *packet, int length) +static int dm9000_send(struct eth_device *dev, void *packet, int length) { int tmo;
struct board_info *db = &dm9000_info;
struct dm9000_priv *priv = dev->priv; DM9000_DMP_PACKET(__func__ , packet, length);
DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
DM9000_iow(dev, DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ /* Move data to DM9000 TX RAM */
DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */
DM9000_outb(DM9000_MWCMD, priv->io_base); /* Prepare for TX-data */ /* push the data to the TX-fifo */
(db->outblk)(packet, length);
(priv->outblk)(dev, packet, length); /* Set TX length to DM9000 */
DM9000_iow(DM9000_TXPLL, length & 0xff);
DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
DM9000_iow(dev, DM9000_TXPLL, length & 0xff);
DM9000_iow(dev, DM9000_TXPLH, (length >> 8) & 0xff); /* Issue TX polling command */
DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
DM9000_iow(dev, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ /* wait for end of transmission */ tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
while (!(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) ||
!(DM9000_ior(DM9000_ISR) & IMR_PTM)) {
while (!(DM9000_ior(dev, DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) ||
!(DM9000_ior(dev, DM9000_ISR) & IMR_PTM)) { if (get_timer(0) >= tmo) { printf("transmission timeout\n"); break; } }
DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
DM9000_iow(dev, DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ DM9000_DBG("transmit done\n\n"); return 0;
@@ -443,46 +468,49 @@ static int dm9000_send(struct eth_device *netdev, void *packet, int length) Stop the interface. The interface is stopped when it is brought. */ -static void dm9000_halt(struct eth_device *netdev) +static void dm9000_halt(struct eth_device *dev) { DM9000_DBG("%s\n", __func__);
/* RESET devie */
dm9000_phy_write(0, 0x8000); /* PHY RESET */
DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
dm9000_phy_write(dev, 0, 0x8000); /* PHY RESET */
DM9000_iow(dev, DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(dev, DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(dev, DM9000_RCR, 0x00); /* Disable RX */
}
/* Received a packet and pass to upper layer */ -static int dm9000_rx(struct eth_device *netdev) +static int dm9000_rx(struct eth_device *dev) { u8 rxbyte; u8 *rdptr = (u8 *)net_rx_packets[0]; u16 rx_status, rx_len = 0;
struct board_info *db = &dm9000_info;
struct dm9000_priv *priv = dev->priv; /* Check packet ready or not, we must check the ISR status first for DM9000A */
if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */
if (!(DM9000_ior(dev, DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */ return 0;
DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */
/* clear PR status latched in bit 0 */
DM9000_iow(dev, DM9000_ISR, 0x01); /* There is _at least_ 1 package in the fifo, read them all */ for (;;) {
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
DM9000_ior(dev, DM9000_MRCMDX); /* Dummy read */ /* Get most updated data, only look at bits 0:1, See application notes DM9000 */
rxbyte = DM9000_inb(DM9000_DATA) & 0x03;
rxbyte = DM9000_inb(priv->data_base) & 0x03; /* Status check: this byte must be 0 or 1 */ if (rxbyte > DM9000_PKT_RDY) {
DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
/* Stop Device */
DM9000_iow(dev, DM9000_RCR, 0x00);
/* Stop INT request */
DM9000_iow(dev, DM9000_ISR, 0x80); printf("DM9000 error: status check fail: 0x%x\n", rxbyte); return 0;
@@ -494,13 +522,13 @@ static int dm9000_rx(struct eth_device *netdev) DM9000_DBG("receiving packet\n");
/* A packet ready now & Get status/length */
(db->rx_status)(&rx_status, &rx_len);
(priv->rx_status)(dev, &rx_status, &rx_len); DM9000_DBG("rx status: 0x%04x rx len: %d\n", rx_status, rx_len); /* Move data from DM9000 */ /* Read received packet from RX SRAM */
(db->inblk)(rdptr, rx_len);
(priv->inblk)(dev, rdptr, rx_len); if ((rx_status & 0xbf00) || (rx_len < 0x40) || (rx_len > DM9000_PKT_MAX)) {
@@ -512,7 +540,7 @@ static int dm9000_rx(struct eth_device *netdev) printf("rx length error\n"); if (rx_len > DM9000_PKT_MAX) { printf("rx length too big\n");
dm9000_reset();
dm9000_reset(dev); } } else { DM9000_DMP_PACKET(__func__ , rdptr, rx_len);
@@ -530,68 +558,77 @@ static int dm9000_rx(struct eth_device *netdev) #if !defined(CONFIG_DM9000_NO_SROM) void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to) {
DM9000_iow(DM9000_EPAR, offset);
DM9000_iow(DM9000_EPCR, 0x4);
DM9000_iow(dev, DM9000_EPAR, offset);
DM9000_iow(dev, DM9000_EPCR, 0x4); udelay(8000);
DM9000_iow(DM9000_EPCR, 0x0);
to[0] = DM9000_ior(DM9000_EPDRL);
to[1] = DM9000_ior(DM9000_EPDRH);
DM9000_iow(dev, DM9000_EPCR, 0x0);
to[0] = DM9000_ior(dev, DM9000_EPDRL);
to[1] = DM9000_ior(dev, DM9000_EPDRH);
}
void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val) {
DM9000_iow(DM9000_EPAR, offset);
DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
DM9000_iow(DM9000_EPDRL, (val & 0xff));
DM9000_iow(DM9000_EPCR, 0x12);
DM9000_iow(dev, DM9000_EPAR, offset);
DM9000_iow(dev, DM9000_EPDRH, ((val >> 8) & 0xff));
DM9000_iow(dev, DM9000_EPDRL, (val & 0xff));
DM9000_iow(dev, DM9000_EPCR, 0x12); udelay(8000);
DM9000_iow(DM9000_EPCR, 0);
DM9000_iow(dev, DM9000_EPCR, 0);
} #endif
static void dm9000_get_enetaddr(struct eth_device *dev) {
This is an example where you can pass in a pointer to the enetaddr member of the eth_device.
-#if !defined(CONFIG_DM9000_NO_SROM)
int i;
for (i = 0; i < 3; i++)
dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i));
-#endif
struct dm9000_priv *priv = dev->priv;
Don't forget to add a blank line between variable definitions and other code.
if (priv->has_srom) {
int i;
Same here.
for (i = 0; i < 3; i++)
dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i));
}
}
/* Read a byte from I/O port */ static u8 -DM9000_ior(int reg) +DM9000_ior(struct eth_device *dev, int reg) {
DM9000_outb(reg, DM9000_IO);
return DM9000_inb(DM9000_DATA);
struct dm9000_priv *priv = dev->priv;
DM9000_outb(reg, priv->io_base);
return DM9000_inb(priv->data_base);
}
/* Write a byte to I/O port */ static void -DM9000_iow(int reg, u8 value) +DM9000_iow(struct eth_device *dev, int reg, u8 value) {
DM9000_outb(reg, DM9000_IO);
DM9000_outb(value, DM9000_DATA);
struct dm9000_priv *priv = dev->priv;
DM9000_outb(reg, priv->io_base);
DM9000_outb(value, priv->data_base);
}
/* Read a word from phyxcer */ static u16 -dm9000_phy_read(int reg) +dm9000_phy_read(struct eth_device *dev, int reg) { u16 val;
/* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
udelay(100); /* Wait read complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
DM9000_iow(dev, DM9000_EPAR, DM9000_PHY | reg);
/* Issue phyxcer read command */
DM9000_iow(dev, DM9000_EPCR, 0xc);
/* Wait read complete */
udelay(100);
/* Clear phyxcer read command */
DM9000_iow(dev, DM9000_EPCR, 0x0);
val = (DM9000_ior(dev, DM9000_EPDRH) << 8) |
DM9000_ior(dev, DM9000_EPDRL); /* The read data keeps on REG_0D & REG_0E */ DM9000_DBG("dm9000_phy_read(0x%x): 0x%x\n", reg, val);
@@ -602,34 +639,55 @@ dm9000_phy_read(int reg) Write a word to phyxcer */ static void -dm9000_phy_write(int reg, u16 value) +dm9000_phy_write(struct eth_device *dev, int reg, u16 value) { /* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
DM9000_iow(dev, DM9000_EPAR, DM9000_PHY | reg); /* Fill the written data into REG_0D & REG_0E */
DM9000_iow(DM9000_EPDRL, (value & 0xff));
DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
udelay(500); /* Wait write complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
DM9000_iow(dev, DM9000_EPDRL, (value & 0xff));
DM9000_iow(dev, DM9000_EPDRH, ((value >> 8) & 0xff));
/* Issue phyxcer write command */
DM9000_iow(dev, DM9000_EPCR, 0xa);
/* Wait write complete */
udelay(500);
/* Clear phyxcer write command */
DM9000_iow(dev, DM9000_EPCR, 0x0); DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value);
}
int dm9000_initialize(u8 dev_num, ulong addr, ulong data, u8 has_srom) {
If only priv is passed around, then most likely this is the only function that needs to change to support driver model.
struct eth_device *dev = &(dm9000_info.netdev);
struct eth_device *dev;
struct dm9000_priv *priv;
priv = malloc(sizeof(*priv));
if (!priv)
return 1;
dev = malloc(sizeof(*dev));
if (!dev) {
free(priv);
return 2;
}
/* Load MAC address from EEPROM */
dm9000_get_enetaddr(dev);
memset(dev, 0, sizeof(*dev));
memset(priv, 0, sizeof(*priv));
priv->io_base = addr;
priv->data_base = data;
priv->has_srom = has_srom;
dev->priv = priv; dev->init = dm9000_init; dev->halt = dm9000_halt; dev->send = dm9000_send; dev->recv = dm9000_rx;
sprintf(dev->name, "dm9000");
if (dev_num > 0)
sprintf(dev->name, "dm9000-%hu", dev_num);
else
sprintf(dev->name, "dm9000");
eth_register(dev);
/* Load MAC address from EEPROM */
dm9000_get_enetaddr(dev);
return 0;
return eth_register(dev);
} diff --git a/include/dm9000.h b/include/dm9000.h index 7a7e629..c3c13ce 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -9,11 +9,9 @@ #define __DM9000_H__
/****************** function prototypes **********************/ -#if !defined(CONFIG_DM9000_NO_SROM) struct eth_device;
void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to); -#endif
#endif /* __DM9000_H__ */
2.1.4

On 08/12/2015 12:24 PM, Andrew Ruder wrote:
To maintain backwards compatibility with older board files, we add a new initialize function taking the io address, data address, and availability of a SROM chip. The old initialize function is now a shim around this new initialize function but provides the parameters based on the old DM9000 preprocessor symbols.
Uh, this is not true. Forgot to remove this paragraph from the cover letter. There is just a single dm9000_initialize() function that has been updated in every board file.
participants (4)
-
Andrew Ruder
-
Andrew Ruder
-
Joe Hershberger
-
Marcel Ziswiler