aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-04-16 14:37:13 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-16 14:37:13 -0400
commitb07afe07b10f24c4fd962330be3618ef965a4781 (patch)
treeb1f0e9de7fd4199d88afbf4258564af05bd8c1ac /drivers/net
parente283546c0465dd3026bc94f7b1a9de7f6b8969ec (diff)
parent3f1dd4bcfe2c19a336e01e32a928fcdb8cc43e5c (diff)
Merge branch 'mvneta_qsgmii'
Thomas Petazzoni says: ==================== net: mvneta: fix usage as a module, and support QSGMII properly This set of patches is a new attempt at fixing the operation of the mvneta driver when built as a module. For the record, the previous attempt, merged in commit e3a8786c10e75903f1269474e21fe8cb49c3a670 ('net: mvneta: fix usage as a module on RGMII configurations') caused problems for all RGMII configurations. In fact, it turned out that the MAC to PHY connection on the Armada XP GP, which was described as using RGMII-ID according to its Device Tree, is in fact a QSGMII connection. And the RGMII and QSGMII configurations have to be handled in a different way in the driver, because the SERDES configuration is different in those two cases. So, this patch series fixes that by: * Adding minimal handling of a "qsgmii" connection type in the PHY layer. Mainly to make sure that a "qsgmii" phy-mode in the Device Tree is recognized, and handed over to the driver as PHY_INTERFACE_QSGMII. * Changing the mvneta driver to properly configure the RGMIIEn and PCSEn bits in the GMAC_CTRL_2 register, and configure the SERDES register, in the three possible cases: RGMII, SGMII and QSGMII. * Updating the Device Tree of the Armada XP GP board to reflect the fact that it uses a QSGMII MAC/PHY connection. PATCH 1 and 2 would be merged by David Miller, through the net tree, while PATCH 3 would be merged by the mach-mvebu maintainers, through their tree and arm-soc. This set of patches has been tested on: * Armada XP GP (four QSGMII interfaces) * Armada XP DB (two RGMII interfaces and two SGMII interfaces) * Armada 370 Mirabox (two RGMII interfaces) I've tested both the driver built-in, and compiled as a module. Since the last attempt at fixing this was quite a fiasco, I'd like this new attempt to be tested more widely before being applied. I'll try to do some testing on other Armada boards I have, but independent testing from other persons would also be appreciated. Note that these patches apply after reverting the previous attempt, obviously. ==================== Tested-by: Arnaud Ebalard <arno@natisbad.org> Tested-by: Willy Tarreau <w@1wt.eu> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index b248bcbdae63..14786c8bf99e 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -89,8 +89,9 @@
89#define MVNETA_TX_IN_PRGRS BIT(1) 89#define MVNETA_TX_IN_PRGRS BIT(1)
90#define MVNETA_TX_FIFO_EMPTY BIT(8) 90#define MVNETA_TX_FIFO_EMPTY BIT(8)
91#define MVNETA_RX_MIN_FRAME_SIZE 0x247c 91#define MVNETA_RX_MIN_FRAME_SIZE 0x247c
92#define MVNETA_SGMII_SERDES_CFG 0x24A0 92#define MVNETA_SERDES_CFG 0x24A0
93#define MVNETA_SGMII_SERDES_PROTO 0x0cc7 93#define MVNETA_SGMII_SERDES_PROTO 0x0cc7
94#define MVNETA_QSGMII_SERDES_PROTO 0x0667
94#define MVNETA_TYPE_PRIO 0x24bc 95#define MVNETA_TYPE_PRIO 0x24bc
95#define MVNETA_FORCE_UNI BIT(21) 96#define MVNETA_FORCE_UNI BIT(21)
96#define MVNETA_TXQ_CMD_1 0x24e4 97#define MVNETA_TXQ_CMD_1 0x24e4
@@ -711,35 +712,6 @@ static void mvneta_rxq_bm_disable(struct mvneta_port *pp,
711 mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); 712 mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
712} 713}
713 714
714
715
716/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */
717static void mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable)
718{
719 u32 val;
720
721 val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
722
723 if (enable)
724 val |= MVNETA_GMAC2_PORT_RGMII;
725 else
726 val &= ~MVNETA_GMAC2_PORT_RGMII;
727
728 mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
729}
730
731/* Config SGMII port */
732static void mvneta_port_sgmii_config(struct mvneta_port *pp)
733{
734 u32 val;
735
736 val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
737 val |= MVNETA_GMAC2_PCS_ENABLE;
738 mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
739
740 mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
741}
742
743/* Start the Ethernet port RX and TX activity */ 715/* Start the Ethernet port RX and TX activity */
744static void mvneta_port_up(struct mvneta_port *pp) 716static void mvneta_port_up(struct mvneta_port *pp)
745{ 717{
@@ -2749,26 +2721,44 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp,
2749} 2721}
2750 2722
2751/* Power up the port */ 2723/* Power up the port */
2752static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) 2724static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
2753{ 2725{
2754 u32 val; 2726 u32 ctrl;
2755 2727
2756 /* MAC Cause register should be cleared */ 2728 /* MAC Cause register should be cleared */
2757 mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0); 2729 mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
2758 2730
2759 if (phy_mode == PHY_INTERFACE_MODE_SGMII) 2731 ctrl = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
2760 mvneta_port_sgmii_config(pp);
2761 2732
2762 mvneta_gmac_rgmii_set(pp, 1); 2733 /* Even though it might look weird, when we're configured in
2734 * SGMII or QSGMII mode, the RGMII bit needs to be set.
2735 */
2736 switch(phy_mode) {
2737 case PHY_INTERFACE_MODE_QSGMII:
2738 mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
2739 ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
2740 break;
2741 case PHY_INTERFACE_MODE_SGMII:
2742 mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
2743 ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
2744 break;
2745 case PHY_INTERFACE_MODE_RGMII:
2746 case PHY_INTERFACE_MODE_RGMII_ID:
2747 ctrl |= MVNETA_GMAC2_PORT_RGMII;
2748 break;
2749 default:
2750 return -EINVAL;
2751 }
2763 2752
2764 /* Cancel Port Reset */ 2753 /* Cancel Port Reset */
2765 val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); 2754 ctrl &= ~MVNETA_GMAC2_PORT_RESET;
2766 val &= ~MVNETA_GMAC2_PORT_RESET; 2755 mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl);
2767 mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
2768 2756
2769 while ((mvreg_read(pp, MVNETA_GMAC_CTRL_2) & 2757 while ((mvreg_read(pp, MVNETA_GMAC_CTRL_2) &
2770 MVNETA_GMAC2_PORT_RESET) != 0) 2758 MVNETA_GMAC2_PORT_RESET) != 0)
2771 continue; 2759 continue;
2760
2761 return 0;
2772} 2762}
2773 2763
2774/* Device initialization routine */ 2764/* Device initialization routine */
@@ -2879,7 +2869,12 @@ static int mvneta_probe(struct platform_device *pdev)
2879 dev_err(&pdev->dev, "can't init eth hal\n"); 2869 dev_err(&pdev->dev, "can't init eth hal\n");
2880 goto err_free_stats; 2870 goto err_free_stats;
2881 } 2871 }
2882 mvneta_port_power_up(pp, phy_mode); 2872
2873 err = mvneta_port_power_up(pp, phy_mode);
2874 if (err < 0) {
2875 dev_err(&pdev->dev, "can't power up port\n");
2876 goto err_deinit;
2877 }
2883 2878
2884 dram_target_info = mv_mbus_dram_info(); 2879 dram_target_info = mv_mbus_dram_info();
2885 if (dram_target_info) 2880 if (dram_target_info)