net/sfc/base: move EVQ descs number check to generic place
[dpdk.git] / drivers / net / sfc / base / ef10_ev.c
index a05a35a..4f71199 100644 (file)
@@ -73,11 +73,10 @@ efx_mcdi_set_evq_tmr(
        __in            uint32_t timer_ns)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_SET_EVQ_TMR_IN_LEN,
-                           MC_CMD_SET_EVQ_TMR_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_EVQ_TMR_IN_LEN,
+               MC_CMD_SET_EVQ_TMR_OUT_LEN);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_SET_EVQ_TMR;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_SET_EVQ_TMR_IN_LEN;
@@ -123,9 +122,9 @@ efx_mcdi_init_evq(
        __in            boolean_t low_latency)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[
-           MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
-               MC_CMD_INIT_EVQ_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload,
+               MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EF10_EVQ_MAXNEVS)),
+               MC_CMD_INIT_EVQ_OUT_LEN);
        efx_qword_t *dma_addr;
        uint64_t addr;
        int npages;
@@ -140,7 +139,6 @@ efx_mcdi_init_evq(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_INIT_EVQ;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
@@ -260,9 +258,9 @@ efx_mcdi_init_evq_v2(
        __in            uint32_t flags)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[
-               MAX(MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
-                   MC_CMD_INIT_EVQ_V2_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload,
+               MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_EVQ_NBUFS(EF10_EVQ_MAXNEVS)),
+               MC_CMD_INIT_EVQ_V2_OUT_LEN);
        boolean_t interrupting;
        unsigned int evq_type;
        efx_qword_t *dma_addr;
@@ -277,7 +275,6 @@ efx_mcdi_init_evq_v2(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_INIT_EVQ;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_INIT_EVQ_V2_IN_LEN(npages);
@@ -384,11 +381,10 @@ efx_mcdi_fini_evq(
        __in            uint32_t instance)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
-                           MC_CMD_FINI_EVQ_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_EVQ_IN_LEN,
+               MC_CMD_FINI_EVQ_OUT_LEN);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_FINI_EVQ;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
@@ -450,23 +446,15 @@ ef10_ev_qcreate(
        efx_rc_t rc;
 
        _NOTE(ARGUNUSED(id))    /* buftbl id managed by MC */
-       EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
-       EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
-
-       if (!ISP2(ndescs) ||
-           (ndescs < EFX_EVQ_MINNEVS) || (ndescs > EFX_EVQ_MAXNEVS)) {
-               rc = EINVAL;
-               goto fail1;
-       }
 
        if (index >= encp->enc_evq_limit) {
                rc = EINVAL;
-               goto fail2;
+               goto fail1;
        }
 
        if (us > encp->enc_evq_timer_max_us) {
                rc = EINVAL;
-               goto fail3;
+               goto fail2;
        }
 
        /* Set up the handler table */
@@ -506,7 +494,7 @@ ef10_ev_qcreate(
                rc = efx_mcdi_init_evq_v2(enp, index, esmp, ndescs, irq, us,
                    flags);
                if (rc != 0)
-                       goto fail4;
+                       goto fail3;
        } else {
                /*
                 * On Huntington we need to specify the settings to use.
@@ -523,13 +511,11 @@ ef10_ev_qcreate(
                rc = efx_mcdi_init_evq(enp, index, esmp, ndescs, irq, us, flags,
                    low_latency);
                if (rc != 0)
-                       goto fail5;
+                       goto fail4;
        }
 
        return (0);
 
-fail5:
-       EFSYS_PROBE(fail5);
 fail4:
        EFSYS_PROBE(fail4);
 fail3:
@@ -567,9 +553,9 @@ ef10_ev_qprime(
        rptr = count & eep->ee_mask;
 
        if (enp->en_nic_cfg.enc_bug35388_workaround) {
-               EFX_STATIC_ASSERT(EFX_EVQ_MINNEVS >
+               EFX_STATIC_ASSERT(EF10_EVQ_MINNEVS >
                    (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
-               EFX_STATIC_ASSERT(EFX_EVQ_MAXNEVS <
+               EFX_STATIC_ASSERT(EF10_EVQ_MAXNEVS <
                    (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
 
                EFX_POPULATE_DWORD_2(dword,
@@ -577,7 +563,7 @@ ef10_ev_qprime(
                    EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
                    ERF_DD_EVQ_IND_RPTR,
                    (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
-               EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
+               EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
                    &dword, B_FALSE);
 
                EFX_POPULATE_DWORD_2(dword,
@@ -585,11 +571,11 @@ ef10_ev_qprime(
                    EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
                    ERF_DD_EVQ_IND_RPTR,
                    rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
-               EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
+               EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
                    &dword, B_FALSE);
        } else {
                EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
-               EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
+               EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
                    &dword, B_FALSE);
        }
 
@@ -603,8 +589,8 @@ efx_mcdi_driver_event(
        __in            efx_qword_t data)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
-                           MC_CMD_DRIVER_EVENT_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRIVER_EVENT_IN_LEN,
+               MC_CMD_DRIVER_EVENT_OUT_LEN);
        efx_rc_t rc;
 
        req.emr_cmd = MC_CMD_DRIVER_EVENT;
@@ -702,13 +688,19 @@ ef10_ev_qmoderate(
                            EFE_DD_EVQ_IND_TIMER_FLAGS,
                            ERF_DD_EVQ_IND_TIMER_MODE, mode,
                            ERF_DD_EVQ_IND_TIMER_VAL, ticks);
-                       EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
+                       EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT,
                            eep->ee_index, &dword, 0);
                } else {
-                       EFX_POPULATE_DWORD_2(dword,
+                       /*
+                        * NOTE: The TMR_REL field introduced in Medford2 is
+                        * ignored on earlier EF10 controllers. See bug66418
+                        * comment 9 for details.
+                        */
+                       EFX_POPULATE_DWORD_3(dword,
                            ERF_DZ_TC_TIMER_MODE, mode,
-                           ERF_DZ_TC_TIMER_VAL, ticks);
-                       EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_TMR_REG,
+                           ERF_DZ_TC_TIMER_VAL, ticks,
+                           ERF_FZ_TC_TMR_REL_VAL, ticks);
+                       EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_TMR_REG,
                            eep->ee_index, &dword, 0);
                }
        }
@@ -743,7 +735,7 @@ ef10_ev_qstats_update(
 }
 #endif /* EFSYS_OPT_QSTATS */
 
-#if EFSYS_OPT_RX_PACKED_STREAM
+#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
 
 static __checkReturn   boolean_t
 ef10_ev_rx_packed_stream(
@@ -782,14 +774,25 @@ ef10_ev_rx_packed_stream(
 
        if (new_buffer) {
                flags |= EFX_PKT_PACKED_STREAM_NEW_BUFFER;
+#if EFSYS_OPT_RX_PACKED_STREAM
+               /*
+                * If both packed stream and equal stride super-buffer
+                * modes are compiled in, in theory credits should be
+                * be maintained for packed stream only, but right now
+                * these modes are not distinguished in the event queue
+                * Rx queue state and it is OK to increment the counter
+                * regardless (it might be event cheaper than branching
+                * since neighbour structure member are updated as well).
+                */
                eersp->eers_rx_packed_stream_credits++;
+#endif
                eersp->eers_rx_read_ptr++;
        }
        current_id = eersp->eers_rx_read_ptr & eersp->eers_rx_mask;
 
        /* Check for errors that invalidate checksum and L3/L4 fields */
-       if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
-               /* RX frame truncated (error flag is misnamed) */
+       if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TRUNC_ERR) != 0) {
+               /* RX frame truncated */
                EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
                flags |= EFX_DISCARD;
                goto deliver;
@@ -824,7 +827,7 @@ deliver:
        return (should_abort);
 }
 
-#endif /* EFSYS_OPT_RX_PACKED_STREAM */
+#endif /* EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER */
 
 static __checkReturn   boolean_t
 ef10_ev_rx(
@@ -850,15 +853,16 @@ ef10_ev_rx(
 
        EFX_EV_QSTAT_INCR(eep, EV_RX);
 
-       /* Discard events after RXQ/TXQ errors */
-       if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+       /* Discard events after RXQ/TXQ errors, or hardware not available */
+       if (enp->en_reset_flags &
+           (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
                return (B_FALSE);
 
        /* Basic packet information */
        label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
        eersp = &eep->ee_rxq_state[label];
 
-#if EFSYS_OPT_RX_PACKED_STREAM
+#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
        /*
         * Packed stream events are very different,
         * so handle them separately
@@ -868,12 +872,23 @@ ef10_ev_rx(
 #endif
 
        size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
+       cont = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT);
        next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
        eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
        mac_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
        l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
-       l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
-       cont = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT);
+
+       /*
+        * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is only
+        * 2 bits wide on Medford2. Check it is safe to use the Medford2 field
+        * and values for all EF10 controllers.
+        */
+       EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN == ESF_DE_RX_L4_CLASS_LBN);
+       EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
+       EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
+       EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN == ESE_DE_L4_CLASS_UNKNOWN);
+
+       l4_class = EFX_QWORD_FIELD(*eqp, ESF_FZ_RX_L4_CLASS);
 
        if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
                /* Drop this event */
@@ -915,8 +930,8 @@ ef10_ev_rx(
        last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
 
        /* Check for errors that invalidate checksum and L3/L4 fields */
-       if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
-               /* RX frame truncated (error flag is misnamed) */
+       if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TRUNC_ERR) != 0) {
+               /* RX frame truncated */
                EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
                flags |= EFX_DISCARD;
                goto deliver;
@@ -952,10 +967,22 @@ ef10_ev_rx(
                        flags |= EFX_CKSUM_IPV4;
                }
 
-               if (l4_class == ESE_DZ_L4_CLASS_TCP) {
+               /*
+                * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is
+                * only 2 bits wide on Medford2. Check it is safe to use the
+                * Medford2 field and values for all EF10 controllers.
+                */
+               EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN ==
+                   ESF_DE_RX_L4_CLASS_LBN);
+               EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
+               EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
+               EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN ==
+                   ESE_DE_L4_CLASS_UNKNOWN);
+
+               if (l4_class == ESE_FZ_L4_CLASS_TCP) {
                        EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
                        flags |= EFX_PKT_TCP;
-               } else if (l4_class == ESE_DZ_L4_CLASS_UDP) {
+               } else if (l4_class == ESE_FZ_L4_CLASS_UDP) {
                        EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
                        flags |= EFX_PKT_UDP;
                } else {
@@ -967,10 +994,22 @@ ef10_ev_rx(
        case ESE_DZ_L3_CLASS_IP6_FRAG:
                flags |= EFX_PKT_IPV6;
 
-               if (l4_class == ESE_DZ_L4_CLASS_TCP) {
+               /*
+                * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is
+                * only 2 bits wide on Medford2. Check it is safe to use the
+                * Medford2 field and values for all EF10 controllers.
+                */
+               EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN ==
+                   ESF_DE_RX_L4_CLASS_LBN);
+               EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
+               EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
+               EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN ==
+                   ESE_DE_L4_CLASS_UNKNOWN);
+
+               if (l4_class == ESE_FZ_L4_CLASS_TCP) {
                        EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
                        flags |= EFX_PKT_TCP;
-               } else if (l4_class == ESE_DZ_L4_CLASS_UDP) {
+               } else if (l4_class == ESE_FZ_L4_CLASS_UDP) {
                        EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
                        flags |= EFX_PKT_UDP;
                } else {
@@ -1016,8 +1055,9 @@ ef10_ev_tx(
 
        EFX_EV_QSTAT_INCR(eep, EV_TX);
 
-       /* Discard events after RXQ/TXQ errors */
-       if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+       /* Discard events after RXQ/TXQ errors, or hardware not available */
+       if (enp->en_reset_flags &
+           (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
                return (B_FALSE);
 
        if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
@@ -1323,8 +1363,9 @@ ef10_ev_rxlabel_init(
        __in            efx_rxq_type_t type)
 {
        efx_evq_rxq_state_t *eersp;
-#if EFSYS_OPT_RX_PACKED_STREAM
+#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
        boolean_t packed_stream = (type == EFX_RXQ_TYPE_PACKED_STREAM);
+       boolean_t es_super_buffer = (type == EFX_RXQ_TYPE_ES_SUPER_BUFFER);
 #endif
 
        _NOTE(ARGUNUSED(type))
@@ -1346,9 +1387,11 @@ ef10_ev_rxlabel_init(
        eersp->eers_rx_read_ptr = 0;
 #endif
        eersp->eers_rx_mask = erp->er_mask;
-#if EFSYS_OPT_RX_PACKED_STREAM
+#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
        eersp->eers_rx_stream_npackets = 0;
-       eersp->eers_rx_packed_stream = packed_stream;
+       eersp->eers_rx_packed_stream = packed_stream || es_super_buffer;
+#endif
+#if EFSYS_OPT_RX_PACKED_STREAM
        if (packed_stream) {
                eersp->eers_rx_packed_stream_credits = (eep->ee_mask + 1) /
                    EFX_DIV_ROUND_UP(EFX_RX_PACKED_STREAM_MEM_PER_CREDIT,
@@ -1382,9 +1425,11 @@ ef10_ev_rxlabel_fini(
 
        eersp->eers_rx_read_ptr = 0;
        eersp->eers_rx_mask = 0;
-#if EFSYS_OPT_RX_PACKED_STREAM
+#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
        eersp->eers_rx_stream_npackets = 0;
        eersp->eers_rx_packed_stream = B_FALSE;
+#endif
+#if EFSYS_OPT_RX_PACKED_STREAM
        eersp->eers_rx_packed_stream_credits = 0;
 #endif
 }