net/sfc/base: provide APIs to configure and reset vPort
authorGautam Dawar <gdawar@solarflare.com>
Mon, 10 Jun 2019 07:38:42 +0000 (08:38 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 20 Jun 2019 21:42:04 +0000 (23:42 +0200)
Implement functions to set vPort VLAN and MAC address and reset the vPort.

Signed-off-by: Gautam Dawar <gdawar@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
drivers/net/sfc/base/ef10_evb.c
drivers/net/sfc/base/ef10_impl.h
drivers/net/sfc/base/ef10_nic.c
drivers/net/sfc/base/efx.h
drivers/net/sfc/base/efx_evb.c
drivers/net/sfc/base/efx_impl.h

index aaa97f6..6b6d7cc 100644 (file)
@@ -325,6 +325,74 @@ efx_mcdi_port_assign(
 
        return (0);
 
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn                           efx_rc_t
+efx_mcdi_vport_reconfigure(
+       __in                                    efx_nic_t *enp,
+       __in                                    efx_vport_id_t vport_id,
+       __in_opt                                uint16_t *vidp,
+       __in_bcount_opt(EFX_MAC_ADDR_LEN)       uint8_t *addrp,
+       __out_opt                               boolean_t *fn_resetp)
+{
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_RECONFIGURE_IN_LEN,
+               MC_CMD_VPORT_RECONFIGURE_OUT_LEN);
+       efx_mcdi_req_t req;
+       efx_rc_t rc;
+       uint32_t reset_flag = 0;
+
+       req.emr_cmd = MC_CMD_VPORT_RECONFIGURE;
+       req.emr_in_buf = payload;
+       req.emr_in_length = MC_CMD_VPORT_RECONFIGURE_IN_LEN;
+       req.emr_out_buf = payload;
+       req.emr_out_length = MC_CMD_VPORT_RECONFIGURE_OUT_LEN;
+
+       MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_VPORT_ID, vport_id);
+
+       if (vidp != NULL) {
+               MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
+                       VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS, 1);
+               if (*vidp != EFX_FILTER_VID_UNSPEC) {
+                       MCDI_IN_SET_DWORD(req,
+                               VPORT_RECONFIGURE_IN_NUM_VLAN_TAGS, 1);
+                       MCDI_IN_POPULATE_DWORD_1(req,
+                               VPORT_RECONFIGURE_IN_VLAN_TAGS,
+                               VPORT_RECONFIGURE_IN_VLAN_TAG_0, *vidp);
+               }
+       }
+
+       if ((addrp != NULL) && (efx_is_zero_eth_addr(addrp) == B_FALSE)) {
+               MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
+                        VPORT_RECONFIGURE_IN_REPLACE_MACADDRS, 1);
+               MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_NUM_MACADDRS, 1);
+               EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
+                                       VPORT_RECONFIGURE_IN_MACADDRS), addrp);
+       }
+
+       efx_mcdi_execute(enp, &req);
+       if (req.emr_rc != 0) {
+               rc = req.emr_rc;
+               goto fail1;
+       }
+
+       if (req.emr_out_length_used < MC_CMD_VPORT_RECONFIGURE_OUT_LEN) {
+               rc = EMSGSIZE;
+               goto fail2;
+       }
+
+       reset_flag = MCDI_OUT_DWORD_FIELD(req, VPORT_RECONFIGURE_OUT_FLAGS,
+                                           VPORT_RECONFIGURE_OUT_RESET_DONE);
+
+       if (fn_resetp != NULL)
+               *fn_resetp = (reset_flag != 0);
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
 fail1:
        EFSYS_PROBE1(fail1, efx_rc_t, rc);
        return (rc);
@@ -453,5 +521,20 @@ ef10_evb_vport_assign(
        return (efx_mcdi_port_assign(enp, vport_id, vf_index));
 }
 
+       __checkReturn                           efx_rc_t
+ef10_evb_vport_reconfigure(
+       __in                                    efx_nic_t *enp,
+       __in                                    efx_vswitch_id_t vswitch_id,
+       __in                                    efx_vport_id_t vport_id,
+       __in_opt                                uint16_t *vidp,
+       __in_bcount_opt(EFX_MAC_ADDR_LEN)       uint8_t *addrp,
+       __out_opt                               boolean_t *fn_resetp)
+{
+       _NOTE(ARGUNUSED(vswitch_id))
+
+       return (efx_mcdi_vport_reconfigure(enp, vport_id, vidp,
+                       addrp, fn_resetp));
+}
+
 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
 #endif /* EFSYS_OPT_EVB */
index e9ce31a..20f2a5c 100644 (file)
@@ -1342,6 +1342,15 @@ ef10_evb_vport_assign(
        __in            efx_vport_id_t vport_id,
        __in            uint32_t vf_index);
 
+extern __checkReturn                           efx_rc_t
+ef10_evb_vport_reconfigure(
+       __in                                    efx_nic_t *enp,
+       __in                                    efx_vswitch_id_t vswitch_id,
+       __in                                    efx_vport_id_t vport_id,
+       __in_opt                                uint16_t *vidp,
+       __in_bcount_opt(EFX_MAC_ADDR_LEN)       uint8_t *addrp,
+       __out_opt                               boolean_t *fn_resetp);
+
 #endif  /* EFSYS_OPT_EVB */
 
 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
index a647daa..b25ce19 100644 (file)
@@ -1108,6 +1108,12 @@ ef10_get_datapath_caps(
        else
                encp->enc_datapath_cap_evb = B_FALSE;
 
+       /* Check if the firmware supports vport reconfiguration */
+       if (CAP_FLAGS1(req, VPORT_RECONFIGURE))
+               encp->enc_vport_reconfigure_supported = B_TRUE;
+       else
+               encp->enc_vport_reconfigure_supported = B_FALSE;
+
        /* Check if the firmware supports VLAN insertion */
        if (CAP_FLAGS1(req, TX_VLAN_INSERTION))
                encp->enc_hw_tx_insert_vlan_enabled = B_TRUE;
index e43302a..0e6e842 100644 (file)
@@ -1370,6 +1370,8 @@ typedef struct efx_nic_cfg_s {
        uint32_t                enc_hw_pf_count;
        /* Datapath firmware vadapter/vport/vswitch support */
        boolean_t               enc_datapath_cap_evb;
+       /* Datapath firmware vport reconfigure support */
+       boolean_t               enc_vport_reconfigure_supported;
        boolean_t               enc_rx_disable_scatter_supported;
        boolean_t               enc_allow_set_mac_with_installed_filters;
        boolean_t               enc_enhanced_set_mac_supported;
@@ -3420,6 +3422,28 @@ efx_evb_vswitch_destroy(
        __in                            efx_nic_t *enp,
        __in                            efx_vswitch_t *evp);
 
+extern __checkReturn                   efx_rc_t
+efx_evb_vport_mac_set(
+       __in                            efx_nic_t *enp,
+       __in                            efx_vswitch_t *evp,
+       __in                            efx_vport_id_t vport_id,
+       __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp);
+
+extern __checkReturn   efx_rc_t
+efx_evb_vport_vlan_set(
+       __in            efx_nic_t *enp,
+       __in            efx_vswitch_t *evp,
+       __in            efx_vport_id_t vport_id,
+       __in            uint16_t vid);
+
+extern __checkReturn                   efx_rc_t
+efx_evb_vport_reset(
+       __in                            efx_nic_t *enp,
+       __in                            efx_vswitch_t *evp,
+       __in                            efx_vport_id_t vport_id,
+       __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp,
+       __in                            uint16_t vid,
+       __out                           boolean_t *is_fn_resetp);
 #endif /* EFSYS_OPT_EVB */
 
 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
index 27b466f..d48e1d7 100644 (file)
@@ -23,6 +23,7 @@ static const efx_evb_ops_t    __efx_evb_dummy_ops = {
        NULL,           /* eeo_vadaptor_alloc */
        NULL,           /* eeo_vadaptor_free */
        NULL,           /* eeo_vport_assign */
+       NULL,           /* eeo_vport_reconfigure */
 };
 #endif /* EFSYS_OPT_SIENA */
 
@@ -39,6 +40,7 @@ static const efx_evb_ops_t    __efx_evb_ef10_ops = {
        ef10_evb_vadaptor_alloc,        /* eeo_vadaptor_alloc */
        ef10_evb_vadaptor_free,         /* eeo_vadaptor_free */
        ef10_evb_vport_assign,          /* eeo_vport_assign */
+       ef10_evb_vport_reconfigure,     /* eeo_vport_reconfigure */
 };
 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
 
@@ -348,7 +350,114 @@ fail1:
        return (rc);
 }
 
+       __checkReturn                   efx_rc_t
+efx_evb_vport_mac_set(
+       __in                            efx_nic_t *enp,
+       __in                            efx_vswitch_t *evp,
+       __in                            efx_vport_id_t vport_id,
+       __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp)
+{
+       const efx_evb_ops_t *eeop = enp->en_eeop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_EVB);
+
+       if (eeop->eeo_vport_reconfigure == NULL) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
+
+       if (addrp == NULL) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       rc = eeop->eeo_vport_reconfigure(enp, evp->ev_vswitch_id, vport_id,
+               NULL, addrp, NULL);
+       if (rc != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_evb_vport_vlan_set(
+       __in            efx_nic_t *enp,
+       __in            efx_vswitch_t *evp,
+       __in            efx_vport_id_t vport_id,
+       __in            uint16_t vid)
+{
+       const efx_evb_ops_t *eeop = enp->en_eeop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_EVB);
+
+       if (eeop->eeo_vport_reconfigure == NULL) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
 
+       rc = eeop->eeo_vport_reconfigure(enp, evp->ev_vswitch_id, vport_id,
+               &vid, NULL, NULL);
+       if (rc != 0)
+               goto fail2;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn                   efx_rc_t
+efx_evb_vport_reset(
+       __in                            efx_nic_t *enp,
+       __in                            efx_vswitch_t *evp,
+       __in                            efx_vport_id_t vport_id,
+       __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp,
+       __in                            uint16_t vid,
+       __out                           boolean_t *is_fn_resetp)
+{
+       const efx_evb_ops_t *eeop = enp->en_eeop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_EVB);
+
+       if (eeop->eeo_vport_reconfigure == NULL) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
+
+       if (is_fn_resetp == NULL) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       rc = eeop->eeo_vport_reconfigure(enp, evp->ev_vswitch_id, vport_id,
+               &vid, addrp, is_fn_resetp);
+       if (rc != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
        __checkReturn   efx_rc_t
 efx_evb_vswitch_destroy(
        __in            efx_nic_t *enp,
index 6c72166..fd31a6d 100644 (file)
@@ -684,6 +684,10 @@ typedef struct efx_evb_ops_s {
                                                efx_vport_id_t);
        efx_rc_t        (*eeo_vport_assign)(efx_nic_t *, efx_vswitch_id_t,
                                                efx_vport_id_t, uint32_t);
+       efx_rc_t        (*eeo_vport_reconfigure)(efx_nic_t *, efx_vswitch_id_t,
+                                                       efx_vport_id_t,
+                                                       uint16_t *, uint8_t *,
+                                                       boolean_t *);
 } efx_evb_ops_t;
 
 extern __checkReturn   boolean_t