Thread (16 messages) 16 messages, 4 authors, 2021-07-20

RE: [PATCH/RFC 2/2] ravb: Add GbEthernet driver support

From: Biju Das <biju.das.jz@bp.renesas.com>
Date: 2021-07-14 17:01:41
Also in: linux-renesas-soc

Hi Andrew Lunn,

Thanks for the feedback.
Subject: Re: [PATCH/RFC 2/2] ravb: Add GbEthernet driver support
quoted
+	if (priv->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) {
+		ravb_write(ndev, ravb_read(ndev, CXR31)
+			 | CXR31_SEL_LINK0, CXR31);
+	} else {
+		ravb_write(ndev, ravb_read(ndev, CXR31)
+			 & ~CXR31_SEL_LINK0, CXR31);
+	}
You need to be very careful here. What value is passed to the PHY?
PHY_INTERFACE_MODE_RGMII is the value passed to PHY.

The below code is used only by R-Car3, where MAC supports internal delay.
There is some funky code:

       /* Fall back to legacy rgmii-*id behavior */
        if (priv->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
            priv->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) {
                priv->rxcidm = 1;
                priv->rgmii_override = 1;
        }

        if (priv->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
            priv->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) {
                if (!WARN(soc_device_match(ravb_delay_mode_quirk_match),
                          "phy-mode %s requires TX clock internal delay
mode which is not supported by this hardware revision. Please update
device tree",
                          phy_modes(priv->phy_interface))) {
                        priv->txcidm = 1;
                        priv->rgmii_override = 1;
                }
        }
...

        iface = priv->rgmii_override ? PHY_INTERFACE_MODE_RGMII
                                     : priv->phy_interface;
        phydev = of_phy_connect(ndev, pn, ravb_adjust_link, 0, iface);

So it looks like, with PHY_INTERFACE_MODE_RGMII_ID,
PHY_INTERFACE_MODE_RGMII_TXID, PHY_INTERFACE_MODE_RGMII_RXID the PHY is
passed PHY_INTERFACE_MODE_RGMII, with the assumption the MAC is adding the
delay. But it looks like you are only adding a delay for
PHY_INTERFACE_MODE_RGMII_ID. So this appears wrong.
This SoC family doesn't use that code and doesn't support MAC internal delay. 
It is applicable only for R-Car Gen3 whet it sets "priv->rgmii_override"
For other SoC's it is just priv->phy_interface.
quoted
@@ -1082,15 +1440,23 @@ static int ravb_phy_init(struct net_device
*ndev)
quoted
 		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 (priv->chip_id == RZ_G2L) {
+		if (priv->phy_interface == PHY_INTERFACE_MODE_RGMII_ID)
+			ravb_write(ndev, ravb_read(ndev, CXR35) |
CXR35_SEL_MODIN, CXR35);
quoted
+		else if (priv->phy_interface == PHY_INTERFACE_MODE_RGMII)
+			ravb_write(ndev, 0x3E80000, CXR35);
This is not obviously correct. What about the other two RGMII modes?
quoted
@@ -1348,6 +1741,21 @@ static const struct ethtool_ops ravb_ethtool_ops
= {
quoted
 	.set_wol		= ravb_set_wol,
 };

+static const struct ethtool_ops rgeth_ethtool_ops = {
+	.nway_reset		= phy_ethtool_nway_reset,
+	.get_msglevel		= ravb_get_msglevel,
+	.set_msglevel		= ravb_set_msglevel,
+	.get_link		= ethtool_op_get_link,
+	.get_strings		= ravb_get_strings,
+	.get_ethtool_stats	= ravb_get_ethtool_stats,
+	.get_sset_count		= ravb_get_sset_count,
+	.get_ringparam		= ravb_get_ringparam,
+	.set_ringparam		= ravb_set_ringparam,
+	.get_ts_info		= ravb_get_ts_info,
+	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
+	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
+};
It is not obvious why you need a seperate ethtool_ops structure? Does it
not support WOL?
Yes,WOL is supported by WAKE_PHY. As per HW manual MAGIC packet detection is not supported.
OK I will add wol. Also it supports eee which we are planning to add later stage.

quoted
+static const struct net_device_ops rgeth_netdev_ops = {
+	.ndo_open               = ravb_open,
+	.ndo_stop               = ravb_close,
+	.ndo_start_xmit         = ravb_start_xmit,
+	.ndo_select_queue       = ravb_select_queue,
+	.ndo_get_stats          = ravb_get_stats,
+	.ndo_set_rx_mode        = ravb_set_rx_mode,
+	.ndo_tx_timeout         = ravb_tx_timeout,
+	.ndo_do_ioctl           = ravb_do_ioctl,
+	.ndo_validate_addr      = eth_validate_addr,
+	.ndo_set_mac_address    = eth_mac_addr,
+	.ndo_set_features       = rgeth_set_features,
It seems like .ndo_set_features is the only difference. Maybe handle that
in actual function?
OK will do.
quoted
@@ -1965,6 +2446,7 @@ static const struct of_device_id
ravb_match_table[] = {
quoted
 	{ .compatible = "renesas,etheravb-rcar-gen2", .data = (void
*)RCAR_GEN2 },
quoted
 	{ .compatible = "renesas,etheravb-r8a7795", .data = (void
*)RCAR_GEN3 },
quoted
 	{ .compatible = "renesas,etheravb-rcar-gen3", .data = (void
*)RCAR_GEN3 },
+	{ .compatible = "renesas,rzg2l-gether", .data = (void *)RZ_G2L },
 	{ }
 };
Please document the new compatible string in the DT binding.
OK. Will do

Thanks,
Biju
       Andrew
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help