summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-08-12 15:46:36 -0400
committerTom Rini <trini@konsulko.com>2015-08-13 07:19:41 -0400
commitfcd78fa604d994477fd209b9faab4a974b103250 (patch)
tree17f5e8cecaa3579e441372e6ec5cfeecdec11c61
parent4fbe41c4af483b082f525328796b7835536ae797 (diff)
parentfaa765d40760d84bff0de26a5a5f605621dbff39 (diff)
downloadu-boot-imx-fcd78fa604d994477fd209b9faab4a974b103250.zip
u-boot-imx-fcd78fa604d994477fd209b9faab4a974b103250.tar.gz
u-boot-imx-fcd78fa604d994477fd209b9faab4a974b103250.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-net
-rw-r--r--arch/arm/cpu/arm926ejs/lpc32xx/devices.c7
-rw-r--r--drivers/net/davinci_emac.c3
-rw-r--r--drivers/net/e1000.c34
-rw-r--r--drivers/net/e1000.h3
-rw-r--r--drivers/net/fm/eth.c5
-rw-r--r--drivers/net/lpc32xx_eth.c55
-rw-r--r--drivers/net/macb.c33
-rw-r--r--drivers/net/macb.h9
-rw-r--r--drivers/net/phy/broadcom.c29
-rw-r--r--drivers/net/phy/marvell.c67
-rw-r--r--drivers/net/phy/phy.c10
-rw-r--r--drivers/net/phy/realtek.c8
-rw-r--r--net/tftp.c2
13 files changed, 210 insertions, 55 deletions
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
index b0287be..c0c9c6c 100644
--- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
+++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
@@ -45,7 +45,12 @@ void lpc32xx_mac_init(void)
{
/* Enable MAC interface */
writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER
- | CLK_MAC_MII, &clk->macclk_ctrl);
+#if defined(CONFIG_RMII)
+ | CLK_MAC_RMII,
+#else
+ | CLK_MAC_MII,
+#endif
+ &clk->macclk_ctrl);
}
void lpc32xx_mlc_nand_init(void)
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 427ad3e..0444795 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -598,7 +598,8 @@ static void davinci_eth_close(struct eth_device *dev)
debug_emac("+ emac_close\n");
davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */
- davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
+ if (readl(&adap_emac->RXCONTROL) & 1)
+ davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
/* Reset EMAC module and disable interrupts in wrapper */
writel(1, &adap_emac->SOFTRESET);
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 96e6bb0..d5d48b1 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -126,6 +126,7 @@ static int e1000_detect_gig_phy(struct e1000_hw *hw);
static void e1000_set_media_type(struct e1000_hw *hw);
static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
#ifndef CONFIG_E1000_NO_NVM
@@ -729,7 +730,10 @@ void e1000_release_eeprom(struct e1000_hw *hw)
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
}
+
+ e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
}
+
/******************************************************************************
* Reads a 16 bit word from the EEPROM.
*
@@ -992,10 +996,6 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
DEBUGFUNC();
- swsm = E1000_READ_REG(hw, SWSM);
- swsm &= ~E1000_SWSM_SMBI;
- E1000_WRITE_REG(hw, SWSM, swsm);
-
if (hw->mac_type != e1000_80003es2lan)
return E1000_SUCCESS;
@@ -1102,6 +1102,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
return E1000_SUCCESS;
}
+/* Take ownership of the PHY */
static int32_t
e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
{
@@ -1115,10 +1116,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
if (e1000_get_hw_eeprom_semaphore(hw))
return -E1000_ERR_SWFW_SYNC;
- if (hw->mac_type == e1000_igb)
- swfw_sync = E1000_READ_REG(hw, I210_SW_FW_SYNC);
- else
- swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
+ swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
if (!(swfw_sync & (fwmask | swmask)))
break;
@@ -1141,6 +1139,21 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
return E1000_SUCCESS;
}
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask)
+{
+ uint32_t swfw_sync = 0;
+
+ DEBUGFUNC();
+ while (e1000_get_hw_eeprom_semaphore(hw))
+ ; /* Empty */
+
+ swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
+ swfw_sync &= ~mask;
+ E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
+
+ e1000_put_hw_eeprom_semaphore(hw);
+}
+
static bool e1000_is_second_port(struct e1000_hw *hw)
{
switch (hw->mac_type) {
@@ -4004,7 +4017,7 @@ e1000_wait_autoneg(struct e1000_hw *hw)
DEBUGFUNC();
DEBUGOUT("Waiting for Auto-Neg to complete.\n");
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
+ /* We will wait for autoneg to complete or timeout to expire. */
for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
/* Read the MII Status Register and wait for Auto-Neg
* Complete bit to be set.
@@ -4438,6 +4451,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if (hw->mac_type >= e1000_82571)
mdelay(10);
+
} else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
* bit to put the PHY into reset. Then, take it out of reset.
@@ -4462,6 +4476,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
}
+ e1000_swfw_sync_release(hw, swfw);
+
/* Wait for FW to finish PHY configuration. */
ret_val = e1000_get_phy_cfg_done(hw);
if (ret_val != E1000_SUCCESS)
diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h
index f3b77b1..23a81e6 100644
--- a/drivers/net/e1000.h
+++ b/drivers/net/e1000.h
@@ -2460,7 +2460,7 @@ struct e1000_hw {
#define MII_CR_SPEED_100 0x2000
#define MII_CR_SPEED_10 0x0000
#define E1000_PHY_ADDRESS 0x01
-#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
+#define PHY_AUTO_NEG_TIME 80 /* 8.0 Seconds */
#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
#define PHY_REVISION_MASK 0xFFFFFFF0
#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */
@@ -2496,7 +2496,6 @@ struct e1000_hw {
#define ICH_GFPREG_BASE_MASK 0x1FFF
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
-#define E1000_I210_SW_FW_SYNC 0x5B50 /* Software-Firmware Synchronization - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
/* SPI EEPROM Status Register */
diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c
index d7a37f3..6702f5a 100644
--- a/drivers/net/fm/eth.c
+++ b/drivers/net/fm/eth.c
@@ -520,6 +520,7 @@ static int fm_eth_recv(struct eth_device *dev)
u16 status, len;
u8 *data;
u16 offset_out;
+ int ret = 1;
fm_eth = (struct fm_eth *)dev->priv;
pram = fm_eth->rx_pram;
@@ -533,7 +534,7 @@ static int fm_eth_recv(struct eth_device *dev)
net_process_received_packet(data, len);
} else {
printf("%s: Rx error\n", dev->name);
- return 0;
+ ret = 0;
}
/* clear the RxBDs */
@@ -559,7 +560,7 @@ static int fm_eth_recv(struct eth_device *dev)
}
fm_eth->cur_rxbd = (void *)rxbd;
- return 1;
+ return ret;
}
static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)
diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c
index 8dcbb4a..f3ab0f4 100644
--- a/drivers/net/lpc32xx_eth.c
+++ b/drivers/net/lpc32xx_eth.c
@@ -151,7 +151,7 @@ struct lpc32xx_eth_registers {
#define SUPP_SPEED 0x00000100
/* MCFG register bitfields/masks and offsets (see Table 292) */
-#define MCFG_CLOCK_SELECT_MASK 0x0000001C
+#define MCFG_RESET_MII_MGMT 0x00008000
/* divide clock by 28 (see Table 293) */
#define MCFG_CLOCK_SELECT_DIV28 0x0000001C
@@ -168,9 +168,10 @@ struct lpc32xx_eth_registers {
#define COMMAND_RXENABLE 0x00000001
#define COMMAND_TXENABLE 0x00000002
#define COMMAND_PASSRUNTFRAME 0x00000040
+#define COMMAND_RMII 0x00000200
#define COMMAND_FULL_DUPLEX 0x00000400
/* Helper: general reset */
-#define COMMAND_RESETS 0x0000001C
+#define COMMAND_RESETS 0x00000038
/* STATUS register bitfields/masks and offsets (see Table 283) */
#define STATUS_RXSTATUS 0x00000001
@@ -201,6 +202,7 @@ struct lpc32xx_eth_device {
struct eth_device dev;
struct lpc32xx_eth_registers *regs;
struct lpc32xx_eth_buffers *bufs;
+ bool phy_rmii;
};
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device))
@@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = {
.regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE,
- .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS
+ .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS,
+#if defined(CONFIG_RMII)
+ .phy_rmii = true,
+#endif
};
#define TX_TIMEOUT 10000
@@ -459,8 +464,22 @@ static int lpc32xx_eth_init(struct eth_device *dev)
struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs;
int index;
- /* Release SOFT reset to let MII talk to PHY */
- clrbits_le32(&regs->mac1, MAC1_SOFT_RESET);
+ /* Initial MAC initialization */
+ writel(MAC1_PASS_ALL_RX_FRAMES, &regs->mac1);
+ writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, &regs->mac2);
+ writel(PKTSIZE_ALIGN, &regs->maxf);
+
+ /* Retries: 15 (0xF). Collision window: 57 (0x37). */
+ writel(0x370F, &regs->clrt);
+
+ /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */
+ writel(0x0012, &regs->ipgr);
+
+ /* pass runt (smaller than 64 bytes) frames */
+ if (lpc32xx_eth_device->phy_rmii)
+ writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, &regs->command);
+ else
+ writel(COMMAND_PASSRUNTFRAME, &regs->command);
/* Configure Full/Half Duplex mode */
if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) {
@@ -477,20 +496,6 @@ static int lpc32xx_eth_init(struct eth_device *dev)
else
writel(0, &regs->supp);
- /* Initial MAC initialization */
- writel(MAC1_PASS_ALL_RX_FRAMES, &regs->mac1);
- writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, &regs->mac2);
- writel(PKTSIZE_ALIGN, &regs->maxf);
-
- /* Retries: 15 (0xF). Collision window: 57 (0x37). */
- writel(0x370F, &regs->clrt);
-
- /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */
- writel(0x0012, &regs->ipgr);
-
- /* pass runt (smaller than 64 bytes) frames */
- writel(COMMAND_PASSRUNTFRAME, &regs->command);
-
/* Save station address */
writel((unsigned long) (dev->enetaddr[0] |
(dev->enetaddr[1] << 8)), &regs->sa2);
@@ -562,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev)
#if defined(CONFIG_PHYLIB)
int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid)
{
+ struct lpc32xx_eth_device *lpc32xx_eth_device =
+ container_of(dev, struct lpc32xx_eth_device, dev);
struct mii_dev *bus;
struct phy_device *phydev;
int ret;
@@ -582,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid)
return -ENOMEM;
}
- phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
+ if (lpc32xx_eth_device->phy_rmii)
+ phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII);
+ else
+ phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
+
if (!phydev) {
printf("phy_connect failed\n");
return -ENODEV;
@@ -604,7 +615,7 @@ int lpc32xx_eth_initialize(bd_t *bis)
* Set RMII management clock rate. With HCLK at 104 MHz and
* a divider of 28, this will be 3.72 MHz.
*/
-
+ writel(MCFG_RESET_MII_MGMT, &regs->mcfg);
writel(MCFG_CLOCK_SELECT_DIV28, &regs->mcfg);
/* Reset all MAC logic */
@@ -630,7 +641,7 @@ int lpc32xx_eth_initialize(bd_t *bis)
eth_register(dev);
#if defined(CONFIG_PHYLIB)
- lpc32xx_eth_phylib_init(dev, 0);
+ lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR);
#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, mii_reg_read, mii_reg_write);
#endif
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index f949161..a5c1880 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -54,6 +54,7 @@ struct macb_dma_desc {
#define DMA_DESC_BYTES(n) (n * sizeof(struct macb_dma_desc))
#define MACB_TX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_TX_RING_SIZE))
#define MACB_RX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_RX_RING_SIZE))
+#define MACB_TX_DUMMY_DMA_DESC_SIZE (DMA_DESC_BYTES(1))
#define RXADDR_USED 0x00000001
#define RXADDR_WRAP 0x00000002
@@ -93,6 +94,9 @@ struct macb_device {
unsigned long rx_ring_dma;
unsigned long tx_ring_dma;
+ struct macb_dma_desc *dummy_desc;
+ unsigned long dummy_desc_dma;
+
const struct device *dev;
struct eth_device netdev;
unsigned short phy_addr;
@@ -525,6 +529,30 @@ static int macb_phy_init(struct macb_device *macb)
return 1;
}
+static int gmac_init_multi_queues(struct macb_device *macb)
+{
+ int i, num_queues = 1;
+ u32 queue_mask;
+
+ /* bit 0 is never set but queue 0 always exists */
+ queue_mask = gem_readl(macb, DCFG6) & 0xff;
+ queue_mask |= 0x1;
+
+ for (i = 1; i < MACB_MAX_QUEUES; i++)
+ if (queue_mask & (1 << i))
+ num_queues++;
+
+ macb->dummy_desc->ctrl = TXBUF_USED;
+ macb->dummy_desc->addr = 0;
+ flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
+ MACB_TX_DUMMY_DMA_DESC_SIZE);
+
+ for (i = 1; i < num_queues; i++)
+ gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1);
+
+ return 0;
+}
+
static int macb_init(struct eth_device *netdev, bd_t *bd)
{
struct macb_device *macb = to_macb(netdev);
@@ -565,6 +593,9 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
macb_writel(macb, TBQP, macb->tx_ring_dma);
if (macb_is_gem(macb)) {
+ /* Check the multi queue and initialize the queue for tx */
+ gmac_init_multi_queues(macb);
+
/*
* When the GMAC IP with GE feature, this bit is used to
* select interface between RGMII and GMII.
@@ -712,6 +743,8 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
&macb->rx_ring_dma);
macb->tx_ring = dma_alloc_coherent(MACB_TX_DMA_DESC_SIZE,
&macb->tx_ring_dma);
+ macb->dummy_desc = dma_alloc_coherent(MACB_TX_DUMMY_DMA_DESC_SIZE,
+ &macb->dummy_desc_dma);
/* TODO: we need check the rx/tx_ring_dma is dcache line aligned */
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 06f7c66..5bb48f4 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -60,6 +60,13 @@
/* GEM specific register offsets */
#define GEM_DCFG1 0x0280
+#define GEM_DCFG6 0x0294
+
+#define MACB_MAX_QUEUES 8
+
+/* GEM specific multi queues register offset */
+/* hw_q can be 0~7 */
+#define GEM_TBQP(hw_q) (0x0440 + ((hw_q) << 2))
/* Bitfields in NCR */
#define MACB_LB_OFFSET 0
@@ -309,5 +316,7 @@
readl((port)->regs + GEM_##reg)
#define gem_writel(port, reg, value) \
writel((value), (port)->regs + GEM_##reg)
+#define gem_writel_queue_TBQP(port, value, queue_num) \
+ writel((value), (port)->regs + GEM_TBQP(queue_num))
#endif /* __DRIVERS_MACB_H__ */
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 4512763..4b2808e 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -137,6 +137,24 @@ static int bcm5482_config(struct phy_device *phydev)
return 0;
}
+static int bcm_cygnus_startup(struct phy_device *phydev)
+{
+ /* Read the Status (2x to make sure link is right) */
+ genphy_update_link(phydev);
+ genphy_parse_link(phydev);
+
+ return 0;
+}
+
+static int bcm_cygnus_config(struct phy_device *phydev)
+{
+ genphy_config_aneg(phydev);
+
+ phy_reset(phydev);
+
+ return 0;
+}
+
/*
* Find out if PHY is in copper or serdes mode by looking at Expansion Reg
* 0x42 - "Operating Mode Status Register"
@@ -264,11 +282,22 @@ static struct phy_driver BCM5482S_driver = {
.shutdown = &genphy_shutdown,
};
+static struct phy_driver BCM_CYGNUS_driver = {
+ .name = "Broadcom CYGNUS GPHY",
+ .uid = 0xae025200,
+ .mask = 0xfffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &bcm_cygnus_config,
+ .startup = &bcm_cygnus_startup,
+ .shutdown = &genphy_shutdown,
+};
+
int phy_broadcom_init(void)
{
phy_register(&BCM5482S_driver);
phy_register(&BCM5464S_driver);
phy_register(&BCM5461S_driver);
+ phy_register(&BCM_CYGNUS_driver);
return 0;
}
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 9437c3b..eab1558 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -303,30 +303,58 @@ static int m88e1518_config(struct phy_device *phydev)
* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
* /88E1514 Rev A0, Errata Section 3.1
*/
+
+ /* EEE initialization */
+ phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff);
+ phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
+ phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
+ phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
+ phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
+ phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
+ phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
+ phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
+ phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
+ phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000);
+
+ /* SGMII-to-Copper mode initialization */
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
- phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); /* page 0xff */
- phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
- phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
- phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
- phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
- phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
- phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
- phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
- phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
- phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); /* reg page 0 */
- phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); /* reg page 18 */
- /* Write HWCFG_MODE = SGMII to Copper */
+ /* Select page 18 */
+ phy_write(phydev, MDIO_DEVAD_NONE, 22, 18);
+
+ /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
m88e1518_phy_writebits(phydev, 20, 0, 3, 1);
- /* Phy reset */
+ /* PHY reset is necessary after changing MODE[2:0] */
m88e1518_phy_writebits(phydev, 20, 15, 1, 1);
- phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); /* reg page 18 */
+
+ /* Reset page selection */
+ phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
+
udelay(100);
}
return m88e1111s_config(phydev);
}
+/* Marvell 88E1510 */
+static int m88e1510_config(struct phy_device *phydev)
+{
+ /* Select page 3 */
+ phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
+
+ /* Enable INTn output on LED[2] */
+ m88e1518_phy_writebits(phydev, 18, 7, 1, 1);
+
+ /* Configure LEDs */
+ m88e1518_phy_writebits(phydev, 16, 0, 4, 3); /* LED[0]:0011 (ACT) */
+ m88e1518_phy_writebits(phydev, 16, 4, 4, 6); /* LED[1]:0110 (LINK) */
+
+ /* Reset page selection */
+ phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
+
+ return m88e1518_config(phydev);
+}
+
/* Marvell 88E1118 */
static int m88e1118_config(struct phy_device *phydev)
{
@@ -539,6 +567,16 @@ static struct phy_driver M88E1149S_driver = {
.shutdown = &genphy_shutdown,
};
+static struct phy_driver M88E1510_driver = {
+ .name = "Marvell 88E1510",
+ .uid = 0x1410dd0,
+ .mask = 0xffffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &m88e1510_config,
+ .startup = &m88e1011s_startup,
+ .shutdown = &genphy_shutdown,
+};
+
static struct phy_driver M88E1518_driver = {
.name = "Marvell 88E1518",
.uid = 0x1410dd1,
@@ -569,6 +607,7 @@ int phy_marvell_init(void)
phy_register(&M88E1118R_driver);
phy_register(&M88E1111S_driver);
phy_register(&M88E1011S_driver);
+ phy_register(&M88E1510_driver);
phy_register(&M88E1518_driver);
return 0;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c8d08e8..65c731a 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -554,7 +554,7 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev,
}
static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
- int phy_id,
+ u32 phy_id,
phy_interface_t interface)
{
struct phy_device *dev;
@@ -763,11 +763,13 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
phy_interface_t interface)
{
/* Reset the bus */
- if (bus->reset)
+ if (bus->reset) {
bus->reset(bus);
- /* Wait 15ms to make sure the PHY has come out of hard reset */
- udelay(15000);
+ /* Wait 15ms to make sure the PHY has come out of hard reset */
+ udelay(15000);
+ }
+
return get_phy_device_by_mask(bus, phy_mask, interface);
}
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 79452a8..bba48da 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -41,6 +41,7 @@
#define MIIM_RTL8211F_PAGE_SELECT 0x1f
#define MIIM_RTL8211F_TX_DELAY 0x100
+#define MIIM_RTL8211F_LCR 0x10
/* RealTek RTL8211x */
static int rtl8211x_config(struct phy_device *phydev)
@@ -79,6 +80,13 @@ static int rtl8211f_config(struct phy_device *phydev)
MIIM_RTL8211F_PAGE_SELECT, 0x0);
}
+ /* Set green LED for Link, yellow LED for Active */
+ phy_write(phydev, MDIO_DEVAD_NONE,
+ MIIM_RTL8211F_PAGE_SELECT, 0xd04);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
+ phy_write(phydev, MDIO_DEVAD_NONE,
+ MIIM_RTL8211F_PAGE_SELECT, 0x0);
+
genphy_config_aneg(phydev);
return 0;
diff --git a/net/tftp.c b/net/tftp.c
index 3e99e73..89be32a 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -249,6 +249,8 @@ static void show_block_marker(void)
if (tftp_tsize) {
ulong pos = tftp_cur_block * tftp_block_size +
tftp_block_wrap_offset;
+ if (pos > tftp_tsize)
+ pos = tftp_tsize;
while (tftp_tsize_num_hash < pos * 50 / tftp_tsize) {
putc('#');