Blame SOURCES/0057-support-for-new-ethtool-capabilities.patch

121cca
From 1a39de2d0af780c06b55f5a96d5f696da1a6fda3 Mon Sep 17 00:00:00 2001
121cca
From: Lyonel Vincent <lyonel@ezix.org>
121cca
Date: Tue, 12 Oct 2021 23:33:08 +0200
121cca
Subject: [PATCH 57/65] support for new ethtool capabilities
121cca
121cca
merge Github PR#73
121cca
---
121cca
 src/core/network.cc | 299 +++++++++++++++++++++++++++++---------------
121cca
 1 file changed, 195 insertions(+), 104 deletions(-)
121cca
121cca
diff --git a/src/core/network.cc b/src/core/network.cc
121cca
index 5aab06d..613c1af 100644
121cca
--- a/src/core/network.cc
121cca
+++ b/src/core/network.cc
121cca
@@ -53,6 +53,7 @@ typedef unsigned long long u64;
121cca
 typedef uint32_t u32;
121cca
 typedef uint16_t u16;
121cca
 typedef uint8_t u8;
121cca
+typedef int8_t s8;
121cca
 
121cca
 struct ethtool_cmd
121cca
 {
121cca
@@ -70,6 +71,28 @@ struct ethtool_cmd
121cca
   u32 reserved[4];
121cca
 };
121cca
 
121cca
+#define MAX_LINK_MODE_MASK_SIZE 64
121cca
+struct ethtool_link_settings
121cca
+{
121cca
+  u32 cmd;
121cca
+  u32 speed;                                      /* The forced speed, 10Mb, 100Mb, gigabit */
121cca
+  u8 duplex;                                      /* Duplex, half or full */
121cca
+  u8 port;                                        /* Which connector port */
121cca
+  u8 phy_address;
121cca
+  u8 autoneg;                                     /* Enable or disable autonegotiation */
121cca
+  u8 mdio_support;
121cca
+  u8 eth_tp_mdix;
121cca
+  u8 eth_tp_mdix_ctrl;
121cca
+  s8 link_mode_masks_nwords;
121cca
+  u8 transceiver;                                 /* Which tranceiver to use */
121cca
+  u8 master_slave_cfg;
121cca
+  u8 master_slave_state;
121cca
+  u8 reserved1[1];
121cca
+  u32 reserved[7];
121cca
+  u32 link_mode_masks[3 * MAX_LINK_MODE_MASK_SIZE]; /* Link mode mask fields for modes:
121cca
+                                                       supported, advertised, peer advertised. */
121cca
+};
121cca
+
121cca
 #ifndef IFNAMSIZ
121cca
 #define IFNAMSIZ 32
121cca
 #endif
121cca
@@ -108,6 +131,7 @@ struct ethtool_value
121cca
 #define ETHTOOL_GSET            0x00000001        /* Get settings. */
121cca
 #define ETHTOOL_GDRVINFO        0x00000003        /* Get driver info. */
121cca
 #define ETHTOOL_GLINK           0x0000000a        /* Get link status (ethtool_value) */
121cca
+#define ETHTOOL_GLINKSETTINGS   0x0000004c        /* Get link mode settings. */
121cca
 
121cca
 /* Indicates what features are supported by the interface. */
121cca
 #define SUPPORTED_10baseT_Half          (1 << 0)
121cca
@@ -124,10 +148,17 @@ struct ethtool_value
121cca
 #define SUPPORTED_BNC                   (1 << 11)
121cca
 #define SUPPORTED_10000baseT_Full       (1 << 12)
121cca
 
121cca
-/* The forced speed, 10Mb, 100Mb, gigabit, 10GbE. */
121cca
+/* Indicates what features are supported by the interface,
121cca
+ * in the second word of the extended bitmap. */
121cca
+#define SUPPORTED2_2500baseT_Full       (1 << 15)
121cca
+#define SUPPORTED2_5000baseT_Full       (1 << 16)
121cca
+
121cca
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5GbE, 5GbE, 10GbE. */
121cca
 #define SPEED_10                10
121cca
 #define SPEED_100               100
121cca
 #define SPEED_1000              1000
121cca
+#define SPEED_2500              2500
121cca
+#define SPEED_5000              5000
121cca
 #define SPEED_10000             10000
121cca
 
121cca
 /* Duplex, half or full. */
121cca
@@ -308,6 +339,168 @@ static bool isVirtual(const string & MAC)
121cca
 }
121cca
 
121cca
 
121cca
+static void updateCapabilities(hwNode & interface, u32 supported, u32 supported2, u32 speed, u8 duplex, u8 port, u8 autoneg)
121cca
+{
121cca
+  if(supported & SUPPORTED_TP)
121cca
+    interface.addCapability("tp", _("twisted pair"));
121cca
+  if(supported & SUPPORTED_AUI)
121cca
+    interface.addCapability("aui", _("AUI"));
121cca
+  if(supported & SUPPORTED_BNC)
121cca
+    interface.addCapability("bnc", _("BNC"));
121cca
+  if(supported & SUPPORTED_MII)
121cca
+    interface.addCapability("mii", _("Media Independant Interface"));
121cca
+  if(supported & SUPPORTED_FIBRE)
121cca
+    interface.addCapability("fibre",_( "optical fibre"));
121cca
+  if(supported & SUPPORTED_10baseT_Half)
121cca
+  {
121cca
+    interface.addCapability("10bt", _("10Mbit/s"));
121cca
+    interface.setCapacity(10000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_10baseT_Full)
121cca
+  {
121cca
+    interface.addCapability("10bt-fd", _("10Mbit/s (full duplex)"));
121cca
+    interface.setCapacity(10000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_100baseT_Half)
121cca
+  {
121cca
+    interface.addCapability("100bt", _("100Mbit/s"));
121cca
+    interface.setCapacity(100000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_100baseT_Full)
121cca
+  {
121cca
+    interface.addCapability("100bt-fd", _("100Mbit/s (full duplex)"));
121cca
+    interface.setCapacity(100000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_1000baseT_Half)
121cca
+  {
121cca
+    interface.addCapability("1000bt", "1Gbit/s");
121cca
+    interface.setCapacity(1000000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_1000baseT_Full)
121cca
+  {
121cca
+    interface.addCapability("1000bt-fd", _("1Gbit/s (full duplex)"));
121cca
+    interface.setCapacity(1000000000ULL);
121cca
+  }
121cca
+  if(supported2 & SUPPORTED2_2500baseT_Full)
121cca
+  {
121cca
+    interface.addCapability("2500bt-fd", _("2.5Gbit/s (full duplex)"));
121cca
+    interface.setCapacity(2500000000ULL);
121cca
+  }
121cca
+  if(supported2 & SUPPORTED2_5000baseT_Full)
121cca
+  {
121cca
+    interface.addCapability("5000bt-fd", _("5Gbit/s (full duplex)"));
121cca
+    interface.setCapacity(5000000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_10000baseT_Full)
121cca
+  {
121cca
+    interface.addCapability("10000bt-fd", _("10Gbit/s (full duplex)"));
121cca
+    interface.setCapacity(10000000000ULL);
121cca
+  }
121cca
+  if(supported & SUPPORTED_Autoneg)
121cca
+    interface.addCapability("autonegotiation", _("Auto-negotiation"));
121cca
+
121cca
+  switch(speed)
121cca
+  {
121cca
+    case SPEED_10:
121cca
+      interface.setConfig("speed", "10Mbit/s");
121cca
+      interface.setSize(10000000ULL);
121cca
+      break;
121cca
+    case SPEED_100:
121cca
+      interface.setConfig("speed", "100Mbit/s");
121cca
+      interface.setSize(100000000ULL);
121cca
+      break;
121cca
+    case SPEED_1000:
121cca
+      interface.setConfig("speed", "1Gbit/s");
121cca
+      interface.setSize(1000000000ULL);
121cca
+      break;
121cca
+    case SPEED_2500:
121cca
+      interface.setConfig("speed", "2.5Gbit/s");
121cca
+      interface.setSize(2500000000ULL);
121cca
+      break;
121cca
+    case SPEED_5000:
121cca
+      interface.setConfig("speed", "5Gbit/s");
121cca
+      interface.setSize(5000000000ULL);
121cca
+      break;
121cca
+    case SPEED_10000:
121cca
+      interface.setConfig("speed", "10Gbit/s");
121cca
+      interface.setSize(10000000000ULL);
121cca
+      break;
121cca
+  }
121cca
+  switch(duplex)
121cca
+  {
121cca
+    case DUPLEX_HALF:
121cca
+      interface.setConfig("duplex", "half");
121cca
+      break;
121cca
+    case DUPLEX_FULL:
121cca
+      interface.setConfig("duplex", "full");
121cca
+      break;
121cca
+  }
121cca
+  switch(port)
121cca
+  {
121cca
+    case PORT_TP:
121cca
+      interface.setConfig("port", "twisted pair");
121cca
+      break;
121cca
+    case PORT_AUI:
121cca
+      interface.setConfig("port", "AUI");
121cca
+      break;
121cca
+    case PORT_BNC:
121cca
+      interface.setConfig("port", "BNC");
121cca
+      break;
121cca
+    case PORT_MII:
121cca
+      interface.setConfig("port", "MII");
121cca
+      break;
121cca
+    case PORT_FIBRE:
121cca
+      interface.setConfig("port", "fibre");
121cca
+      break;
121cca
+  }
121cca
+  interface.setConfig("autonegotiation", (autoneg == AUTONEG_DISABLE) ?  "off" : "on");
121cca
+}
121cca
+
121cca
+
121cca
+static void scan_modes(hwNode & interface, int fd)
121cca
+{
121cca
+  struct ifreq ifr;
121cca
+  struct ethtool_cmd ecmd;
121cca
+  struct ethtool_link_settings elink;
121cca
+  s8 mask_size;
121cca
+
121cca
+  elink.cmd = ETHTOOL_GLINKSETTINGS;
121cca
+  elink.link_mode_masks_nwords = 0;
121cca
+  memset(&ifr, 0, sizeof(ifr));
121cca
+  strcpy(ifr.ifr_name, interface.getLogicalName().c_str());
121cca
+  ifr.ifr_data = (caddr_t) &elink;
121cca
+  // Probe link mode mask count.
121cca
+  if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
121cca
+  {
121cca
+    mask_size = -elink.link_mode_masks_nwords;
121cca
+    if (mask_size > 1 && mask_size <= MAX_LINK_MODE_MASK_SIZE)
121cca
+    {
121cca
+      elink.cmd = ETHTOOL_GLINKSETTINGS;
121cca
+      elink.link_mode_masks_nwords = mask_size;
121cca
+      memset(&ifr, 0, sizeof(ifr));
121cca
+      strcpy(ifr.ifr_name, interface.getLogicalName().c_str());
121cca
+      ifr.ifr_data = (caddr_t) &elink;
121cca
+      // Read link mode settings.
121cca
+      if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
121cca
+      {
121cca
+        updateCapabilities(interface, elink.link_mode_masks[0], elink.link_mode_masks[1],
121cca
+          elink.speed, elink.duplex, elink.port, elink.autoneg);
121cca
+        return;
121cca
+      }
121cca
+    }
121cca
+  }
121cca
+
121cca
+  ecmd.cmd = ETHTOOL_GSET;
121cca
+  memset(&ifr, 0, sizeof(ifr));
121cca
+  strcpy(ifr.ifr_name, interface.getLogicalName().c_str());
121cca
+  ifr.ifr_data = (caddr_t) &ecm;;
121cca
+  if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
121cca
+  {
121cca
+    updateCapabilities(interface, ecmd.supported, 0, ecmd.speed, ecmd.duplex, ecmd.port, ecmd.autoneg);
121cca
+  }
121cca
+}
121cca
+
121cca
+
121cca
 bool scan_network(hwNode & n)
121cca
 {
121cca
   vector < string > interfaces;
121cca
@@ -322,7 +515,6 @@ bool scan_network(hwNode & n)
121cca
   {
121cca
     struct ifreq ifr;
121cca
     struct ethtool_drvinfo drvinfo;
121cca
-    struct ethtool_cmd ecmd;
121cca
     struct ethtool_value edata;
121cca
 
121cca
     for (unsigned int i = 0; i < interfaces.size(); i++)
121cca
@@ -417,108 +609,7 @@ bool scan_network(hwNode & n)
121cca
         interface.setConfig("link", edata.data ? "yes":"no");
121cca
       }
121cca
 
121cca
-      ecmd.cmd = ETHTOOL_GSET;
121cca
-      memset(&ifr, 0, sizeof(ifr));
121cca
-      strcpy(ifr.ifr_name, interfaces[i].c_str());
121cca
-      ifr.ifr_data = (caddr_t) &ecm;;
121cca
-      if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
121cca
-      {
121cca
-        if(ecmd.supported & SUPPORTED_TP)
121cca
-          interface.addCapability("tp", _("twisted pair"));
121cca
-        if(ecmd.supported & SUPPORTED_AUI)
121cca
-          interface.addCapability("aui", _("AUI"));
121cca
-        if(ecmd.supported & SUPPORTED_BNC)
121cca
-          interface.addCapability("bnc", _("BNC"));
121cca
-        if(ecmd.supported & SUPPORTED_MII)
121cca
-          interface.addCapability("mii", _("Media Independant Interface"));
121cca
-        if(ecmd.supported & SUPPORTED_FIBRE)
121cca
-          interface.addCapability("fibre",_( "optical fibre"));
121cca
-        if(ecmd.supported & SUPPORTED_10baseT_Half)
121cca
-        {
121cca
-          interface.addCapability("10bt", _("10Mbit/s"));
121cca
-          interface.setCapacity(10000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_10baseT_Full)
121cca
-        {
121cca
-          interface.addCapability("10bt-fd", _("10Mbit/s (full duplex)"));
121cca
-          interface.setCapacity(10000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_100baseT_Half)
121cca
-        {
121cca
-          interface.addCapability("100bt", _("100Mbit/s"));
121cca
-          interface.setCapacity(100000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_100baseT_Full)
121cca
-        {
121cca
-          interface.addCapability("100bt-fd", _("100Mbit/s (full duplex)"));
121cca
-          interface.setCapacity(100000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_1000baseT_Half)
121cca
-        {
121cca
-          interface.addCapability("1000bt", "1Gbit/s");
121cca
-          interface.setCapacity(1000000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_1000baseT_Full)
121cca
-        {
121cca
-          interface.addCapability("1000bt-fd", _("1Gbit/s (full duplex)"));
121cca
-          interface.setCapacity(1000000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_10000baseT_Full)
121cca
-        {
121cca
-          interface.addCapability("10000bt-fd", _("10Gbit/s (full duplex)"));
121cca
-          interface.setCapacity(10000000000ULL);
121cca
-        }
121cca
-        if(ecmd.supported & SUPPORTED_Autoneg)
121cca
-          interface.addCapability("autonegotiation", _("Auto-negotiation"));
121cca
-
121cca
-        switch(ecmd.speed)
121cca
-        {
121cca
-          case SPEED_10:
121cca
-            interface.setConfig("speed", "10Mbit/s");
121cca
-            interface.setSize(10000000ULL);
121cca
-            break;
121cca
-          case SPEED_100:
121cca
-            interface.setConfig("speed", "100Mbit/s");
121cca
-            interface.setSize(100000000ULL);
121cca
-            break;
121cca
-          case SPEED_1000:
121cca
-            interface.setConfig("speed", "1Gbit/s");
121cca
-            interface.setSize(1000000000ULL);
121cca
-            break;
121cca
-          case SPEED_10000:
121cca
-            interface.setConfig("speed", "10Gbit/s");
121cca
-            interface.setSize(10000000000ULL);
121cca
-            break;
121cca
-        }
121cca
-        switch(ecmd.duplex)
121cca
-        {
121cca
-          case DUPLEX_HALF:
121cca
-            interface.setConfig("duplex", "half");
121cca
-            break;
121cca
-          case DUPLEX_FULL:
121cca
-            interface.setConfig("duplex", "full");
121cca
-            break;
121cca
-        }
121cca
-        switch(ecmd.port)
121cca
-        {
121cca
-          case PORT_TP:
121cca
-            interface.setConfig("port", "twisted pair");
121cca
-            break;
121cca
-          case PORT_AUI:
121cca
-            interface.setConfig("port", "AUI");
121cca
-            break;
121cca
-          case PORT_BNC:
121cca
-            interface.setConfig("port", "BNC");
121cca
-            break;
121cca
-          case PORT_MII:
121cca
-            interface.setConfig("port", "MII");
121cca
-            break;
121cca
-          case PORT_FIBRE:
121cca
-            interface.setConfig("port", "fibre");
121cca
-            break;
121cca
-        }
121cca
-        interface.setConfig("autonegotiation", (ecmd.autoneg == AUTONEG_DISABLE) ?  "off" : "on");
121cca
-      }
121cca
+      scan_modes(interface, fd);
121cca
 
121cca
       drvinfo.cmd = ETHTOOL_GDRVINFO;
121cca
       memset(&ifr, 0, sizeof(ifr));
121cca
-- 
121cca
2.33.1
121cca