net/sfc/base: import PHY LEDs control
authorAndrew Rybchenko <arybchenko@solarflare.com>
Tue, 29 Nov 2016 16:18:49 +0000 (16:18 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:39:26 +0000 (19:39 +0100)
EFSYS_OPT_PHY_LED_CONTROL should be enabled to use it.

From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
drivers/net/sfc/base/ef10_phy.c
drivers/net/sfc/base/efx.h
drivers/net/sfc/base/efx_check.h
drivers/net/sfc/base/efx_impl.h
drivers/net/sfc/base/efx_mcdi.c
drivers/net/sfc/base/efx_phy.c
drivers/net/sfc/base/siena_phy.c

index b15b693..cc00250 100644 (file)
@@ -314,7 +314,26 @@ ef10_phy_reconfigure(
        req.emr_out_buf = payload;
        req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
 
+#if EFSYS_OPT_PHY_LED_CONTROL
+       switch (epp->ep_phy_led_mode) {
+       case EFX_PHY_LED_DEFAULT:
+               led_mode = MC_CMD_LED_DEFAULT;
+               break;
+       case EFX_PHY_LED_OFF:
+               led_mode = MC_CMD_LED_OFF;
+               break;
+       case EFX_PHY_LED_ON:
+               led_mode = MC_CMD_LED_ON;
+               break;
+       default:
+               EFSYS_ASSERT(0);
+               led_mode = MC_CMD_LED_DEFAULT;
+       }
+
+       MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode);
+#else
        MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
 
        efx_mcdi_execute(enp, &req);
 
index d2fe43e..794ba4b 100644 (file)
@@ -463,6 +463,23 @@ extern     __checkReturn   efx_rc_t
 efx_phy_verify(
        __in            efx_nic_t *enp);
 
+#if EFSYS_OPT_PHY_LED_CONTROL
+
+typedef enum efx_phy_led_mode_e {
+       EFX_PHY_LED_DEFAULT = 0,
+       EFX_PHY_LED_OFF,
+       EFX_PHY_LED_ON,
+       EFX_PHY_LED_FLASH,
+       EFX_PHY_LED_NMODES
+} efx_phy_led_mode_t;
+
+extern __checkReturn   efx_rc_t
+efx_phy_led_set(
+       __in    efx_nic_t *enp,
+       __in    efx_phy_led_mode_t mode);
+
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
 extern __checkReturn   efx_rc_t
 efx_port_init(
        __in            efx_nic_t *enp);
@@ -745,6 +762,9 @@ typedef struct efx_nic_cfg_s {
 #if EFSYS_OPT_PHY_FLAGS
        uint32_t                enc_phy_flags_mask;
 #endif /* EFSYS_OPT_PHY_FLAGS */
+#if EFSYS_OPT_PHY_LED_CONTROL
+       uint32_t                enc_led_mask;
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
 #if EFSYS_OPT_PHY_STATS
        uint64_t                enc_phy_stat_mask;
 #endif /* EFSYS_OPT_PHY_STATS */
index adda531..4e76dc1 100644 (file)
 # endif
 #endif /* EFSYS_OPT_PHY_FLAGS */
 
+#if EFSYS_OPT_PHY_LED_CONTROL
+/* Support for PHY LED control */
+# if !EFSYS_OPT_SIENA
+#  error "PHY_LED_CONTROL requires SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
 #ifdef EFSYS_OPT_PHY_NULL
 # error "PHY_NULL is obsolete and is not supported."
 #endif
index 2b81768..6077114 100644 (file)
@@ -244,6 +244,9 @@ typedef struct efx_port_s {
 #if EFSYS_OPT_PHY_FLAGS
        uint32_t                ep_phy_flags;
 #endif /* EFSYS_OPT_PHY_FLAGS */
+#if EFSYS_OPT_PHY_LED_CONTROL
+       efx_phy_led_mode_t      ep_phy_led_mode;
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
        efx_phy_media_type_t    ep_fixed_port_type;
        efx_phy_media_type_t    ep_module_type;
        uint32_t                ep_adv_cap_mask;
index c5422da..34ba960 100644 (file)
@@ -1409,6 +1409,11 @@ efx_mcdi_get_phy_cfg(
                MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
                MIN(sizeof (encp->enc_phy_revision) - 1,
                    MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
+#if EFSYS_OPT_PHY_LED_CONTROL
+       encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
+                           (1 << EFX_PHY_LED_OFF) |
+                           (1 << EFX_PHY_LED_ON));
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
 
        /* Get the media type of the fixed port, if recognised. */
        EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
index 20debd3..752cd52 100644 (file)
@@ -132,6 +132,51 @@ efx_phy_verify(
        return (epop->epo_verify(enp));
 }
 
+#if EFSYS_OPT_PHY_LED_CONTROL
+
+       __checkReturn   efx_rc_t
+efx_phy_led_set(
+       __in            efx_nic_t *enp,
+       __in            efx_phy_led_mode_t mode)
+{
+       efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
+       efx_port_t *epp = &(enp->en_port);
+       const efx_phy_ops_t *epop = epp->ep_epop;
+       uint32_t mask;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if (epp->ep_phy_led_mode == mode)
+               goto done;
+
+       mask = (1 << EFX_PHY_LED_DEFAULT);
+       mask |= encp->enc_led_mask;
+
+       if (!((1 << mode) & mask)) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
+
+       EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
+       epp->ep_phy_led_mode = mode;
+
+       if ((rc = epop->epo_reconfigure(enp)) != 0)
+               goto fail2;
+
+done:
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
                        void
 efx_phy_adv_cap_get(
        __in            efx_nic_t *enp,
index 73690f1..9aeef23 100644 (file)
@@ -298,7 +298,26 @@ siena_phy_reconfigure(
        req.emr_out_buf = payload;
        req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
 
+#if EFSYS_OPT_PHY_LED_CONTROL
+       switch (epp->ep_phy_led_mode) {
+       case EFX_PHY_LED_DEFAULT:
+               led_mode = MC_CMD_LED_DEFAULT;
+               break;
+       case EFX_PHY_LED_OFF:
+               led_mode = MC_CMD_LED_OFF;
+               break;
+       case EFX_PHY_LED_ON:
+               led_mode = MC_CMD_LED_ON;
+               break;
+       default:
+               EFSYS_ASSERT(0);
+               led_mode = MC_CMD_LED_DEFAULT;
+       }
+
+       MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode);
+#else
        MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
 
        efx_mcdi_execute(enp, &req);