]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/spdk/dpdk/drivers/net/sfc/base/efx_mcdi.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / sfc / base / efx_mcdi.c
index adc2eb8e8deb6bc2b5c496222bac673f4f2cd208..8cd651f52973dbcabc4a6fb57b0b90decf7b2ff8 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- * Copyright (c) 2008-2018 Solarflare Communications Inc.
- * All rights reserved.
+ * Copyright(c) 2019-2020 Xilinx, Inc.
+ * Copyright(c) 2008-2019 Solarflare Communications Inc.
  */
 
 #include "efx.h"
@@ -360,7 +360,11 @@ efx_mcdi_read_response_header(
                rc = EIO;
                goto fail1;
        }
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+       if (((cmd != emrp->emr_cmd) && (emrp->emr_cmd != MC_CMD_PROXY_CMD)) ||
+#else
        if ((cmd != emrp->emr_cmd) ||
+#endif
            (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) {
                /* Response is for a different request */
                rc = EIO;
@@ -442,6 +446,11 @@ efx_mcdi_finish_response(
        efx_dword_t hdr[2];
        unsigned int hdr_len;
        size_t bytes;
+       unsigned int resp_off;
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+       unsigned int resp_cmd;
+       boolean_t proxied_cmd_resp = B_FALSE;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
 
        if (emrp->emr_out_buf == NULL)
                return;
@@ -456,14 +465,35 @@ efx_mcdi_finish_response(
                 */
                efx_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
                hdr_len += sizeof (hdr[1]);
+               resp_off = hdr_len;
 
                emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1],
-                                           MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+                                               MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+               /*
+                * A proxy MCDI command is executed by PF on behalf of
+                * one of its VFs. The command to be proxied follows
+                * immediately afterward in the host buffer.
+                * PROXY_CMD inner call complete response should be copied to
+                * output buffer so that it can be returned to the requesting
+                * function in MC_CMD_PROXY_COMPLETE payload.
+                */
+               resp_cmd =
+                       EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
+               proxied_cmd_resp = ((emrp->emr_cmd == MC_CMD_PROXY_CMD) &&
+                                       (resp_cmd != MC_CMD_PROXY_CMD));
+               if (proxied_cmd_resp) {
+                       resp_off = 0;
+                       emrp->emr_out_length_used += hdr_len;
+               }
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
+       } else {
+               resp_off = hdr_len;
        }
 
        /* Copy payload out into caller supplied buffer */
        bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
-       efx_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes);
+       efx_mcdi_read_response(enp, emrp->emr_out_buf, resp_off, bytes);
 
 #if EFSYS_OPT_MCDI_LOGGING
        if (emtp->emt_logger != NULL) {
@@ -845,6 +875,18 @@ efx_mcdi_ev_proxy_response(
 }
 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
+                       void
+efx_mcdi_ev_proxy_request(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index)
+{
+       const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+
+       if (emtp->emt_ev_proxy_request != NULL)
+               emtp->emt_ev_proxy_request(emtp->emt_context, index);
+}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
                        void
 efx_mcdi_ev_death(
        __in            efx_nic_t *enp,
@@ -1256,13 +1298,17 @@ efx_mcdi_drv_attach(
        __in            boolean_t attach)
 {
        efx_mcdi_req_t req;
-       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRV_ATTACH_IN_LEN,
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRV_ATTACH_IN_V2_LEN,
                MC_CMD_DRV_ATTACH_EXT_OUT_LEN);
        efx_rc_t rc;
 
        req.emr_cmd = MC_CMD_DRV_ATTACH;
        req.emr_in_buf = payload;
-       req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
+       if (enp->en_drv_version[0] == '\0') {
+               req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
+       } else {
+               req.emr_in_length = MC_CMD_DRV_ATTACH_IN_V2_LEN;
+       }
        req.emr_out_buf = payload;
        req.emr_out_length = MC_CMD_DRV_ATTACH_EXT_OUT_LEN;
 
@@ -1283,6 +1329,14 @@ efx_mcdi_drv_attach(
        MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
        MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_FIRMWARE_ID, enp->efv);
 
+       if (req.emr_in_length >= MC_CMD_DRV_ATTACH_IN_V2_LEN) {
+               EFX_STATIC_ASSERT(sizeof (enp->en_drv_version) ==
+                   MC_CMD_DRV_ATTACH_IN_V2_DRIVER_VERSION_LEN);
+               memcpy(MCDI_IN2(req, char, DRV_ATTACH_IN_V2_DRIVER_VERSION),
+                   enp->en_drv_version,
+                   MC_CMD_DRV_ATTACH_IN_V2_DRIVER_VERSION_LEN);
+       }
+
        efx_mcdi_execute(enp, &req);
 
        if (req.emr_rc != 0) {
@@ -1780,17 +1834,10 @@ fail1:
 
 #if EFSYS_OPT_MAC_STATS
 
-typedef enum efx_stats_action_e {
-       EFX_STATS_CLEAR,
-       EFX_STATS_UPLOAD,
-       EFX_STATS_ENABLE_NOEVENTS,
-       EFX_STATS_ENABLE_EVENTS,
-       EFX_STATS_DISABLE,
-} efx_stats_action_t;
-
-static __checkReturn   efx_rc_t
+       __checkReturn   efx_rc_t
 efx_mcdi_mac_stats(
        __in            efx_nic_t *enp,
+       __in            uint32_t vport_id,
        __in_opt        efsys_mem_t *esmp,
        __in            efx_stats_action_t action,
        __in            uint16_t period_ms)
@@ -1856,7 +1903,7 @@ efx_mcdi_mac_stats(
         *       vadapter has already been deleted.
         */
        MCDI_IN_SET_DWORD(req, MAC_STATS_IN_PORT_ID,
-           (disable ? EVB_PORT_ID_NULL : enp->en_vport_id));
+               (disable ? EVB_PORT_ID_NULL : vport_id));
 
        efx_mcdi_execute(enp, &req);
 
@@ -1889,7 +1936,8 @@ efx_mcdi_mac_stats_clear(
 {
        efx_rc_t rc;
 
-       if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR, 0)) != 0)
+       if ((rc = efx_mcdi_mac_stats(enp, enp->en_vport_id, NULL,
+                       EFX_STATS_CLEAR, 0)) != 0)
                goto fail1;
 
        return (0);
@@ -1912,7 +1960,8 @@ efx_mcdi_mac_stats_upload(
         * avoid having to pull the statistics buffer into the cache to
         * maintain cumulative statistics.
         */
-       if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD, 0)) != 0)
+       if ((rc = efx_mcdi_mac_stats(enp, enp->en_vport_id, esmp,
+                       EFX_STATS_UPLOAD, 0)) != 0)
                goto fail1;
 
        return (0);
@@ -1940,13 +1989,14 @@ efx_mcdi_mac_stats_periodic(
         * Medford uses a fixed 1sec period before v6.2.1.1033 firmware.
         */
        if (period_ms == 0)
-               rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE, 0);
+               rc = efx_mcdi_mac_stats(enp, enp->en_vport_id, NULL,
+                       EFX_STATS_DISABLE, 0);
        else if (events)
-               rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS,
-                   period_ms);
+               rc = efx_mcdi_mac_stats(enp, enp->en_vport_id, esmp,
+                       EFX_STATS_ENABLE_EVENTS, period_ms);
        else
-               rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS,
-                   period_ms);
+               rc = efx_mcdi_mac_stats(enp, enp->en_vport_id, esmp,
+                       EFX_STATS_ENABLE_NOEVENTS, period_ms);
 
        if (rc != 0)
                goto fail1;