OSDN Git Service

net: atlantic: adding ethtool physical identification
authorNikita Danilov <ndanilov@marvell.com>
Thu, 7 Nov 2019 22:41:55 +0000 (22:41 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Nov 2019 03:54:43 +0000 (19:54 -0800)
`ethtool -p eth0` will blink leds helping identify
physical port.

Signed-off-by: Nikita Danilov <ndanilov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
drivers/net/ethernet/aquantia/atlantic/aq_hw.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c

index 5be2738..2f877fb 100644 (file)
@@ -153,6 +153,35 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
        }
 }
 
+static int aq_ethtool_set_phys_id(struct net_device *ndev,
+                                 enum ethtool_phys_id_state state)
+{
+       struct aq_nic_s *aq_nic = netdev_priv(ndev);
+       struct aq_hw_s *hw = aq_nic->aq_hw;
+       int ret = 0;
+
+       if (!aq_nic->aq_fw_ops->led_control)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&aq_nic->fwreq_mutex);
+
+       switch (state) {
+       case ETHTOOL_ID_ACTIVE:
+               ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
+                                AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
+               break;
+       case ETHTOOL_ID_INACTIVE:
+               ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
+               break;
+       default:
+               break;
+       }
+
+       mutex_unlock(&aq_nic->fwreq_mutex);
+
+       return ret;
+}
+
 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
 {
        int ret = 0;
@@ -627,6 +656,7 @@ const struct ethtool_ops aq_ethtool_ops = {
        .get_regs            = aq_ethtool_get_regs,
        .get_drvinfo         = aq_ethtool_get_drvinfo,
        .get_strings         = aq_ethtool_get_strings,
+       .set_phys_id         = aq_ethtool_set_phys_id,
        .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
        .get_wol             = aq_ethtool_get_wol,
        .set_wol             = aq_ethtool_set_wol,
index 5246cf4..c2725a5 100644 (file)
@@ -119,6 +119,9 @@ struct aq_stats_s {
 
 #define AQ_HW_MULTICAST_ADDRESS_MAX     32U
 
+#define AQ_HW_LED_BLINK    0x2U
+#define AQ_HW_LED_DEFAULT  0x0U
+
 struct aq_hw_s {
        atomic_t flags;
        u8 rbl_enabled:1;
@@ -304,6 +307,8 @@ struct aq_fw_ops {
 
        int (*set_flow_control)(struct aq_hw_s *self);
 
+       int (*led_control)(struct aq_hw_s *self, u32 mode);
+
        int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
                         u8 *mac);
 
index fd2c6be..fc82ede 100644 (file)
@@ -970,4 +970,5 @@ const struct aq_fw_ops aq_fw_1x_ops = {
        .set_flow_control = NULL,
        .send_fw_request = NULL,
        .enable_ptp = NULL,
+       .led_control = NULL,
 };
index 9b89622..4eab51b 100644 (file)
@@ -17,6 +17,7 @@
 #include "hw_atl_utils.h"
 #include "hw_atl_llh.h"
 
+#define HW_ATL_FW2X_MPI_LED_ADDR         0x31c
 #define HW_ATL_FW2X_MPI_RPC_ADDR         0x334
 
 #define HW_ATL_FW2X_MPI_MBOX_ADDR        0x360
@@ -51,6 +52,8 @@
 #define HAL_ATLANTIC_WOL_FILTERS_COUNT   8
 #define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL  0x0E
 
+#define HW_ATL_FW_VER_LED                0x03010026U
+
 struct __packed fw2x_msg_wol_pattern {
        u8 mask[16];
        u32 crc;
@@ -450,6 +453,16 @@ static void aq_fw3x_enable_ptp(struct aq_hw_s *self, int enable)
        aq_hw_write_reg(self, HW_ATL_FW3X_EXT_CONTROL_ADDR, ptp_opts);
 }
 
+static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode)
+{
+       if (self->fw_ver_actual < HW_ATL_FW_VER_LED)
+               return -EOPNOTSUPP;
+
+       aq_hw_write_reg(self, HW_ATL_FW2X_MPI_LED_ADDR, mode);
+
+       return 0;
+}
+
 static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed)
 {
        u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
@@ -557,4 +570,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
        .get_flow_control   = aq_fw2x_get_flow_control,
        .send_fw_request    = aq_fw2x_send_fw_request,
        .enable_ptp         = aq_fw3x_enable_ptp,
+       .led_control        = aq_fw2x_led_control,
 };