From 7e2d991d63f2d24d567e259c822f24aa08c85d88 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Tue, 19 May 2015 10:01:18 -0700 Subject: e1000: releasing semaphore once no longer needed Once the hwsw semaphore is acquired, it must be released when access to the hw is completed. Without this subsequent calls to acquire will timeout obtaining the semaphore. Cc: Marcel Ziswiler Cc: Marek Vasut Cc: Aneesh Bansal Cc: Naveen Burmi Cc: Po Liu Cc: Bin Meng Cc: Alison Wang Cc: Reinhard Arlt Cc: Shengzhou Liu Cc: York Sun Signed-off-by: Tim Harvey Tested-by: Bin Meng Tested-by: Marcel Ziswiler diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 96e6bb0..b49980a 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. * @@ -1102,6 +1106,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) { @@ -1141,6 +1146,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) { @@ -4462,6 +4482,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) -- cgit v0.10.2 From 3c63dd5302a2f14c292a469b9934a8fc02b627cc Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Tue, 19 May 2015 10:01:19 -0700 Subject: Revert "e1000: fix sw fw sync on igb i210/i211" This reverts commit 17da7120249bfdef877f46be5bbcb3cc01212eb9. The i210/i211 do have the SW_FW_SYNC (0x5b5c) register and this is what should be used when acquiring the semaphore. I believe the issue that this patch was trying to resolve is now resolved by properly releasing the semaphore once no longer needed. Cc: Marcel Ziswiler Cc: Marek Vasut Cc: Aneesh Bansal Cc: Naveen Burmi Cc: Po Liu Cc: Bin Meng Cc: Alison Wang Cc: Reinhard Arlt Cc: Shengzhou Liu Cc: York Sun Signed-off-by: Tim Harvey Tested-by: Bin Meng Tested-by: Marcel Ziswiler diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index b49980a..739d24b 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -1120,10 +1120,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; @@ -4458,6 +4455,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. diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index f3b77b1..232c95d 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -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 */ -- cgit v0.10.2 From 48b168bbfa97e4ebb7c093696c27dfb32bf82ad8 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Tue, 19 May 2015 10:01:20 -0700 Subject: e1000: remove unnecessary clearing of SWSM.SWSM_SMBI remove unnecessary clearing of SWSM.SWSM_SMBI when obtaining the SW semaphore. This was introduced in 951860634fdb557bbb58e0f99215391bc0c29779 while adding i210 support and should be now resolved by releasing the semaphore when no longer needed. Cc: Marcel Ziswiler Cc: Marek Vasut Cc: Aneesh Bansal Cc: Naveen Burmi Cc: Po Liu Cc: Bin Meng Cc: Alison Wang Cc: Reinhard Arlt Cc: Shengzhou Liu Cc: York Sun Signed-off-by: Tim Harvey Tested-by: Bin Meng Tested-by: Marcel Ziswiler diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 739d24b..ecd1a52 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -996,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; -- cgit v0.10.2 From 90712741c9f03c4fddc5d71f4c397d5e18f94a3d Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Thu, 21 May 2015 18:07:35 +0800 Subject: net/phy: set led for rtl8211f phy Initialize LCR rigister to configure green LED for Link, yellow LED for Active. Signed-off-by: Shengzhou Liu 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; -- cgit v0.10.2 From ade4ea4d71f6dad6683087621eb27bbcdfa6871d Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Wed, 3 Jun 2015 16:45:44 +0800 Subject: net: macb: add gmac multi-queue support This patch refer to linux kernel commit: d8b763e1e79f net/macb: add TX multiqueue support for gem by: Cyrille Pitchen 1. macb driver will check the register to find how many queues support for this chip. 2. Then as we only use queue0 for tx, so we will set up all other queues use a dummy descriptor, which USED bit is set. So those queues are not used. Signed-off-by: Josh Wu Acked-by: Joe Hershberger 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__ */ -- cgit v0.10.2 From 90a94ef6521b0a512c594d8d1cbcd8093fdecfb5 Mon Sep 17 00:00:00 2001 From: Clemens Gruber Date: Sat, 6 Jun 2015 14:44:57 +0200 Subject: net: Improve 88E151x PHY initialization - The EEE fixup magic should also be enabled for RGMII - Improved comments Signed-off-by: Clemens Gruber Cc: Joe Hershberger Cc: Hao Zhang Cc: Michal Simek Acked-by: Joe Hershberger diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 9437c3b..cff5c87 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -303,24 +303,33 @@ 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); } -- cgit v0.10.2 From 8396d0ab8b46907bd89e9f3a35fbb727f077d28a Mon Sep 17 00:00:00 2001 From: Clemens Gruber Date: Sat, 6 Jun 2015 14:44:58 +0200 Subject: net: Add support for Marvell 88E1510 PHY Support the 88E1510 PHY which is very similar to the 88E1518. I also set the INTn output and configured the LEDs. Signed-off-by: Clemens Gruber Cc: Joe Hershberger Cc: Hao Zhang Cc: Michal Simek Acked-by: Joe Hershberger diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index cff5c87..eab1558 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -336,6 +336,25 @@ static int m88e1518_config(struct phy_device *phydev) 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) { @@ -548,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, @@ -578,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; -- cgit v0.10.2 From 0b830198fb3c6ee0dbbe5aa98829eddbb27429b1 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sun, 7 Jun 2015 17:30:38 +0200 Subject: net: davinci_emac: don't teardown inactive rx channel Tearing down an unitialized rx channel causes a pending address hole event to be queued. When booting linux it will report this pending as something like "Address Hole seen by USB_OTG at address 57fff584", since u-boot did not handled this interrupt. Prevent that by not tearing down the rx channel, when not receiving. Signed-off-by: Jeroen Hofstee 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); -- cgit v0.10.2 From 6e039b4c624e293fb86710efd12a17afe268d6e9 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Sun, 28 Jun 2015 06:03:38 +0300 Subject: net: lpc32xx: correct command register reset value According to LPC32x0 User Manual the following bits in Command register 0x3106_0100 are defined: Bit Symbol 2 - Unused 3 RegReset 4 TxReset 5 RxReset Fix wrong (1-bit shifted right) COMMAND_RESETS value, which sets an unused bit, but neglects RxReset. Signed-off-by: Vladimir Zapolskiy Acked-by: Albert ARIBAUD (3ADEV) Acked-by: Joe Hershberger diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index 8dcbb4a..72451a9 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -170,7 +170,7 @@ struct lpc32xx_eth_registers { #define COMMAND_PASSRUNTFRAME 0x00000040 #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 -- cgit v0.10.2 From fe0596cac3079a74eeee93e2940010a7a158c58d Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 29 Jun 2015 03:35:12 +0300 Subject: net: lpc32xx: connect MAC to phy with CONFIG_PHY_ADDR id The lpc32xx_eth_phylib_init() function is capable to connect LPC32XX MAC to some specified phy by phy id, by chance the single user of lpc32xx_eth has CONFIG_PHY_ADDR set to 0, however other boards may have non-zero CONFIG_PHY_ADDR value, fix it. Signed-off-by: Vladimir Zapolskiy Acked-by: Albert ARIBAUD (3ADEV) Acked-by: Joe Hershberger diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index 72451a9..6033392 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -630,7 +630,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 -- cgit v0.10.2 From 23f5db0e26f0e6c25ba143e700b4812efdd5f941 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 6 Jul 2015 07:22:10 +0300 Subject: net: lpc32xx: improve MAC configuration on reset and initialization This change rearranges general MAC configuration and PHY specific configuration of MAC registers (duplex mode and speed), before this change set bits related to PHY configuration in MAC2 and COMMAND registers are rewritten by the following writing to the registers. Without the change auto negotiation on boot quite often is not completed in reasonable time: Waiting for PHY auto negotiation to complete......... TIMEOUT ! Additionally MAC1_SOFT_RESET clear bit is removed since it is done in preceding lpc32xx_eth_initialize() and in lpc32xx_eth_halt(), instead added missing MCFG_RESET_MII_MGMT on device initialization. Signed-off-by: Vladimir Zapolskiy diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index 6033392..f883a25 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 @@ -459,8 +459,19 @@ 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(®s->mac1, MAC1_SOFT_RESET); + /* Initial MAC initialization */ + writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); + writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); + writel(PKTSIZE_ALIGN, ®s->maxf); + + /* Retries: 15 (0xF). Collision window: 57 (0x37). */ + writel(0x370F, ®s->clrt); + + /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ + writel(0x0012, ®s->ipgr); + + /* pass runt (smaller than 64 bytes) frames */ + writel(COMMAND_PASSRUNTFRAME, ®s->command); /* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -477,20 +488,6 @@ static int lpc32xx_eth_init(struct eth_device *dev) else writel(0, ®s->supp); - /* Initial MAC initialization */ - writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); - writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); - writel(PKTSIZE_ALIGN, ®s->maxf); - - /* Retries: 15 (0xF). Collision window: 57 (0x37). */ - writel(0x370F, ®s->clrt); - - /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ - writel(0x0012, ®s->ipgr); - - /* pass runt (smaller than 64 bytes) frames */ - writel(COMMAND_PASSRUNTFRAME, ®s->command); - /* Save station address */ writel((unsigned long) (dev->enetaddr[0] | (dev->enetaddr[1] << 8)), ®s->sa2); @@ -604,7 +601,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, ®s->mcfg); writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg); /* Reset all MAC logic */ -- cgit v0.10.2 From 1a791892dcb5904c8b208535704714b07802e0b8 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 6 Jul 2015 07:22:11 +0300 Subject: net: lpc32xx: add RMII phy mode support LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII. It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit. Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value. Signed-off-by: Vladimir Zapolskiy Tested-by: Sylvain Lemieux diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index 5a453e3..9c8d655 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/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index f883a25..f3ab0f4 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -168,6 +168,7 @@ 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 0x00000038 @@ -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 @@ -471,7 +476,10 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel(0x0012, ®s->ipgr); /* pass runt (smaller than 64 bytes) frames */ - writel(COMMAND_PASSRUNTFRAME, ®s->command); + if (lpc32xx_eth_device->phy_rmii) + writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); + else + writel(COMMAND_PASSRUNTFRAME, ®s->command); /* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -559,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; @@ -579,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; -- cgit v0.10.2 From 466f775e02bcde5ea7454cd73ecf1a0f79275a30 Mon Sep 17 00:00:00 2001 From: Daniel Inderbitzin Date: Fri, 10 Jul 2015 14:06:02 +0200 Subject: qoriq eth.c bugfix: handle received corrupted frames correctly The rxbd is not correctly handled in case of a frame physical error (FPE) or frame size error (FSE). The rxbd must be cleared and advanced in case of an error to avoid receive stall. Signed-off-by: Daniel Inderbitzin 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) -- cgit v0.10.2 From 2c171a2a5fc0865501a2e5043e9728036dac6dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= Date: Wed, 15 Jul 2015 14:58:49 +0200 Subject: net: phy: fix data type of phy_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit phy_id is declared as u32 in create_phy_by_mask and in struct phy_device. Signed-off-by: Jörg Krause diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index c8d08e8..865abab 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; -- cgit v0.10.2 From 59370f3fcd135089c402c93720a87c688abe600c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= Date: Wed, 15 Jul 2015 15:18:22 +0200 Subject: net: phy: delay only if reset handler is registered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With commit e3a77218a256edbe201112a39beeed8adcabae3f the MII bus is only reset if a reset handler is registered. If there is no reset handler there is no need to wait for a device to come out of the reset. Signed-off-by: Jörg Krause diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 865abab..65c731a 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -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); } -- cgit v0.10.2 From 1b564cecc358ccd08691c879fca95c2075fcb702 Mon Sep 17 00:00:00 2001 From: Jiandong Zheng Date: Wed, 15 Jul 2015 16:28:13 -0700 Subject: net: phy: broadcom: Add BCM Cygnus PHY Add Ethernet PHY for BCM Cygnus SoC Signed-off-by: Jiandong Zheng Signed-off-by: Steve Rae Acked-by: Joe Hershberger 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; } -- cgit v0.10.2 From 7628afebe9685a333e0a42398ed8be749a1fef0d Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 5 Aug 2015 17:17:05 +0200 Subject: tftp.c: fix CONFIG_TFTP_TSIZE for small files CONFIG_TFTP_TSIZE should limit a tftp downloads progress to 50 '#' chars. Make this work also for small files. If the file size is small, i.e. smaller than 2 tftp block sizes the number of '#' can get much larger. i.e. with a 1 byte file 65000 characters are printed, with a 512 byte file around 500. When using CONFIG TFTP BLOCKSIZE together with CONFIG_IP_DEFRAG the issue is more notable. Signed-off-by: Max Krummenacher Signed-off-by: Marcel Ziswiler Reviewed-by: Marek Vasut Acked-by: Joe Hershberger 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('#'); -- cgit v0.10.2 From faa765d40760d84bff0de26a5a5f605621dbff39 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 11 Aug 2015 17:12:44 +0200 Subject: net: e1000: Increase autoneg timeout to 8 seconds The current 4.5 timeout for the autonegotiation are not enough to complete it on my platform. Using the Intel E1000 PCIe card in the Marvell db-mv784mp-gp eval board. So lets increase the timeout to 8 seconds. Signed-off-by: Stefan Roese Cc: Joe Hershberger Cc: Simon Glass diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index ecd1a52..d5d48b1 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -4017,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. diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 232c95d..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 */ -- cgit v0.10.2