]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ravb: Add half_duplex to struct ravb_hw_info
authorBiju Das <biju.das.jz@bp.renesas.com>
Fri, 1 Oct 2021 15:06:35 +0000 (16:06 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Oct 2021 12:52:46 +0000 (13:52 +0100)
RZ/G2L supports half duplex mode.
Add a half_duplex hw feature bit to struct ravb_hw_info for
supporting half duplex mode for RZ/G2L.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/renesas/ravb.h
drivers/net/ethernet/renesas/ravb_main.c

index f0d9b7bc8c202b0a9af69dcae9ae9ca358e4b8b2..d83d3b4f3f5f1cafaeba18828583fa69e7a4b460 100644 (file)
@@ -1008,6 +1008,7 @@ struct ravb_hw_info {
        unsigned ccc_gac:1;             /* AVB-DMAC has gPTP support active in config mode */
        unsigned nc_queue:1;            /* AVB-DMAC has NC queue */
        unsigned magic_pkt:1;           /* E-MAC supports magic packet detection */
+       unsigned half_duplex:1;         /* E-MAC supports half duplex mode */
 };
 
 struct ravb_private {
@@ -1062,6 +1063,8 @@ struct ravb_private {
        unsigned rgmii_override:1;      /* Deprecated rgmii-*id behavior */
        unsigned int num_tx_desc;       /* TX descriptors per packet */
 
+       int duplex;
+
        const struct ravb_hw_info *info;
        struct reset_control *rstc;
 };
index 6fb11d4cfc57435eb21b24f9e5958a4e1b685d8f..3e694738e683bc22dff1c957c45c4f5c90f0e5b4 100644 (file)
@@ -1091,6 +1091,13 @@ out:
        return budget - quota;
 }
 
+static void ravb_set_duplex_gbeth(struct net_device *ndev)
+{
+       struct ravb_private *priv = netdev_priv(ndev);
+
+       ravb_modify(ndev, ECMR, ECMR_DM, priv->duplex > 0 ? ECMR_DM : 0);
+}
+
 /* PHY state control function */
 static void ravb_adjust_link(struct net_device *ndev)
 {
@@ -1107,6 +1114,12 @@ static void ravb_adjust_link(struct net_device *ndev)
                ravb_rcv_snd_disable(ndev);
 
        if (phydev->link) {
+               if (info->half_duplex && phydev->duplex != priv->duplex) {
+                       new_state = true;
+                       priv->duplex = phydev->duplex;
+                       ravb_set_duplex_gbeth(ndev);
+               }
+
                if (phydev->speed != priv->speed) {
                        new_state = true;
                        priv->speed = phydev->speed;
@@ -1121,6 +1134,8 @@ static void ravb_adjust_link(struct net_device *ndev)
                new_state = true;
                priv->link = 0;
                priv->speed = 0;
+               if (info->half_duplex)
+                       priv->duplex = -1;
        }
 
        /* Enable TX and RX right over here, if E-MAC change is ignored */
@@ -1143,6 +1158,7 @@ static int ravb_phy_init(struct net_device *ndev)
 {
        struct device_node *np = ndev->dev.parent->of_node;
        struct ravb_private *priv = netdev_priv(ndev);
+       const struct ravb_hw_info *info = priv->info;
        struct phy_device *phydev;
        struct device_node *pn;
        phy_interface_t iface;
@@ -1150,6 +1166,7 @@ static int ravb_phy_init(struct net_device *ndev)
 
        priv->link = 0;
        priv->speed = 0;
+       priv->duplex = -1;
 
        /* Try connecting to PHY */
        pn = of_parse_phandle(np, "phy-handle", 0);
@@ -1188,15 +1205,17 @@ static int ravb_phy_init(struct net_device *ndev)
                netdev_info(ndev, "limited PHY to 100Mbit/s\n");
        }
 
-       /* 10BASE, Pause and Asym Pause is not supported */
-       phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
-       phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
-       phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Pause_BIT);
-       phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
+       if (!info->half_duplex) {
+               /* 10BASE, Pause and Asym Pause is not supported */
+               phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
+               phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
+               phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Pause_BIT);
+               phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
 
-       /* Half Duplex is not supported */
-       phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
-       phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
+               /* Half Duplex is not supported */
+               phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
+               phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
+       }
 
        phy_attached_info(phydev);
 
@@ -2175,6 +2194,7 @@ static const struct ravb_hw_info gbeth_hw_info = {
        .tsrq = TCCR_TSRQ0,
        .aligned_tx = 1,
        .tx_counters = 1,
+       .half_duplex = 1,
 };
 
 static const struct of_device_id ravb_match_table[] = {