From 4cd8ed40615a7d741ef2f09ee53779ec6907b8a6 Mon Sep 17 00:00:00 2001 From: Ben Warren Date: Tue, 9 Dec 2008 23:26:31 -0800 Subject: Fix compile error in building MBX860T. Bug was introduced in 9eb79bd8856bcab896ed5e1f1bca159807a124dd Signed-off-by: Ben Warren diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 40f81ef..2eb848b 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -644,7 +644,7 @@ void reset_8xx_watchdog (volatile immap_t * immr) */ int cpu_eth_init(bd_t *bis) { -#if defined(SCC_ENET) +#if defined(SCC_ENET) && defined(CONFIG_CMD_NET) scc_initialize(bis); #endif #if defined(FEC_ENET) -- cgit v0.10.2 From 8b69b563039989885969d24465c56f8ac4c07c4c Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Thu, 20 Nov 2008 09:57:14 +0100 Subject: powerpc: net: support for the SMSC LAN8700 PHY Signed-off-by: Heiko Schocher Signed-off-by: Ben Warren diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index 829f082..d613f3e 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -603,6 +603,55 @@ static int fixed_phy_read_status (struct uec_mii_info *mii_info) return 0; } +static int smsc_config_aneg (struct uec_mii_info *mii_info) +{ + return 0; +} + +static int smsc_read_status (struct uec_mii_info *mii_info) +{ + u16 status; + int err; + + /* Update the link, but return if there + * was an error */ + err = genmii_update_link (mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + int val; + + status = phy_read (mii_info, 0x1f); + val = (status & 0x1c) >> 2; + + switch (val) { + case 1: + mii_info->duplex = DUPLEX_HALF; + mii_info->speed = SPEED_10; + break; + case 5: + mii_info->duplex = DUPLEX_FULL; + mii_info->speed = SPEED_10; + break; + case 2: + mii_info->duplex = DUPLEX_HALF; + mii_info->speed = SPEED_100; + break; + case 6: + mii_info->duplex = DUPLEX_FULL; + mii_info->speed = SPEED_100; + break; + } + mii_info->pause = 0; + } + + return 0; +} + static struct phy_info phy_info_dm9161 = { .phy_id = 0x0181b880, .phy_id_mask = 0x0ffffff0, @@ -655,6 +704,15 @@ static struct phy_info phy_info_fixedphy = { .read_status = fixed_phy_read_status, }; +static struct phy_info phy_info_smsclan8700 = { + .phy_id = 0x0007c0c0, + .phy_id_mask = 0xfffffff0, + .name = "SMSC LAN8700", + .features = MII_BASIC_FEATURES, + .config_aneg = smsc_config_aneg, + .read_status = smsc_read_status, +}; + static struct phy_info phy_info_genmii = { .phy_id = 0x00000000, .phy_id_mask = 0x00000000, @@ -669,6 +727,7 @@ static struct phy_info *phy_info[] = { &phy_info_dm9161a, &phy_info_marvell, &phy_info_bcm5481, + &phy_info_smsclan8700, &phy_info_fixedphy, &phy_info_genmii, NULL -- cgit v0.10.2 From 890a02e8ee6b8c26a6e3e505e1a2d29cd73aa6f6 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 12 Nov 2008 13:31:02 +0100 Subject: net: smc911x: Make register read/write functions weak This patch changes the reg_read/_write to smc911x_reg_read/_write and defines then as weak so that they can be overridden by board specific version. This will be used by the upcoming VCTH board support. Signed-off-by: Stefan Roese Signed-off-by: Ben Warren diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 648c94c..6c5a4b3 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -34,21 +34,24 @@ #endif #if defined (CONFIG_DRIVER_SMC911X_32_BIT) -static inline u32 reg_read(u32 addr) +static inline u32 __smc911x_reg_read(u32 addr) { return *(volatile u32*)addr; } -static inline void reg_write(u32 addr, u32 val) +u32 smc911x_reg_read(u32 addr) __attribute__((weak, alias("__smc911x_reg_read"))); + +static inline void __smc911x_reg_write(u32 addr, u32 val) { *(volatile u32*)addr = val; } +void smc911x_reg_write(u32 addr, u32 val) __attribute__((weak, alias("__smc911x_reg_write"))); #elif defined (CONFIG_DRIVER_SMC911X_16_BIT) -static inline u32 reg_read(u32 addr) +static inline u32 smc911x_reg_read(u32 addr) { volatile u16 *addr_16 = (u16 *)addr; return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); } -static inline void reg_write(u32 addr, u32 val) +static inline void smc911x_reg_write(u32 addr, u32 val) { *(volatile u16*)addr = (u16)val; *(volatile u16*)(addr + 2) = (u16)(val >> 16); @@ -58,9 +61,9 @@ static inline void reg_write(u32 addr, u32 val) #endif /* CONFIG_DRIVER_SMC911X_16_BIT */ u32 pkt_data_pull(u32 addr) \ - __attribute__ ((weak, alias ("reg_read"))); + __attribute__ ((weak, alias ("smc911x_reg_read"))); void pkt_data_push(u32 addr, u32 val) \ - __attribute__ ((weak, alias ("reg_write"))); + __attribute__ ((weak, alias ("smc911x_reg_write"))); #define mdelay(n) udelay((n)*1000) @@ -407,22 +410,22 @@ static const struct chip_id chip_ids[] = { u32 smc911x_get_mac_csr(u8 reg) { - while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); - while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + smc911x_reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); + while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - return reg_read(MAC_CSR_DATA); + return smc911x_reg_read(MAC_CSR_DATA); } void smc911x_set_mac_csr(u8 reg, u32 data) { - while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - reg_write(MAC_CSR_DATA, data); - reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); - while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) + smc911x_reg_write(MAC_CSR_DATA, data); + smc911x_reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); + while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; } @@ -496,10 +499,10 @@ static int smc911x_phy_reset(void) { u32 reg; - reg = reg_read(PMT_CTRL); + reg = smc911x_reg_read(PMT_CTRL); reg &= ~0xfffff030; reg |= PMT_CTRL_PHY_RST; - reg_write(PMT_CTRL, reg); + smc911x_reg_write(PMT_CTRL, reg); mdelay(100); @@ -541,13 +544,13 @@ static void smc911x_reset(void) int timeout; /* Take out of PM setting first */ - if (reg_read(PMT_CTRL) & PMT_CTRL_READY) { + if (smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY) { /* Write to the bytetest will take out of powerdown */ - reg_write(BYTE_TEST, 0x0); + smc911x_reg_write(BYTE_TEST, 0x0); timeout = 10; - while (timeout-- && !(reg_read(PMT_CTRL) & PMT_CTRL_READY)) + while (timeout-- && !(smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY)) udelay(10); if (!timeout) { printf(DRIVERNAME @@ -557,12 +560,12 @@ static void smc911x_reset(void) } /* Disable interrupts */ - reg_write(INT_EN, 0); + smc911x_reg_write(INT_EN, 0); - reg_write(HW_CFG, HW_CFG_SRST); + smc911x_reg_write(HW_CFG, HW_CFG_SRST); timeout = 1000; - while (timeout-- && reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY) + while (timeout-- && smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY) udelay(10); if (!timeout) { @@ -572,23 +575,23 @@ static void smc911x_reset(void) /* Reset the FIFO level and flow control settings */ smc911x_set_mac_csr(FLOW, FLOW_FCPT | FLOW_FCEN); - reg_write(AFC_CFG, 0x0050287F); + smc911x_reg_write(AFC_CFG, 0x0050287F); /* Set to LED outputs */ - reg_write(GPIO_CFG, 0x70070000); + smc911x_reg_write(GPIO_CFG, 0x70070000); } static void smc911x_enable(void) { /* Enable TX */ - reg_write(HW_CFG, 8 << 16 | HW_CFG_SF); + smc911x_reg_write(HW_CFG, 8 << 16 | HW_CFG_SF); - reg_write(GPT_CFG, GPT_CFG_TIMER_EN | 10000); + smc911x_reg_write(GPT_CFG, GPT_CFG_TIMER_EN | 10000); - reg_write(TX_CFG, TX_CFG_TX_ON); + smc911x_reg_write(TX_CFG, TX_CFG_TX_ON); /* no padding to start of packets */ - reg_write(RX_CFG, 0); + smc911x_reg_write(RX_CFG, 0); smc911x_set_mac_csr(MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); @@ -600,13 +603,13 @@ int eth_init(bd_t *bd) printf(DRIVERNAME ": initializing\n"); - val = reg_read(BYTE_TEST); + val = smc911x_reg_read(BYTE_TEST); if (val != 0x87654321) { printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val); goto err_out; } - val = reg_read(ID_REV) >> 16; + val = smc911x_reg_read(ID_REV) >> 16; for (i = 0; chip_ids[i].id != 0; i++) { if (chip_ids[i].id == val) break; } @@ -640,8 +643,8 @@ int eth_send(volatile void *packet, int length) u32 tmplen; u32 status; - reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); - reg_write(TX_DATA_FIFO, length); + smc911x_reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); + smc911x_reg_write(TX_DATA_FIFO, length); tmplen = (length + 3) / 4; @@ -649,12 +652,12 @@ int eth_send(volatile void *packet, int length) pkt_data_push(TX_DATA_FIFO, *data++); /* wait for transmission */ - while (!((reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16)); + while (!((smc911x_reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16)); /* get status. Ignore 'no carrier' error, it has no meaning for * full duplex operation */ - status = reg_read(TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL | + status = smc911x_reg_read(TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL | TX_STS_MANY_DEFER | TX_STS_UNDERRUN); if (!status) @@ -681,11 +684,11 @@ int eth_rx(void) u32 pktlen, tmplen; u32 status; - if ((reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { - status = reg_read(RX_STATUS_FIFO); + if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { + status = smc911x_reg_read(RX_STATUS_FIFO); pktlen = (status & RX_STS_PKT_LEN) >> 16; - reg_write(RX_CFG, 0); + smc911x_reg_write(RX_CFG, 0); tmplen = (pktlen + 2+ 3) / 4; while (tmplen--) -- cgit v0.10.2 From bd3980cc095af1728b994cdd8bf1ac430b6289e6 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 21 Nov 2008 12:04:18 +0900 Subject: sh: sh_eth: Change new network API sh_eth used old network API. This patch changed new API. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Ben Warren diff --git a/cpu/sh4/cpu.c b/cpu/sh4/cpu.c index d94e139..52b6cfd 100644 --- a/cpu/sh4/cpu.c +++ b/cpu/sh4/cpu.c @@ -82,3 +82,11 @@ int dcache_status (void) { return 0; } + +int cpu_eth_init(bd_t *bis) +{ +#ifdef CONFIG_SH_ETHER + sh_eth_initialize(bis); +#endif + return 0; +} diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 9e3cf98..ebe8588 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -36,12 +37,7 @@ # error "Please define CONFIG_SH_ETHER_PHY_ADDR" #endif -extern int eth_init(bd_t *bd); -extern void eth_halt(void); -extern int eth_rx(void); -extern int eth_send(volatile void *packet, int length); - -static struct dev_info_s *dev; +#define SH_ETH_PHY_DELAY 50000 /* * Bits are written to the PHY serially using the @@ -89,7 +85,7 @@ static void sh_eth_mii_ind_bus_release(int port) udelay(1); } -static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len) +static void sh_eth_mii_read_phy_bits(int port, u32 *val, int len) { int i; u32 pir; @@ -106,8 +102,6 @@ static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len) outl(0, PIR(port)); udelay(1); } - - return 0; } #define PHY_INIT 0xFFFFFFFF @@ -183,26 +177,23 @@ static void sh_eth_mii_write_phy_reg(int port, u8 phy_addr, int reg, u16 val) sh_eth_mii_ind_bus_release(port); } -void eth_halt(void) -{ -} - -int eth_send(volatile void *packet, int len) +int sh_eth_send(struct eth_device *dev, volatile void *packet, int len) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; - int timeout; - int rc = 0; + struct sh_eth_dev *eth = dev->priv; + int port = eth->port, ret = 0, timeout; + struct sh_eth_info *port_info = ð->port_info[port]; if (!packet || len > 0xffff) { - printf("eth_send: Invalid argument\n"); - return -EINVAL; + printf(SHETHER_NAME ": %s: Invalid argument\n", __func__); + ret = -EINVAL; + goto err; } /* packet must be a 4 byte boundary */ if ((int)packet & (4 - 1)) { - printf("eth_send: packet not 4 byte alligned\n"); - return -EFAULT; + printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__); + ret = -EFAULT; + goto err; } /* Update tx descriptor */ @@ -224,24 +215,25 @@ int eth_send(volatile void *packet, int len) udelay(100); if (timeout < 0) { - printf("eth_send: transmit timeout\n"); - rc = -1; + printf(SHETHER_NAME ": transmit timeout\n"); + ret = -ETIMEDOUT; goto err; } -err: port_info->tx_desc_cur++; if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC) port_info->tx_desc_cur = port_info->tx_desc_base; - return rc; + return ret; +err: + return ret; } -int eth_rx(void) +int sh_eth_recv(struct eth_device *dev) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; - int len = 0; + struct sh_eth_dev *eth = dev->priv; + int port = eth->port, len = 0; + struct sh_eth_info *port_info = ð->port_info[port]; volatile u8 *packet; /* Check if the rx descriptor is ready */ @@ -275,10 +267,10 @@ int eth_rx(void) } #define EDMR_INIT_CNT 1000 -static int sh_eth_reset(struct dev_info_s *dev) +static int sh_eth_reset(struct sh_eth_dev *eth) { - int port = dev->port; - int i; + int port = eth->port; + int ret = 0, i; /* Start e-dmac transmitter and receiver */ outl(EDSR_ENALL, EDSR(port)); @@ -292,33 +284,36 @@ static int sh_eth_reset(struct dev_info_s *dev) } if (i == EDMR_INIT_CNT) { - printf("Error: Software reset timeout\n"); - return -1; + printf(SHETHER_NAME ": Software reset timeout\n"); + ret = -EIO; } - return 0; + + return ret; } -static int sh_eth_tx_desc_init(struct dev_info_s *dev) +static int sh_eth_tx_desc_init(struct sh_eth_dev *eth) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; + int port = eth->port, i, ret = 0; u32 tmp_addr; + struct sh_eth_info *port_info = ð->port_info[port]; struct tx_desc_s *cur_tx_desc; - int i; - /* Allocate tx descriptors. They must be TX_DESC_SIZE bytes - aligned */ - if (!(port_info->tx_desc_malloc = malloc(NUM_TX_DESC * + /* + * Allocate tx descriptors. They must be TX_DESC_SIZE bytes aligned + */ + port_info->tx_desc_malloc = malloc(NUM_TX_DESC * sizeof(struct tx_desc_s) + - TX_DESC_SIZE - 1))) { - printf("Error: malloc failed\n"); - return -ENOMEM; + TX_DESC_SIZE - 1); + if (!port_info->tx_desc_malloc) { + printf(SHETHER_NAME ": malloc failed\n"); + ret = -ENOMEM; + goto err; } + tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) & ~(TX_DESC_SIZE - 1)); /* Make sure we use a P2 address (non-cacheable) */ port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr); - port_info->tx_desc_cur = port_info->tx_desc_base; /* Initialize all descriptors */ @@ -340,26 +335,30 @@ static int sh_eth_tx_desc_init(struct dev_info_s *dev) outl(ADDR_TO_PHY(cur_tx_desc), TDFXR(port)); outl(0x01, TDFFR(port));/* Last discriptor bit */ - return 0; +err: + return ret; } -static int sh_eth_rx_desc_init(struct dev_info_s *dev) +static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; - u32 tmp_addr; + int port = eth->port, i , ret = 0; + struct sh_eth_info *port_info = ð->port_info[port]; struct rx_desc_s *cur_rx_desc; + u32 tmp_addr; u8 *rx_buf; - int i; - /* Allocate rx descriptors. They must be RX_DESC_SIZE bytes - aligned */ - if (!(port_info->rx_desc_malloc = malloc(NUM_RX_DESC * + /* + * Allocate rx descriptors. They must be RX_DESC_SIZE bytes aligned + */ + port_info->rx_desc_malloc = malloc(NUM_RX_DESC * sizeof(struct rx_desc_s) + - RX_DESC_SIZE - 1))) { - printf("Error: malloc failed\n"); - return -ENOMEM; + RX_DESC_SIZE - 1); + if (!port_info->rx_desc_malloc) { + printf(SHETHER_NAME ": malloc failed\n"); + ret = -ENOMEM; + goto err; } + tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) & ~(RX_DESC_SIZE - 1)); /* Make sure we use a P2 address (non-cacheable) */ @@ -367,15 +366,17 @@ static int sh_eth_rx_desc_init(struct dev_info_s *dev) port_info->rx_desc_cur = port_info->rx_desc_base; - /* Allocate rx data buffers. They must be 32 bytes aligned and in - P2 area */ - if (!(port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + - 31))) { - printf("Error: malloc failed\n"); - free(port_info->rx_desc_malloc); - port_info->rx_desc_malloc = NULL; - return -ENOMEM; + /* + * Allocate rx data buffers. They must be 32 bytes aligned and in + * P2 area + */ + port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + 31); + if (!port_info->rx_buf_malloc) { + printf(SHETHER_NAME ": malloc failed\n"); + ret = -ENOMEM; + goto err_buf_malloc; } + tmp_addr = (u32)(((int)port_info->rx_buf_malloc + (32 - 1)) & ~(32 - 1)); port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr); @@ -399,18 +400,31 @@ static int sh_eth_rx_desc_init(struct dev_info_s *dev) outl(ADDR_TO_PHY(cur_rx_desc), RDFXR(port)); outl(RDFFR_RDLF, RDFFR(port)); - return 0; + return ret; + +err_buf_malloc: + free(port_info->rx_desc_malloc); + port_info->rx_desc_malloc = NULL; + +err: + return ret; } -static void sh_eth_desc_free(struct dev_info_s *dev) +static void sh_eth_tx_desc_free(struct sh_eth_dev *eth) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; + int port = eth->port; + struct sh_eth_info *port_info = ð->port_info[port]; if (port_info->tx_desc_malloc) { free(port_info->tx_desc_malloc); port_info->tx_desc_malloc = NULL; } +} + +static void sh_eth_rx_desc_free(struct sh_eth_dev *eth) +{ + int port = eth->port; + struct sh_eth_info *port_info = ð->port_info[port]; if (port_info->rx_desc_malloc) { free(port_info->rx_desc_malloc); @@ -423,36 +437,48 @@ static void sh_eth_desc_free(struct dev_info_s *dev) } } -static int sh_eth_desc_init(struct dev_info_s *dev) +static int sh_eth_desc_init(struct sh_eth_dev *eth) { - int rc; + int ret = 0; - if ((rc = sh_eth_tx_desc_init(dev)) || (rc = sh_eth_rx_desc_init(dev))) { - sh_eth_desc_free(dev); - return rc; - } + ret = sh_eth_tx_desc_init(eth); + if (ret) + goto err_tx_init; - return 0; + ret = sh_eth_rx_desc_init(eth); + if (ret) + goto err_rx_init; + + return ret; +err_rx_init: + sh_eth_tx_desc_free(eth); + +err_tx_init: + return ret; } -static int sh_eth_phy_config(struct dev_info_s *dev) +static int sh_eth_phy_config(struct sh_eth_dev *eth) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; - int timeout; + int port = eth->port, timeout, ret = 0; + struct sh_eth_info *port_info = ð->port_info[port]; u32 val; + /* Reset phy */ - sh_eth_mii_write_phy_reg(port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET); + sh_eth_mii_write_phy_reg + (port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET); timeout = 10; while (timeout--) { - val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, PHY_CTRL); + val = sh_eth_mii_read_phy_reg(port, + port_info->phy_addr, PHY_CTRL); if (!(val & PHY_C_RESET)) break; - udelay(50000); + udelay(SH_ETH_PHY_DELAY); } + if (timeout < 0) { - printf("%s phy reset timeout\n", __func__); - return -1; + printf(SHETHER_NAME ": phy reset timeout\n"); + ret = -EIO; + goto err_tout; } /* Advertise 100/10 baseT full/half duplex */ @@ -467,23 +493,27 @@ static int sh_eth_phy_config(struct dev_info_s *dev) val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1); if (val & PHY_S_ANEGC) break; - udelay(50000); + + udelay(SH_ETH_PHY_DELAY); } + if (timeout < 0) { - printf("sh_eth_phy_config() phy auto-negotiation failed\n"); - return -1; + printf(SHETHER_NAME ": phy auto-negotiation failed\n"); + ret = -ETIMEDOUT; + goto err_tout; } - return 0; + return ret; + +err_tout: + return ret; } -static int sh_eth_config(struct dev_info_s *dev, bd_t * bd) +static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) { - int port = dev->port; - struct port_info_s *port_info = &dev->port_info[port]; - u32 val; - u32 phy_status; - int rc; + int port = eth->port, ret = 0; + u32 val, phy_status; + struct sh_eth_info *port_info = ð->port_info[port]; /* Configure e-dmac registers */ outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port)); @@ -513,20 +543,20 @@ static int sh_eth_config(struct dev_info_s *dev, bd_t * bd) outl(TPAUSER_TPAUSE, TPAUSER(port)); /* Configure phy */ - if ((rc = sh_eth_phy_config(dev))) - return rc; - + ret = sh_eth_phy_config(eth); + if (ret) { + printf(SHETHER_NAME ":i phy config timeout\n"); + goto err_phy_cfg; + } /* Read phy status to finish configuring the e-mac */ - phy_status = sh_eth_mii_read_phy_reg(dev->port, - dev->port_info[dev->port].phy_addr, - 1); + phy_status = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1); /* Set the transfer speed */ if (phy_status & (PHY_S_100X_F|PHY_S_100X_H)) { - printf("100Base/"); + printf(SHETHER_NAME ": 100Base/"); outl(GECMR_100B, GECMR(port)); } else { - printf("10Base/"); + printf(SHETHER_NAME ": 10Base/"); outl(GECMR_10B, GECMR(port)); } @@ -538,27 +568,34 @@ static int sh_eth_config(struct dev_info_s *dev, bd_t * bd) printf("Half\n"); outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR(port)); } - return 0; + + return ret; + +err_phy_cfg: + return ret; } -static int sh_eth_start(struct dev_info_s *dev) +static void sh_eth_start(struct sh_eth_dev *eth) { /* * Enable the e-dmac receiver only. The transmitter will be enabled when * we have something to transmit */ - outl(EDRRR_R, EDRRR(dev->port)); + outl(EDRRR_R, EDRRR(eth->port)); +} - return 0; +static void sh_eth_stop(struct sh_eth_dev *eth) +{ + outl(~EDRRR_R, EDRRR(eth->port)); } static int sh_eth_get_mac(bd_t *bd) { char *s, *e; - int i; s = getenv("ethaddr"); if (s != NULL) { + int i; for (i = 0; i < 6; ++i) { bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; if (s) @@ -570,34 +607,92 @@ static int sh_eth_get_mac(bd_t *bd) return 0; } -int eth_init(bd_t *bd) +int sh_eth_init(struct eth_device *dev, bd_t *bd) { - int rc; - /* Allocate main device information structure */ - if (!(dev = malloc(sizeof(*dev)))) { - printf("eth_init: malloc failed\n"); - return -ENOMEM; - } + int ret = 0; + struct sh_eth_dev *eth = dev->priv; - memset(dev, 0, sizeof(*dev)); + ret = sh_eth_reset(eth); + if (ret) + goto err; - dev->port = CONFIG_SH_ETHER_USE_PORT; - dev->port_info[dev->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; + ret = sh_eth_desc_init(eth); + if (ret) + goto err; - sh_eth_get_mac(bd); + ret = sh_eth_config(eth, bd); + if (ret) + goto err_config; + + sh_eth_start(eth); + + return ret; - if ((rc = sh_eth_reset(dev)) || (rc = sh_eth_desc_init(dev))) +err_config: + sh_eth_tx_desc_free(eth); + sh_eth_rx_desc_free(eth); + +err: + return ret; +} + +void sh_eth_halt(struct eth_device *dev) +{ + struct sh_eth_dev *eth = dev->priv; + + sh_eth_reset(eth); + sh_eth_stop(eth); +} + +int sh_eth_initialize(bd_t *bd) +{ + int ret = 0; + struct sh_eth_dev *eth = NULL; + struct eth_device *dev = NULL; + + eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev)); + if (!eth) { + printf(SHETHER_NAME ": %s: malloc failed\n", __func__); + ret = -ENOMEM; goto err; + } - if ((rc = sh_eth_config(dev, bd)) || (rc = sh_eth_start(dev))) - goto err_desc; + dev = (struct eth_device *)malloc(sizeof(struct eth_device)); + if (!dev) { + printf(SHETHER_NAME ": %s: malloc failed\n", __func__); + ret = -ENOMEM; + goto err; + } + memset(dev, 0, sizeof(struct eth_device)); + memset(eth, 0, sizeof(struct sh_eth_dev)); - return 0; + eth->port = CONFIG_SH_ETHER_USE_PORT; + eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; + + dev->priv = (void *)eth; + dev->iobase = 0; + dev->init = sh_eth_init; + dev->halt = sh_eth_halt; + dev->send = sh_eth_send; + dev->recv = sh_eth_recv; + eth->port_info[eth->port].dev = dev; + + sprintf(dev->name, SHETHER_NAME); + + /* Register Device to EtherNet subsystem */ + eth_register(dev); + + sh_eth_get_mac(bd); + + return ret; -err_desc: - sh_eth_desc_free(dev); err: - free(dev); - printf("eth_init: Failed\n"); - return rc; + if (dev) + free(dev); + + if (eth) + free(eth); + + printf(SHETHER_NAME ": Failed\n"); + return ret; } diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 9cf0ea0..a13fff0 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -20,6 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #define SHETHER_NAME "sh_eth" @@ -48,7 +49,7 @@ #define TX_DESC_PADDING 4 #define TX_DESC_SIZE (12 + TX_DESC_PADDING) -/* Tx descriptor. We always use 4 bytes of padding */ +/* Tx descriptor. We always use 3 bytes of padding */ struct tx_desc_s { volatile u32 td0; u32 td1; @@ -72,7 +73,7 @@ struct rx_desc_s { u32 padding; }; -struct port_info_s { +struct sh_eth_info { struct tx_desc_s *tx_desc_malloc; struct tx_desc_s *tx_desc_base; struct tx_desc_s *tx_desc_cur; @@ -83,11 +84,12 @@ struct port_info_s { u8 *rx_buf_base; u8 mac_addr[6]; u8 phy_addr; + struct eth_device *dev; }; -struct dev_info_s { +struct sh_eth_dev { int port; - struct port_info_s port_info[MAX_PORT_NUM]; + struct sh_eth_info port_info[MAX_PORT_NUM]; }; /* Register Address */ diff --git a/include/netdev.h b/include/netdev.h index 751f0da..a7d662d 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -70,6 +70,7 @@ int skge_initialize(bd_t *bis); int tsi108_eth_initialize(bd_t *bis); int uec_initialize(int index); int uli526x_initialize(bd_t *bis); +int sh_eth_initialize(bd_t *bis); /* Boards with PCI network controllers can call this from their board_eth_init() * function to initialize whatever's on board. -- cgit v0.10.2 From ba705b5b1a97b47388ed48858bef6bf7b6bfcd56 Mon Sep 17 00:00:00 2001 From: Gary Jennejohn Date: Thu, 20 Nov 2008 12:28:38 +0100 Subject: mgcoge make ether_scc.c work with CONFIG_NET_MULTI This change is needed for mgcoge because it uses two ethernet drivers. Add a check for the presence of the PIGGY board on mgcoge. Without this board networking cannot work and the initialization must be aborted. Only allocate rtx once to prevent DPRAM exhaustion. Initialize ether_scc.c and the keymile-specific HDLC driver (to be added soon) in eth.c. Signed-off-by: Gary Jennejohn Signed-off-by: Ben Warren diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile index 80d7852..9f0c2dd 100644 --- a/cpu/mpc8260/Makefile +++ b/cpu/mpc8260/Makefile @@ -1,5 +1,5 @@ # -# (C) Copyright 2000-2006 +# (C) Copyright 2000-2008 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # See file CREDITS for list of people who contributed to this @@ -27,9 +27,13 @@ LIB = $(obj)lib$(CPU).a START = start.o kgdb.o COBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \ - interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \ + interrupts.o ether_fcc.o i2c.o commproc.o \ bedbug_603e.o pci.o spi.o +COBJS-$(CONFIG_ETHER_ON_SCC) = ether_scc.o + +COBJS += $(COBJS-y) + SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) START := $(addprefix $(obj),$(START)) diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c index b9e748a..f4beca5 100644 --- a/cpu/mpc8260/cpu.c +++ b/cpu/mpc8260/cpu.c @@ -326,5 +326,8 @@ int cpu_eth_init(bd_t *bis) #if defined(CONFIG_ETHER_ON_FCC) fec_initialize(bis); #endif +#if defined(CONFIG_ETHER_ON_SCC) + mpc82xx_scc_enet_initialize(bd); +#endif return 0; } diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c index c65f0e0..3671ef1 100644 --- a/cpu/mpc8260/ether_scc.c +++ b/cpu/mpc8260/ether_scc.c @@ -10,6 +10,12 @@ * Advent Networks, Inc. * Jay Monkman * + * Modified so that it plays nicely when more than one ETHERNET interface + * is in use a la ether_fcc.c. + * (C) Copyright 2008 + * DENX Software Engineerin GmbH + * Gary Jennejohn + * * See file CREDITS for list of people who contributed to this * project. * @@ -32,11 +38,14 @@ #include #include #include +#include #include #include #include -#if defined(CONFIG_ETHER_ON_SCC) && defined(CONFIG_CMD_NET) +#ifndef CONFIG_NET_MULTI +#error "CONFIG_NET_MULTI must be defined." +#endif #if (CONFIG_ETHER_INDEX == 1) # define PROFF_ENET PROFF_SCC1 @@ -100,7 +109,7 @@ typedef volatile struct CommonBufferDescriptor { static RTXBD *rtx; -int eth_send(volatile void *packet, int length) +static int sec_send(struct eth_device *dev, volatile void *packet, int length) { int i; int result = 0; @@ -137,7 +146,7 @@ int eth_send(volatile void *packet, int length) } -int eth_rx(void) +static int sec_rx(struct eth_device *dev) { int length; @@ -184,7 +193,7 @@ int eth_rx(void) * *************************************************************/ -int eth_init(bd_t *bis) +static int sec_init(struct eth_device *dev, bd_t *bis) { int i; volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; @@ -194,9 +203,14 @@ int eth_init(bd_t *bis) rxIdx = 0; txIdx = 0; - /* assign static pointer to BD area */ - dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16); - rtx = (RTXBD *)&immr->im_dprambase[dpaddr]; + /* + * Assign static pointer to BD area. + * Avoid exhausting DPRAM, which would cause a panic. + */ + if (rtx == NULL) { + dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16); + rtx = (RTXBD *)&immr->im_dprambase[dpaddr]; + } /* 24.21 - (1-3): ioports have been set up already */ @@ -338,7 +352,7 @@ int eth_init(bd_t *bis) } -void eth_halt(void) +static void sec_halt(struct eth_device *dev) { volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl &= ~(SCC_GSMRL_ENR | @@ -346,7 +360,7 @@ void eth_halt(void) } #if 0 -void restart(void) +static void sec_restart(void) { volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; immr->im_cpm.cp_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | @@ -354,4 +368,20 @@ void restart(void) } #endif -#endif +int mpc82xx_scc_enet_initialize(bd_t *bis) +{ + struct eth_device *dev; + + dev = (struct eth_device *) malloc(sizeof *dev); + memset(dev, 0, sizeof *dev); + + sprintf(dev->name, "SCC ETHERNET"); + dev->init = sec_init; + dev->halt = sec_halt; + dev->send = sec_send; + dev->recv = sec_rx; + + eth_register(dev); + + return 1; +} diff --git a/include/netdev.h b/include/netdev.h index a7d662d..ce1ecbd 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -57,6 +57,7 @@ int mcffec_initialize(bd_t *bis); int mpc512x_fec_initialize(bd_t *bis); int mpc5xxx_fec_initialize(bd_t *bis); int mpc8220_fec_initialize(bd_t *bis); +int mpc82xx_scc_enet_initialize(bd_t *bis); int natsemi_initialize(bd_t *bis); int npe_initialize(bd_t *bis); int ns8382x_initialize(bd_t *bis); -- cgit v0.10.2 From 71a040f4f556cca4d30f06805d82e717b3ef1020 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 21 Nov 2008 12:06:26 +0900 Subject: sh: sh7763rdp: Update sh7763rdp config Add CONFIG_NET_MULTI in config file, because sh_eth changed new newwork API. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Ben Warren diff --git a/include/configs/sh7763rdp.h b/include/configs/sh7763rdp.h index 8a76dad..4ea79cf 100644 --- a/include/configs/sh7763rdp.h +++ b/include/configs/sh7763rdp.h @@ -118,6 +118,7 @@ #define CONFIG_SYS_HZ (CONFIG_SYS_CLK_FREQ / TMU_CLK_DIVIDER) /* Ether */ +#define CONFIG_NET_MULTI 1 #define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT (1) #define CONFIG_SH_ETHER_PHY_ADDR (0x01) -- cgit v0.10.2 From 268859338c0188eab1d0d3b867b7dad3c5cc734a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 5 Jan 2009 12:25:13 +0100 Subject: net: Sort Makefile labels Signed-off-by: Michal Simek Signed-off-by: Ben Warren diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 631336a..128dc11 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libnet.a COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o +COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o @@ -54,11 +55,11 @@ COBJS-$(CONFIG_NS8382X) += ns8382x.o COBJS-$(CONFIG_DRIVER_NS9750_ETHERNET) += ns9750_eth.o COBJS-$(CONFIG_PCNET) += pcnet.o COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o -COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o COBJS-$(CONFIG_RTL8139) += rtl8139.o COBJS-$(CONFIG_RTL8169) += rtl8169.o COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o +COBJS-$(CONFIG_SH_ETHER) += sh_eth.o COBJS-$(CONFIG_DRIVER_SMC91111) += smc91111.o COBJS-$(CONFIG_DRIVER_SMC911X) += smc911x.o COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o @@ -68,7 +69,6 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o -COBJS-$(CONFIG_SH_ETHER) += sh_eth.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) -- cgit v0.10.2 From 75edebe3011c963a7cd84be0f4a987477f2aaf89 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 27 Jan 2009 16:53:39 -0500 Subject: Move is_valid_ether_addr() to include/net.h Import the is_valid_ether_addr() function from the Linux kernel. Signed-off-by: Mike Frysinger Signed-off-by: Ben Warren diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index 7303f1b..cec2b26 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -34,22 +34,6 @@ #include #include -/** - * is_valid_ether_addr - Determine if the given Ethernet address is valid - * @addr: Pointer to a six-byte array containing the Ethernet address - * - * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not - * a multicast address, and is not FF:FF:FF:FF:FF:FF. - * - * Return true if the address is valid. - */ -static inline int is_valid_ether_addr(const u8 * addr) -{ - /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to - * explicitly check for it here. */ - return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); -} - DECLARE_GLOBAL_DATA_PTR; #define POST_WORD_ADDR 0xFF903FFC diff --git a/include/net.h b/include/net.h index d2d394f..bbe0d4b 100644 --- a/include/net.h +++ b/include/net.h @@ -474,6 +474,22 @@ static inline int is_multicast_ether_addr(const u8 *addr) return (0x01 & addr[0]); } +/** + * is_valid_ether_addr - Determine if the given Ethernet address is valid + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not + * a multicast address, and is not FF:FF:FF:FF:FF:FF. + * + * Return true if the address is valid. + */ +static inline int is_valid_ether_addr(const u8 * addr) +{ + /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to + * explicitly check for it here. */ + return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); +} + /* Convert an IP address to a string */ extern void ip_to_string (IPaddr_t x, char *s); -- cgit v0.10.2 From 9a37f2acc31a3296dddd3574ea9eaf7f319807b9 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 21 Jan 2009 17:14:26 +0100 Subject: net: smc911x.c: Add LAN9211 to chip_ids[] array Signed-off-by: Stefan Roese Signed-off-by: Ben Warren diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 6c5a4b3..9cc4fce 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -384,6 +384,7 @@ void pkt_data_push(u32 addr, u32 val) \ #define CHIP_9116 0x116 #define CHIP_9117 0x117 #define CHIP_9118 0x118 +#define CHIP_9211 0x9211 #define CHIP_9215 0x115a #define CHIP_9216 0x116a #define CHIP_9217 0x117a @@ -399,6 +400,7 @@ static const struct chip_id chip_ids[] = { { CHIP_9116, "LAN9116" }, { CHIP_9117, "LAN9117" }, { CHIP_9118, "LAN9118" }, + { CHIP_9211, "LAN9211" }, { CHIP_9215, "LAN9215" }, { CHIP_9216, "LAN9216" }, { CHIP_9217, "LAN9217" }, -- cgit v0.10.2 From 12a8b9db12f82a189ff143a58731007f5469da61 Mon Sep 17 00:00:00 2001 From: Ron Madrid Date: Wed, 28 Jan 2009 16:17:21 -0800 Subject: Marvell 88E1118 interrupt fix This patch adjusts the LED control so that interrupt lines are not reading LEDs and effectively causing indefinite interrupts to the controller. Signed-off-by: Ron Madrid Signed-off-by: Ben Warren diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index fbc9a6d..dc90f23 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -1141,6 +1141,9 @@ struct phy_info phy_info_M88E1118 = { {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, {0x16, 0x0002, NULL}, /* Change Page Number */ {0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */ + {0x16, 0x0003, NULL}, /* Change Page Number */ + {0x10, 0x021e, NULL}, /* Adjust LED control */ + {0x16, 0x0000, NULL}, /* Change Page Number */ {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, @@ -1152,6 +1155,7 @@ struct phy_info phy_info_M88E1118 = { /* Status is read once to clear old link state */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ + {MIIM_STATUS, miim_read, &mii_parse_sr}, /* Read the status */ {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr}, -- cgit v0.10.2 From af8626e0c08a780d9ded1d9c4883a89355f60e75 Mon Sep 17 00:00:00 2001 From: Olav Morken Date: Fri, 23 Jan 2009 12:56:26 +0100 Subject: Fix IP alignment problem This patch removes volatile from: volatile IP_t *ip = (IP_t *)xip; Due to a bug, avr32-gcc will assume that ip is aligned on a word boundary when using volatile, which causes an exception since xip isn't aligned on a word boundary. Signed-off-by: Gunnar Rangoy Signed-off-by: Paul Driveklepp Signed-off-by: Olav Morken Signed-off-by: Ben Warren diff --git a/net/net.c b/net/net.c index e6547f9..459baf4 100644 --- a/net/net.c +++ b/net/net.c @@ -1684,7 +1684,7 @@ NetSetEther(volatile uchar * xet, uchar * addr, uint prot) void NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len) { - volatile IP_t *ip = (IP_t *)xip; + IP_t *ip = (IP_t *)xip; /* * If the data is an odd number of bytes, zero the -- cgit v0.10.2 From fc01ea1e27d5b124f0a1868d0ce569f156d58dfe Mon Sep 17 00:00:00 2001 From: Gunnar Rangoy Date: Fri, 23 Jan 2009 12:56:31 +0100 Subject: AVR32: macb - Search for PHY id This patch adds support for searching through available PHY-addresses in the macb-driver. This is needed for the ATEVK1100 evaluation board, where the PHY-address will be initialized to either 1 or 7. This patch adds a config option, CONFIG_MACB_SEARCH_PHY, which when enabled tells the driver to search for the PHY address. Signed-off-by: Gunnar Rangoy Signed-off-by: Paul Driveklepp Signed-off-by: Olav Morken Signed-off-by: Ben Warren diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 98e8c73..af0409b 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -317,6 +317,30 @@ static void macb_phy_reset(struct macb_device *macb) netdev->name, status); } +#ifdef CONFIG_MACB_SEARCH_PHY +static int macb_phy_find(struct macb_device *macb) +{ + int i; + u16 phy_id; + + /* Search for PHY... */ + for (i = 0; i < 32; i++) { + macb->phy_addr = i; + phy_id = macb_mdio_read(macb, MII_PHYSID1); + if (phy_id != 0xffff) { + printf("%s: PHY present at %d\n", macb->netdev.name, i); + return 1; + } + } + + /* PHY isn't up to snuff */ + printf("%s: PHY not found", macb->netdev.name); + + return 0; +} +#endif /* CONFIG_MACB_SEARCH_PHY */ + + static int macb_phy_init(struct macb_device *macb) { struct eth_device *netdev = &macb->netdev; @@ -325,6 +349,13 @@ static int macb_phy_init(struct macb_device *macb) int media, speed, duplex; int i; +#ifdef CONFIG_MACB_SEARCH_PHY + /* Auto-detect phy_addr */ + if (!macb_phy_find(macb)) { + return 0; + } +#endif /* CONFIG_MACB_SEARCH_PHY */ + /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { -- cgit v0.10.2