aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorStas Sergeev <stsp@list.ru>2015-04-01 13:32:49 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-03 15:08:20 -0400
commit898b2970e2c91e4543b579998922822894325866 (patch)
tree11065a9cf7570f455b747eab454dfc9b48916175 /drivers/net/ethernet
parenta3bebdce4135a44d09e96ba66c40797c8f9fa902 (diff)
mvneta: implement SGMII-based in-band link state signaling
When MDIO bus is unavailable (common setup for SGMII), the in-band signaling must be used to correctly track link state. This patch enables the in-band status delivery for link state changes, namely: - link up/down - link speed - duplex full/half fixed_phy_update_state() is used to update phy status. CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> CC: Florian Fainelli <f.fainelli@gmail.com> CC: netdev@vger.kernel.org CC: linux-kernel@vger.kernel.org Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c106
1 files changed, 95 insertions, 11 deletions
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 96208f17bb53..a7a9271f64b1 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -100,6 +100,8 @@
100#define MVNETA_TXQ_CMD 0x2448 100#define MVNETA_TXQ_CMD 0x2448
101#define MVNETA_TXQ_DISABLE_SHIFT 8 101#define MVNETA_TXQ_DISABLE_SHIFT 8
102#define MVNETA_TXQ_ENABLE_MASK 0x000000ff 102#define MVNETA_TXQ_ENABLE_MASK 0x000000ff
103#define MVNETA_GMAC_CLOCK_DIVIDER 0x24f4
104#define MVNETA_GMAC_1MS_CLOCK_ENABLE BIT(31)
103#define MVNETA_ACC_MODE 0x2500 105#define MVNETA_ACC_MODE 0x2500
104#define MVNETA_CPU_MAP(cpu) (0x2540 + ((cpu) << 2)) 106#define MVNETA_CPU_MAP(cpu) (0x2540 + ((cpu) << 2))
105#define MVNETA_CPU_RXQ_ACCESS_ALL_MASK 0x000000ff 107#define MVNETA_CPU_RXQ_ACCESS_ALL_MASK 0x000000ff
@@ -122,6 +124,7 @@
122#define MVNETA_TX_INTR_MASK_ALL (0xff << 0) 124#define MVNETA_TX_INTR_MASK_ALL (0xff << 0)
123#define MVNETA_RX_INTR_MASK(nr_rxqs) (((1 << nr_rxqs) - 1) << 8) 125#define MVNETA_RX_INTR_MASK(nr_rxqs) (((1 << nr_rxqs) - 1) << 8)
124#define MVNETA_RX_INTR_MASK_ALL (0xff << 8) 126#define MVNETA_RX_INTR_MASK_ALL (0xff << 8)
127#define MVNETA_MISCINTR_INTR_MASK BIT(31)
125 128
126#define MVNETA_INTR_OLD_CAUSE 0x25a8 129#define MVNETA_INTR_OLD_CAUSE 0x25a8
127#define MVNETA_INTR_OLD_MASK 0x25ac 130#define MVNETA_INTR_OLD_MASK 0x25ac
@@ -165,6 +168,7 @@
165#define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc 168#define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc
166#define MVNETA_GMAC0_PORT_ENABLE BIT(0) 169#define MVNETA_GMAC0_PORT_ENABLE BIT(0)
167#define MVNETA_GMAC_CTRL_2 0x2c08 170#define MVNETA_GMAC_CTRL_2 0x2c08
171#define MVNETA_GMAC2_INBAND_AN_ENABLE BIT(0)
168#define MVNETA_GMAC2_PCS_ENABLE BIT(3) 172#define MVNETA_GMAC2_PCS_ENABLE BIT(3)
169#define MVNETA_GMAC2_PORT_RGMII BIT(4) 173#define MVNETA_GMAC2_PORT_RGMII BIT(4)
170#define MVNETA_GMAC2_PORT_RESET BIT(6) 174#define MVNETA_GMAC2_PORT_RESET BIT(6)
@@ -180,9 +184,11 @@
180#define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c 184#define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c
181#define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0) 185#define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0)
182#define MVNETA_GMAC_FORCE_LINK_PASS BIT(1) 186#define MVNETA_GMAC_FORCE_LINK_PASS BIT(1)
187#define MVNETA_GMAC_INBAND_AN_ENABLE BIT(2)
183#define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5) 188#define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5)
184#define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6) 189#define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6)
185#define MVNETA_GMAC_AN_SPEED_EN BIT(7) 190#define MVNETA_GMAC_AN_SPEED_EN BIT(7)
191#define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11)
186#define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) 192#define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
187#define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) 193#define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
188#define MVNETA_MIB_COUNTERS_BASE 0x3080 194#define MVNETA_MIB_COUNTERS_BASE 0x3080
@@ -304,6 +310,7 @@ struct mvneta_port {
304 unsigned int link; 310 unsigned int link;
305 unsigned int duplex; 311 unsigned int duplex;
306 unsigned int speed; 312 unsigned int speed;
313 int use_inband_status:1;
307}; 314};
308 315
309/* The mvneta_tx_desc and mvneta_rx_desc structures describe the 316/* The mvneta_tx_desc and mvneta_rx_desc structures describe the
@@ -994,6 +1001,20 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
994 val &= ~MVNETA_PHY_POLLING_ENABLE; 1001 val &= ~MVNETA_PHY_POLLING_ENABLE;
995 mvreg_write(pp, MVNETA_UNIT_CONTROL, val); 1002 mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
996 1003
1004 if (pp->use_inband_status) {
1005 val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
1006 val &= ~(MVNETA_GMAC_FORCE_LINK_PASS |
1007 MVNETA_GMAC_FORCE_LINK_DOWN |
1008 MVNETA_GMAC_AN_FLOW_CTRL_EN);
1009 val |= MVNETA_GMAC_INBAND_AN_ENABLE |
1010 MVNETA_GMAC_AN_SPEED_EN |
1011 MVNETA_GMAC_AN_DUPLEX_EN;
1012 mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
1013 val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
1014 val |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
1015 mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
1016 }
1017
997 mvneta_set_ucast_table(pp, -1); 1018 mvneta_set_ucast_table(pp, -1);
998 mvneta_set_special_mcast_table(pp, -1); 1019 mvneta_set_special_mcast_table(pp, -1);
999 mvneta_set_other_mcast_table(pp, -1); 1020 mvneta_set_other_mcast_table(pp, -1);
@@ -2043,6 +2064,28 @@ static irqreturn_t mvneta_isr(int irq, void *dev_id)
2043 return IRQ_HANDLED; 2064 return IRQ_HANDLED;
2044} 2065}
2045 2066
2067static int mvneta_fixed_link_update(struct mvneta_port *pp,
2068 struct phy_device *phy)
2069{
2070 struct fixed_phy_status status;
2071 struct fixed_phy_status changed = {};
2072 u32 gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
2073
2074 status.link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
2075 if (gmac_stat & MVNETA_GMAC_SPEED_1000)
2076 status.speed = SPEED_1000;
2077 else if (gmac_stat & MVNETA_GMAC_SPEED_100)
2078 status.speed = SPEED_100;
2079 else
2080 status.speed = SPEED_10;
2081 status.duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
2082 changed.link = 1;
2083 changed.speed = 1;
2084 changed.duplex = 1;
2085 fixed_phy_update_state(phy, &status, &changed);
2086 return 0;
2087}
2088
2046/* NAPI handler 2089/* NAPI handler
2047 * Bits 0 - 7 of the causeRxTx register indicate that are transmitted 2090 * Bits 0 - 7 of the causeRxTx register indicate that are transmitted
2048 * packets on the corresponding TXQ (Bit 0 is for TX queue 1). 2091 * packets on the corresponding TXQ (Bit 0 is for TX queue 1).
@@ -2063,8 +2106,18 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
2063 } 2106 }
2064 2107
2065 /* Read cause register */ 2108 /* Read cause register */
2066 cause_rx_tx = mvreg_read(pp, MVNETA_INTR_NEW_CAUSE) & 2109 cause_rx_tx = mvreg_read(pp, MVNETA_INTR_NEW_CAUSE);
2067 (MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number)); 2110 if (cause_rx_tx & MVNETA_MISCINTR_INTR_MASK) {
2111 u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE);
2112
2113 mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
2114 if (pp->use_inband_status && (cause_misc &
2115 (MVNETA_CAUSE_PHY_STATUS_CHANGE |
2116 MVNETA_CAUSE_LINK_CHANGE |
2117 MVNETA_CAUSE_PSC_SYNC_CHANGE))) {
2118 mvneta_fixed_link_update(pp, pp->phy_dev);
2119 }
2120 }
2068 2121
2069 /* Release Tx descriptors */ 2122 /* Release Tx descriptors */
2070 if (cause_rx_tx & MVNETA_TX_INTR_MASK_ALL) { 2123 if (cause_rx_tx & MVNETA_TX_INTR_MASK_ALL) {
@@ -2109,7 +2162,9 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
2109 napi_complete(napi); 2162 napi_complete(napi);
2110 local_irq_save(flags); 2163 local_irq_save(flags);
2111 mvreg_write(pp, MVNETA_INTR_NEW_MASK, 2164 mvreg_write(pp, MVNETA_INTR_NEW_MASK,
2112 MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number)); 2165 MVNETA_RX_INTR_MASK(rxq_number) |
2166 MVNETA_TX_INTR_MASK(txq_number) |
2167 MVNETA_MISCINTR_INTR_MASK);
2113 local_irq_restore(flags); 2168 local_irq_restore(flags);
2114 } 2169 }
2115 2170
@@ -2373,7 +2428,13 @@ static void mvneta_start_dev(struct mvneta_port *pp)
2373 2428
2374 /* Unmask interrupts */ 2429 /* Unmask interrupts */
2375 mvreg_write(pp, MVNETA_INTR_NEW_MASK, 2430 mvreg_write(pp, MVNETA_INTR_NEW_MASK,
2376 MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number)); 2431 MVNETA_RX_INTR_MASK(rxq_number) |
2432 MVNETA_TX_INTR_MASK(txq_number) |
2433 MVNETA_MISCINTR_INTR_MASK);
2434 mvreg_write(pp, MVNETA_INTR_MISC_MASK,
2435 MVNETA_CAUSE_PHY_STATUS_CHANGE |
2436 MVNETA_CAUSE_LINK_CHANGE |
2437 MVNETA_CAUSE_PSC_SYNC_CHANGE);
2377 2438
2378 phy_start(pp->phy_dev); 2439 phy_start(pp->phy_dev);
2379 netif_tx_start_all_queues(pp->dev); 2440 netif_tx_start_all_queues(pp->dev);
@@ -2523,9 +2584,7 @@ static void mvneta_adjust_link(struct net_device *ndev)
2523 val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); 2584 val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
2524 val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED | 2585 val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
2525 MVNETA_GMAC_CONFIG_GMII_SPEED | 2586 MVNETA_GMAC_CONFIG_GMII_SPEED |
2526 MVNETA_GMAC_CONFIG_FULL_DUPLEX | 2587 MVNETA_GMAC_CONFIG_FULL_DUPLEX);
2527 MVNETA_GMAC_AN_SPEED_EN |
2528 MVNETA_GMAC_AN_DUPLEX_EN);
2529 2588
2530 if (phydev->duplex) 2589 if (phydev->duplex)
2531 val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; 2590 val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
@@ -2554,12 +2613,24 @@ static void mvneta_adjust_link(struct net_device *ndev)
2554 2613
2555 if (status_change) { 2614 if (status_change) {
2556 if (phydev->link) { 2615 if (phydev->link) {
2557 u32 val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); 2616 if (!pp->use_inband_status) {
2558 val |= (MVNETA_GMAC_FORCE_LINK_PASS | 2617 u32 val = mvreg_read(pp,
2559 MVNETA_GMAC_FORCE_LINK_DOWN); 2618 MVNETA_GMAC_AUTONEG_CONFIG);
2560 mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); 2619 val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
2620 val |= MVNETA_GMAC_FORCE_LINK_PASS;
2621 mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
2622 val);
2623 }
2561 mvneta_port_up(pp); 2624 mvneta_port_up(pp);
2562 } else { 2625 } else {
2626 if (!pp->use_inband_status) {
2627 u32 val = mvreg_read(pp,
2628 MVNETA_GMAC_AUTONEG_CONFIG);
2629 val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
2630 val |= MVNETA_GMAC_FORCE_LINK_DOWN;
2631 mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
2632 val);
2633 }
2563 mvneta_port_down(pp); 2634 mvneta_port_down(pp);
2564 } 2635 }
2565 phy_print_status(phydev); 2636 phy_print_status(phydev);
@@ -2910,6 +2981,9 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
2910 return -EINVAL; 2981 return -EINVAL;
2911 } 2982 }
2912 2983
2984 if (pp->use_inband_status)
2985 ctrl |= MVNETA_GMAC2_INBAND_AN_ENABLE;
2986
2913 /* Cancel Port Reset */ 2987 /* Cancel Port Reset */
2914 ctrl &= ~MVNETA_GMAC2_PORT_RESET; 2988 ctrl &= ~MVNETA_GMAC2_PORT_RESET;
2915 mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl); 2989 mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl);
@@ -2934,6 +3008,7 @@ static int mvneta_probe(struct platform_device *pdev)
2934 char hw_mac_addr[ETH_ALEN]; 3008 char hw_mac_addr[ETH_ALEN];
2935 const char *mac_from; 3009 const char *mac_from;
2936 int phy_mode; 3010 int phy_mode;
3011 int fixed_phy = 0;
2937 int err; 3012 int err;
2938 3013
2939 /* Our multiqueue support is not complete, so for now, only 3014 /* Our multiqueue support is not complete, so for now, only
@@ -2967,6 +3042,7 @@ static int mvneta_probe(struct platform_device *pdev)
2967 dev_err(&pdev->dev, "cannot register fixed PHY\n"); 3042 dev_err(&pdev->dev, "cannot register fixed PHY\n");
2968 goto err_free_irq; 3043 goto err_free_irq;
2969 } 3044 }
3045 fixed_phy = 1;
2970 3046
2971 /* In the case of a fixed PHY, the DT node associated 3047 /* In the case of a fixed PHY, the DT node associated
2972 * to the PHY is the Ethernet MAC DT node. 3048 * to the PHY is the Ethernet MAC DT node.
@@ -2990,6 +3066,8 @@ static int mvneta_probe(struct platform_device *pdev)
2990 pp = netdev_priv(dev); 3066 pp = netdev_priv(dev);
2991 pp->phy_node = phy_node; 3067 pp->phy_node = phy_node;
2992 pp->phy_interface = phy_mode; 3068 pp->phy_interface = phy_mode;
3069 pp->use_inband_status = (phy_mode == PHY_INTERFACE_MODE_SGMII) &&
3070 fixed_phy;
2993 3071
2994 pp->clk = devm_clk_get(&pdev->dev, NULL); 3072 pp->clk = devm_clk_get(&pdev->dev, NULL);
2995 if (IS_ERR(pp->clk)) { 3073 if (IS_ERR(pp->clk)) {
@@ -3067,6 +3145,12 @@ static int mvneta_probe(struct platform_device *pdev)
3067 3145
3068 platform_set_drvdata(pdev, pp->dev); 3146 platform_set_drvdata(pdev, pp->dev);
3069 3147
3148 if (pp->use_inband_status) {
3149 struct phy_device *phy = of_phy_find_device(dn);
3150
3151 mvneta_fixed_link_update(pp, phy);
3152 }
3153
3070 return 0; 3154 return 0;
3071 3155
3072err_free_stats: 3156err_free_stats: