New upstream version 17.11.5
[deb_dpdk.git] / drivers / net / sfc / base / ef10_rx.c
index b65faed..c5f48b6 100644 (file)
@@ -47,8 +47,8 @@ efx_mcdi_init_rxq(
        __in            uint32_t ps_bufsize)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_INIT_RXQ_EXT_IN_LEN,
-                           MC_CMD_INIT_RXQ_EXT_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_RXQ_EXT_IN_LEN,
+               MC_CMD_INIT_RXQ_EXT_OUT_LEN);
        int npages = EFX_RXQ_NBUFS(size);
        int i;
        efx_qword_t *dma_addr;
@@ -65,7 +65,6 @@ efx_mcdi_init_rxq(
        else
                dma_mode = MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_INIT_RXQ;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_INIT_RXQ_EXT_IN_LEN;
@@ -122,11 +121,10 @@ efx_mcdi_fini_rxq(
        __in            uint32_t instance)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_FINI_RXQ_IN_LEN,
-                           MC_CMD_FINI_RXQ_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_RXQ_IN_LEN,
+               MC_CMD_FINI_RXQ_OUT_LEN);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_FINI_RXQ;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
@@ -137,7 +135,7 @@ efx_mcdi_fini_rxq(
 
        efx_mcdi_execute_quiet(enp, &req);
 
-       if ((req.emr_rc != 0) && (req.emr_rc != MC_CMD_ERR_EALREADY)) {
+       if (req.emr_rc != 0) {
                rc = req.emr_rc;
                goto fail1;
        }
@@ -145,7 +143,12 @@ efx_mcdi_fini_rxq(
        return (0);
 
 fail1:
-       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       /*
+        * EALREADY is not an error, but indicates that the MC has rebooted and
+        * that the RXQ has already been destroyed.
+        */
+       if (rc != EALREADY)
+               EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
        return (rc);
 }
@@ -154,13 +157,13 @@ fail1:
 static __checkReturn   efx_rc_t
 efx_mcdi_rss_context_alloc(
        __in            efx_nic_t *enp,
-       __in            efx_rx_scale_support_t scale_support,
+       __in            efx_rx_scale_context_type_t type,
        __in            uint32_t num_queues,
        __out           uint32_t *rss_contextp)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
+               MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
        uint32_t rss_context;
        uint32_t context_type;
        efx_rc_t rc;
@@ -170,7 +173,7 @@ efx_mcdi_rss_context_alloc(
                goto fail1;
        }
 
-       switch (scale_support) {
+       switch (type) {
        case EFX_RX_SCALE_EXCLUSIVE:
                context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE;
                break;
@@ -182,7 +185,6 @@ efx_mcdi_rss_context_alloc(
                goto fail2;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
@@ -239,8 +241,8 @@ efx_mcdi_rss_context_free(
        __in            uint32_t rss_context)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
+               MC_CMD_RSS_CONTEXT_FREE_OUT_LEN);
        efx_rc_t rc;
 
        if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -248,7 +250,6 @@ efx_mcdi_rss_context_free(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;
@@ -283,8 +284,8 @@ efx_mcdi_rss_context_set_flags(
        __in            efx_rx_hash_type_t type)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
+               MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN);
        efx_rc_t rc;
 
        if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -292,7 +293,6 @@ efx_mcdi_rss_context_set_flags(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;
@@ -339,8 +339,8 @@ efx_mcdi_rss_context_set_key(
        __in            size_t n)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
+               MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN);
        efx_rc_t rc;
 
        if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -348,7 +348,6 @@ efx_mcdi_rss_context_set_key(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;
@@ -396,8 +395,8 @@ efx_mcdi_rss_context_set_table(
        __in            size_t n)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
+               MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN);
        uint8_t *req_table;
        int i, rc;
 
@@ -406,7 +405,6 @@ efx_mcdi_rss_context_set_table(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;
@@ -456,7 +454,7 @@ ef10_rx_init(
                 * Allocated an exclusive RSS context, which allows both the
                 * indirection table and key to be modified.
                 */
-               enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
+               enp->en_rss_context_type = EFX_RX_SCALE_EXCLUSIVE;
                enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
        } else {
                /*
@@ -464,7 +462,7 @@ ef10_rx_init(
                 * operation without support for RSS. The pseudo-header in
                 * received packets will not contain a Toeplitz hash value.
                 */
-               enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
+               enp->en_rss_context_type = EFX_RX_SCALE_UNAVAILABLE;
                enp->en_hash_support = EFX_RX_HASH_UNAVAILABLE;
        }
 
@@ -484,10 +482,53 @@ ef10_rx_scatter_enable(
 }
 #endif /* EFSYS_OPT_RX_SCATTER */
 
+#if EFSYS_OPT_RX_SCALE
+       __checkReturn   efx_rc_t
+ef10_rx_scale_context_alloc(
+       __in            efx_nic_t *enp,
+       __in            efx_rx_scale_context_type_t type,
+       __in            uint32_t num_queues,
+       __out           uint32_t *rss_contextp)
+{
+       efx_rc_t rc;
+
+       rc = efx_mcdi_rss_context_alloc(enp, type, num_queues, rss_contextp);
+       if (rc != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+       __checkReturn   efx_rc_t
+ef10_rx_scale_context_free(
+       __in            efx_nic_t *enp,
+       __in            uint32_t rss_context)
+{
+       efx_rc_t rc;
+
+       rc = efx_mcdi_rss_context_free(enp, rss_context);
+       if (rc != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
 #if EFSYS_OPT_RX_SCALE
        __checkReturn   efx_rc_t
 ef10_rx_scale_mode_set(
        __in            efx_nic_t *enp,
+       __in            uint32_t rss_context,
        __in            efx_rx_hash_alg_t alg,
        __in            efx_rx_hash_type_t type,
        __in            boolean_t insert)
@@ -502,13 +543,16 @@ ef10_rx_scale_mode_set(
                goto fail1;
        }
 
-       if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
-               rc = ENOTSUP;
-               goto fail2;
+       if (rss_context == EFX_RSS_CONTEXT_DEFAULT) {
+               if (enp->en_rss_context_type == EFX_RX_SCALE_UNAVAILABLE) {
+                       rc = ENOTSUP;
+                       goto fail2;
+               }
+               rss_context = enp->en_rss_context;
        }
 
        if ((rc = efx_mcdi_rss_context_set_flags(enp,
-                   enp->en_rss_context, type)) != 0)
+                   rss_context, type)) != 0)
                goto fail3;
 
        return (0);
@@ -528,18 +572,24 @@ fail1:
        __checkReturn   efx_rc_t
 ef10_rx_scale_key_set(
        __in            efx_nic_t *enp,
+       __in            uint32_t rss_context,
        __in_ecount(n)  uint8_t *key,
        __in            size_t n)
 {
        efx_rc_t rc;
 
-       if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
-               rc = ENOTSUP;
-               goto fail1;
+       EFX_STATIC_ASSERT(EFX_RSS_KEY_SIZE ==
+           MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
+
+       if (rss_context == EFX_RSS_CONTEXT_DEFAULT) {
+               if (enp->en_rss_context_type == EFX_RX_SCALE_UNAVAILABLE) {
+                       rc = ENOTSUP;
+                       goto fail1;
+               }
+               rss_context = enp->en_rss_context;
        }
 
-       if ((rc = efx_mcdi_rss_context_set_key(enp,
-           enp->en_rss_context, key, n)) != 0)
+       if ((rc = efx_mcdi_rss_context_set_key(enp, rss_context, key, n)) != 0)
                goto fail2;
 
        return (0);
@@ -557,18 +607,23 @@ fail1:
        __checkReturn   efx_rc_t
 ef10_rx_scale_tbl_set(
        __in            efx_nic_t *enp,
+       __in            uint32_t rss_context,
        __in_ecount(n)  unsigned int *table,
        __in            size_t n)
 {
        efx_rc_t rc;
 
-       if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
-               rc = ENOTSUP;
-               goto fail1;
+
+       if (rss_context == EFX_RSS_CONTEXT_DEFAULT) {
+               if (enp->en_rss_context_type == EFX_RX_SCALE_UNAVAILABLE) {
+                       rc = ENOTSUP;
+                       goto fail1;
+               }
+               rss_context = enp->en_rss_context;
        }
 
        if ((rc = efx_mcdi_rss_context_set_table(enp,
-           enp->en_rss_context, table, n)) != 0)
+                   rss_context, table, n)) != 0)
                goto fail2;
 
        return (0);
@@ -802,7 +857,14 @@ ef10_rx_qflush(
        return (0);
 
 fail1:
-       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       /*
+        * EALREADY is not an error, but indicates that the MC has rebooted and
+        * that the RXQ has already been destroyed. Callers need to know that
+        * the RXQ flush has completed to avoid waiting until timeout for a
+        * flush done event that will not be delivered.
+        */
+       if (rc != EALREADY)
+               EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
        return (rc);
 }
@@ -952,11 +1014,10 @@ ef10_rx_fini(
        __in    efx_nic_t *enp)
 {
 #if EFSYS_OPT_RX_SCALE
-       if (enp->en_rss_support != EFX_RX_SCALE_UNAVAILABLE) {
+       if (enp->en_rss_context_type != EFX_RX_SCALE_UNAVAILABLE)
                (void) efx_mcdi_rss_context_free(enp, enp->en_rss_context);
-       }
        enp->en_rss_context = 0;
-       enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
+       enp->en_rss_context_type = EFX_RX_SCALE_UNAVAILABLE;
 #else
        _NOTE(ARGUNUSED(enp))
 #endif /* EFSYS_OPT_RX_SCALE */