]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rtase: Implement ethtool function
authorJustin Lai <justinlai0215@realtek.com>
Wed, 4 Sep 2024 03:21:11 +0000 (11:21 +0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 6 Sep 2024 05:02:38 +0000 (22:02 -0700)
Implement the ethtool function to support users to obtain network card
information, including obtaining various device settings, Report whether
physical link is up, Report pause parameters, Set pause parameters,
Return extended statistics about the device.

Signed-off-by: Justin Lai <justinlai0215@realtek.com>
Link: https://patch.msgid.link/20240904032114.247117-11-justinlai0215@realtek.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/realtek/rtase/rtase_main.c

index 7a31bef0576a4611554d58084177b642f52fd501..7882f2c0e1a4a510121257ac21c21dffa9fab22e 100644 (file)
@@ -1710,9 +1710,83 @@ static void rtase_get_mac_address(struct net_device *dev)
        rtase_rar_set(tp, dev->dev_addr);
 }
 
+static int rtase_get_settings(struct net_device *dev,
+                             struct ethtool_link_ksettings *cmd)
+{
+       u32 supported = SUPPORTED_MII | SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+
+       ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
+                                               supported);
+       cmd->base.speed = SPEED_5000;
+       cmd->base.duplex = DUPLEX_FULL;
+       cmd->base.port = PORT_MII;
+       cmd->base.autoneg = AUTONEG_DISABLE;
+
+       return 0;
+}
+
+static void rtase_get_pauseparam(struct net_device *dev,
+                                struct ethtool_pauseparam *pause)
+{
+       const struct rtase_private *tp = netdev_priv(dev);
+       u16 value = rtase_r16(tp, RTASE_CPLUS_CMD);
+
+       pause->autoneg = AUTONEG_DISABLE;
+       pause->tx_pause = !!(value & RTASE_FORCE_TXFLOW_EN);
+       pause->rx_pause = !!(value & RTASE_FORCE_RXFLOW_EN);
+}
+
+static int rtase_set_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *pause)
+{
+       const struct rtase_private *tp = netdev_priv(dev);
+       u16 value = rtase_r16(tp, RTASE_CPLUS_CMD);
+
+       if (pause->autoneg)
+               return -EOPNOTSUPP;
+
+       value &= ~(RTASE_FORCE_TXFLOW_EN | RTASE_FORCE_RXFLOW_EN);
+
+       if (pause->tx_pause)
+               value |= RTASE_FORCE_TXFLOW_EN;
+
+       if (pause->rx_pause)
+               value |= RTASE_FORCE_RXFLOW_EN;
+
+       rtase_w16(tp, RTASE_CPLUS_CMD, value);
+       return 0;
+}
+
+static void rtase_get_eth_mac_stats(struct net_device *dev,
+                                   struct ethtool_eth_mac_stats *stats)
+{
+       struct rtase_private *tp = netdev_priv(dev);
+       const struct rtase_counters *counters;
+
+       counters = tp->tally_vaddr;
+
+       rtase_dump_tally_counter(tp);
+
+       stats->FramesTransmittedOK = le64_to_cpu(counters->tx_packets);
+       stats->FramesReceivedOK = le64_to_cpu(counters->rx_packets);
+       stats->FramesLostDueToIntMACXmitError =
+               le64_to_cpu(counters->tx_errors);
+       stats->BroadcastFramesReceivedOK = le64_to_cpu(counters->rx_broadcast);
+}
+
+static const struct ethtool_ops rtase_ethtool_ops = {
+       .get_link = ethtool_op_get_link,
+       .get_link_ksettings = rtase_get_settings,
+       .get_pauseparam = rtase_get_pauseparam,
+       .set_pauseparam = rtase_set_pauseparam,
+       .get_eth_mac_stats = rtase_get_eth_mac_stats,
+       .get_ts_info = ethtool_op_get_ts_info,
+};
+
 static void rtase_init_netdev_ops(struct net_device *dev)
 {
        dev->netdev_ops = &rtase_netdev_ops;
+       dev->ethtool_ops = &rtase_ethtool_ops;
 }
 
 static void rtase_reset_interrupt(struct pci_dev *pdev,