Thread (40 messages) read the whole thread 40 messages, 4 authors, 2024-11-26

Re: [PATCH net-next v2 13/21] motorcomm:yt6801: Implement some ethtool_ops function

From: Andrew Lunn <andrew@lunn.ch>
Date: 2024-11-22 22:34:15
Also in: lkml

+static const struct fxgmac_stats_desc fxgmac_gstring_stats[] = {
+	/* MMC TX counters */
+	FXGMAC_STAT("tx_bytes", txoctetcount_gb),
+	FXGMAC_STAT("tx_bytes_good", txoctetcount_g),
+	FXGMAC_STAT("tx_packets", txframecount_gb),
+	FXGMAC_STAT("tx_packets_good", txframecount_g),
+	FXGMAC_STAT("tx_unicast_packets", txunicastframes_gb),
+	FXGMAC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
+	FXGMAC_STAT("tx_broadcast_packets_good", txbroadcastframes_g),
+	FXGMAC_STAT("tx_multicast_packets", txmulticastframes_gb),
+	FXGMAC_STAT("tx_multicast_packets_good", txmulticastframes_g),
+	FXGMAC_STAT("tx_vlan_packets_good", txvlanframes_g),
+	FXGMAC_STAT("tx_64_byte_packets", tx64octets_gb),
+	FXGMAC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
+	FXGMAC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
+	FXGMAC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
+	FXGMAC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
+	FXGMAC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
+	FXGMAC_STAT("tx_underflow_errors", txunderflowerror),
+	FXGMAC_STAT("tx_pause_frames", txpauseframes),
+	FXGMAC_STAT("tx_single_collision", txsinglecollision_g),
+	FXGMAC_STAT("tx_multiple_collision", txmultiplecollision_g),
+	FXGMAC_STAT("tx_deferred_frames", txdeferredframes),
+	FXGMAC_STAT("tx_late_collision_frames", txlatecollisionframes),
+	FXGMAC_STAT("tx_excessive_collision_frames",
+		    txexcessivecollisionframes),
+	FXGMAC_STAT("tx_carrier_error_frames", txcarriererrorframes),
+	FXGMAC_STAT("tx_excessive_deferral_error", txexcessivedeferralerror),
+	FXGMAC_STAT("tx_oversize_frames_good", txoversize_g),
Please look at the rmon group.
+static void fxgmac_ethtool_get_drvinfo(struct net_device *netdev,
+				       struct ethtool_drvinfo *drvinfo)
+{
+	struct fxgmac_pdata *pdata = netdev_priv(netdev);
+	u32 ver = pdata->hw_feat.version;
+	u32 sver, devid, userver;
+
+	strscpy(drvinfo->version, pdata->drv_ver, sizeof(drvinfo->version));
Please leave this blank, so the core fills it with the git hash of the
kernel.
+
+	/* S|SVER: MAC Version
+	 * D|DEVID: Indicates the Device family
+	 * U|USERVER: User-defined Version
+	 */
+	sver = FXGMAC_GET_BITS(ver, MAC_VR_SVER_POS, MAC_VR_SVER_LEN);
+	devid = FXGMAC_GET_BITS(ver, MAC_VR_DEVID_POS, MAC_VR_DEVID_LEN);
+	userver = FXGMAC_GET_BITS(ver, MAC_VR_USERVER_POS, MAC_VR_USERVER_LEN);
+
+	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+		 "S.D.U: %x.%x.%x", sver, devid, userver);
You might want to consider devlink, which gives you more flexibility
in reporting versions.
+static void fxgmac_ethtool_set_msglevel(struct net_device *netdev, u32 msglevel)
+{
+	struct fxgmac_pdata *pdata = netdev_priv(netdev);
+
+	yt_dbg(pdata, "set msglvl from %08x to %08x\n", pdata->msg_enable,
+	       msglevel);
+	pdata->msg_enable = msglevel;
This is an example of a yt_dbg() which seems pointless now that you
have debugged it. Maybe you did have a bug in the first version of
this one line function, but it looks reasonably bug free now, so i
don't see the need for the print.
+static void fxgmac_get_regs(struct net_device *netdev,
+			    struct ethtool_regs *regs, void *p)
+{
+	struct fxgmac_pdata *pdata = netdev_priv(netdev);
+	u32 *regs_buff = p;
+
+	memset(p, 0, FXGMAC_PHY_REG_CNT * sizeof(u32));
+	for (u32 i = MII_BMCR; i < FXGMAC_PHY_REG_CNT; i++)
+		regs_buff[i] = phy_read(pdata->phydev, i);
A MAC driver should not be touching the PHY. There are other
standardised ways of dumping PHY registers, which don't involve the
MAC driver.
+static void fxgmac_get_pauseparam(struct net_device *dev,
+				  struct ethtool_pauseparam *data)
+{
+	struct fxgmac_pdata *yt = netdev_priv(dev);
Please be consistent with your naming. The function above calls this
pdata. I don't particularly like pdata, because that often means
platform_data, which you don't have. priv is more common.
+	bool tx_pause, rx_pause;
+
+	phy_get_pause(yt->phydev, &tx_pause, &rx_pause);
+
+	data->autoneg = yt->phydev->autoneg;
This is wrong. You can be doing autoneg in general,
i.e. phydev->autoneg, but not using autoneg for pause. You should
remember the value set in set_pauseparam().
+	data->tx_pause = tx_pause ? 1 : 0;
+	data->rx_pause = rx_pause ? 1 : 0;
Why the ? 1: 0 ?
+
+	yt_dbg(yt, "%s, rx=%d, tx=%d\n", __func__, data->rx_pause,
+	       data->tx_pause);
+}
+
+static int fxgmac_set_pauseparam(struct net_device *dev,
+				 struct ethtool_pauseparam *data)
+{
+	struct fxgmac_pdata *yt = netdev_priv(dev);
+
+	if (dev->mtu > ETH_DATA_LEN)
+		return -EOPNOTSUPP;
A comment about why jumbo packets breaks pause would be good. I also
assume your set_mtu code disables pause when jumbo is enabled?
get_pauseparam should also make it clear pause is disabled.
+	phy_set_asym_pause(yt->phydev, data->rx_pause, data->tx_pause);
You are ignoring ethtool_pauseparam autoneg.
+static void fxgmac_ethtool_get_strings(struct net_device *netdev, u32 stringset,
+				       u8 *data)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (u32 i = 0; i < FXGMAC_STATS_COUNT; i++) {
+			memcpy(data, fxgmac_gstring_stats[i].stat_string,
+			       strlen(fxgmac_gstring_stats[i].stat_string));
+			data += ETH_GSTRING_LEN;
+		}
+		break;
+	default:
+		WARN_ON(1);
You need to be careful with WARN_ON() particularly if it can be
triggered from user space. Maybe build cause a WARN to result in a
reboot.
+static int fxgmac_ethtool_reset(struct net_device *netdev, u32 *flag)
+{
+	struct fxgmac_pdata *pdata = netdev_priv(netdev);
+	int ret = 0;
+	u32 val;
+
+	val = *flag & (ETH_RESET_ALL | ETH_RESET_PHY);
+	if (!val) {
+		yt_err(pdata, "Operation not support.\n");
+		return -EOPNOTSUPP;
+	}
+
+	switch (*flag) {
+	case ETH_RESET_ALL:
+		fxgmac_restart(pdata);
+		*flag = 0;
+		break;
+	case ETH_RESET_PHY:
+		/* Power off and on the phy in order to properly
+		 * configure the MAC timing
+		 */
+		ret = phy_modify(pdata->phydev, MII_BMCR, BMCR_PDOWN,
+				 BMCR_PDOWN);
+		if (ret < 0)
+			return ret;
+		fsleep(9000);
+
+		ret = phy_modify(pdata->phydev, MII_BMCR, BMCR_PDOWN, 0);
+		if (ret < 0)
+			return ret;
+		*flag = 0;
This is a bad idea, since depending on the PHY, you have thrown away
all the configuration, and the PHY is now probably dead until you
admin down/admin up the interface. In general a MAC driver should
never directly touch the PHY, it should just use the API phylib
exposes.

    Andrew

---
pw-bot: cr
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help