All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/37] net/sfc: update base driver
@ 2018-09-10  9:32 Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return Andrew Rybchenko
                   ` (37 more replies)
  0 siblings, 38 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:32 UTC (permalink / raw)
  To: dev

Update net/sfc base driver (aka libefx).

There are a number of checkpatches.sh warnings/errors
because of coding style difference.

Andrew Jackson (1):
  net/sfc/base: highlight that image layout header generated

Andrew Rybchenko (1):
  net/sfc/base: fix build failure because of no declaration

Andy Moreton (6):
  net/sfc/base: properly align on line continuation
  net/sfc/base: add space after sizeof
  net/sfc/base: add routine to check for hardware presence
  net/sfc/base: add API to inform libefx of hardware removal
  net/sfc/base: fix ID retrival in v3 licensing
  net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes

Gautam Dawar (1):
  net/sfc/base: fix out of bounds read when dereferencing sdup

Ivan Malov (6):
  net/sfc/base: fix name of the argument to store RSS flags
  net/sfc/base: fix a typo in unicast filter insertion comment
  net/sfc/base: use simpler code to check hash algorithm type
  net/sfc/base: check buffer size for hash flags
  net/sfc/base: simplify the code to parse RSS hash type
  net/sfc/base: improve handling of legacy RSS hash flags

Mark Spender (3):
  net/sfc/base: remove probes when a Tx queue is too full
  net/sfc/base: add information if TSO workaround is required
  net/sfc/base: prevent access to the NIC config before probe

Martin Harvey (10):
  net/sfc/base: fix PreFAST warnings because of unused return
  net/sfc/base: fix invalid order of memset arguments
  net/sfc/base: fix output buffer SAL annotation
  net/sfc/base: fix erroneous SAL annotation for input buffers
  net/sfc/base: move empty efsys definitions to EFX headers
  net/sfc/base: refactor monitors support
  net/sfc/base: add generated description of sensors
  net/sfc/base: check size of memory to read sensors data to
  net/sfc/base: add API to retrieve sensor limits
  net/sfc/base: avoid usage of too big arrays on stack

Paul Fox (1):
  net/sfc/base: add more definitions of partitions

Richard Houldsworth (4):
  net/sfc/base: add buffer editing functions to boot config
  net/sfc/base: add accessor for default port mode
  net/sfc/base: generalise EF10 NVRAM buffer interface
  net/sfc/base: modify phy caps to indicate FEC request

Vijay Srivastava (4):
  net/sfc/base: fix outer IPID field in TSO option descriptors
  net/sfc/base: add check for TUNNEL module in NIC reset API
  net/sfc/base: add support to get active FEC type
  net/sfc/base: add helper API to make Geneve filter spec

 drivers/net/sfc/base/ef10_ev.c                |  38 +-
 drivers/net/sfc/base/ef10_filter.c            |  64 +-
 drivers/net/sfc/base/ef10_image.c             |   5 +-
 drivers/net/sfc/base/ef10_impl.h              |  62 +-
 drivers/net/sfc/base/ef10_intr.c              |   5 +-
 drivers/net/sfc/base/ef10_mac.c               |  24 +-
 drivers/net/sfc/base/ef10_nic.c               | 155 ++--
 drivers/net/sfc/base/ef10_nvram.c             | 161 +++-
 drivers/net/sfc/base/ef10_phy.c               |  93 ++-
 drivers/net/sfc/base/ef10_rx.c                |  89 +--
 .../net/sfc/base/ef10_signed_image_layout.h   |   8 +
 drivers/net/sfc/base/ef10_tx.c                |  38 +-
 drivers/net/sfc/base/efx.h                    | 305 +++++--
 drivers/net/sfc/base/efx_annote.h             | 103 +++
 drivers/net/sfc/base/efx_bootcfg.c            | 641 +++++++++++++--
 drivers/net/sfc/base/efx_filter.c             |  90 ++-
 drivers/net/sfc/base/efx_impl.h               |  10 +-
 drivers/net/sfc/base/efx_lic.c                |  91 +--
 drivers/net/sfc/base/efx_mcdi.c               |  88 +--
 drivers/net/sfc/base/efx_mcdi.h               |  15 +
 drivers/net/sfc/base/efx_mon.c                | 745 ++++++++++++++++--
 drivers/net/sfc/base/efx_nic.c                |  54 +-
 drivers/net/sfc/base/efx_nvram.c              |  71 +-
 drivers/net/sfc/base/efx_phy.c                |  31 +
 drivers/net/sfc/base/efx_port.c               |   2 +-
 drivers/net/sfc/base/efx_rx.c                 | 225 +++---
 drivers/net/sfc/base/efx_tunnel.c             |   6 +-
 drivers/net/sfc/base/efx_tx.c                 |  19 +-
 drivers/net/sfc/base/hunt_nic.c               |   6 +-
 drivers/net/sfc/base/mc_driver_pcol_strs.h    | 102 +++
 drivers/net/sfc/base/mcdi_mon.c               | 381 +++++----
 drivers/net/sfc/base/mcdi_mon.h               |   5 +
 drivers/net/sfc/base/medford2_nic.c           |   5 +-
 drivers/net/sfc/base/medford_nic.c            |   5 +-
 drivers/net/sfc/base/siena_mac.c              |   9 +-
 drivers/net/sfc/base/siena_nic.c              |   5 +-
 drivers/net/sfc/base/siena_nvram.c            |   5 +-
 drivers/net/sfc/base/siena_phy.c              |  28 +-
 drivers/net/sfc/efsys.h                       |  38 -
 drivers/net/sfc/sfc_rx.c                      |   2 +-
 40 files changed, 2886 insertions(+), 943 deletions(-)
 create mode 100644 drivers/net/sfc/base/efx_annote.h
 create mode 100644 drivers/net/sfc/base/mc_driver_pcol_strs.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 02/37] net/sfc/base: fix invalid order of memset arguments Andrew Rybchenko
                   ` (36 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, stable

From: Martin Harvey <mharvey@solarflare.com>

Fixes: 19b64c6ac35f ("net/sfc/base: import libefx base")
Fixes: d96a34d165b1 ("net/sfc/base: import NVRAM support")
Fixes: e7cd430c864f ("net/sfc/base: import SFN7xxx family support")
Cc: stable@dpdk.org

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_filter.c | 47 ++++++++++++++++++++++++------
 drivers/net/sfc/base/ef10_mac.c    |  2 +-
 drivers/net/sfc/base/ef10_nic.c    |  4 +--
 drivers/net/sfc/base/ef10_nvram.c  |  4 +--
 drivers/net/sfc/base/ef10_tx.c     |  8 +++--
 drivers/net/sfc/base/efx_port.c    |  2 +-
 6 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_filter.c b/drivers/net/sfc/base/ef10_filter.c
index ae872853d..a4d97f99c 100644
--- a/drivers/net/sfc/base/ef10_filter.c
+++ b/drivers/net/sfc/base/ef10_filter.c
@@ -1144,12 +1144,15 @@ ef10_filter_insert_unicast(
 	efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
 	    filter_flags,
 	    eftp->eft_default_rxq);
-	efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
+	rc = efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
+	    addr);
+	if (rc != 0)
+		goto fail1;
 
 	rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
 	    &eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
 	if (rc != 0)
-		goto fail1;
+		goto fail2;
 
 	eftp->eft_unicst_filter_count++;
 	EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
@@ -1157,6 +1160,8 @@ ef10_filter_insert_unicast(
 
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 	return (rc);
@@ -1175,11 +1180,13 @@ ef10_filter_insert_all_unicast(
 	efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
 	    filter_flags,
 	    eftp->eft_default_rxq);
-	efx_filter_spec_set_uc_def(&spec);
+	rc = efx_filter_spec_set_uc_def(&spec);
+	if (rc != 0)
+		goto fail1;
 	rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
 	    &eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
 	if (rc != 0)
-		goto fail1;
+		goto fail2;
 
 	eftp->eft_unicst_filter_count++;
 	EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
@@ -1187,6 +1194,8 @@ ef10_filter_insert_all_unicast(
 
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 	return (rc);
@@ -1228,9 +1237,21 @@ ef10_filter_insert_multicast_list(
 		    filter_flags,
 		    eftp->eft_default_rxq);
 
-		efx_filter_spec_set_eth_local(&spec,
+		rc = efx_filter_spec_set_eth_local(&spec,
 		    EFX_FILTER_SPEC_VID_UNSPEC,
 		    &addrs[i * EFX_MAC_ADDR_LEN]);
+		if (rc != 0) {
+			if (rollback == B_TRUE) {
+				/* Only stop upon failure if told to rollback */
+				goto rollback;
+			} else {
+				/*
+				 * Don't try to add a filter with a corrupt
+				 * specification.
+				 */
+				continue;
+			}
+		}
 
 		rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
 					    &filter_index);
@@ -1253,8 +1274,12 @@ ef10_filter_insert_multicast_list(
 		    eftp->eft_default_rxq);
 
 		EFX_MAC_BROADCAST_ADDR_SET(addr);
-		efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
-		    addr);
+		rc = efx_filter_spec_set_eth_local(&spec,
+		    EFX_FILTER_SPEC_VID_UNSPEC, addr);
+		if ((rc != 0) && (rollback == B_TRUE)) {
+			/* Only stop upon failure if told to rollback */
+			goto rollback;
+		}
 
 		rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
 					    &filter_index);
@@ -1302,12 +1327,14 @@ ef10_filter_insert_all_multicast(
 	efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
 	    filter_flags,
 	    eftp->eft_default_rxq);
-	efx_filter_spec_set_mc_def(&spec);
+	rc = efx_filter_spec_set_mc_def(&spec);
+	if (rc != 0)
+		goto fail1;
 
 	rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
 	    &eftp->eft_mulcst_filter_indexes[0]);
 	if (rc != 0)
-		goto fail1;
+		goto fail2;
 
 	eftp->eft_mulcst_filter_count = 1;
 	eftp->eft_using_all_mulcst = B_TRUE;
@@ -1318,6 +1345,8 @@ ef10_filter_insert_all_multicast(
 
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
diff --git a/drivers/net/sfc/base/ef10_mac.c b/drivers/net/sfc/base/ef10_mac.c
index 1031e8369..c14010732 100644
--- a/drivers/net/sfc/base/ef10_mac.c
+++ b/drivers/net/sfc/base/ef10_mac.c
@@ -412,7 +412,7 @@ ef10_mac_filter_default_rxq_clear(
 
 	ef10_filter_default_rxq_clear(enp);
 
-	efx_filter_reconfigure(enp, epp->ep_mac_addr,
+	(void) efx_filter_reconfigure(enp, epp->ep_mac_addr,
 				    epp->ep_all_unicst, epp->ep_mulcst,
 				    epp->ep_all_mulcst, epp->ep_brdcst,
 				    epp->ep_mulcst_addr_list,
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index 7dbf843bf..d1985b3c5 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -806,7 +806,7 @@ ef10_nic_alloc_piobufs(
 	for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
 		handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
 
-		efx_mcdi_free_piobuf(enp, *handlep);
+		(void) efx_mcdi_free_piobuf(enp, *handlep);
 		*handlep = EFX_PIOBUF_HANDLE_INVALID;
 	}
 	enp->en_arch.ef10.ena_piobuf_count = 0;
@@ -823,7 +823,7 @@ ef10_nic_free_piobufs(
 	for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
 		handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
 
-		efx_mcdi_free_piobuf(enp, *handlep);
+		(void) efx_mcdi_free_piobuf(enp, *handlep);
 		*handlep = EFX_PIOBUF_HANDLE_INVALID;
 	}
 	enp->en_arch.ef10.ena_piobuf_count = 0;
diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 2883ec8f4..0d885ccdf 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -1808,7 +1808,7 @@ ef10_nvram_partn_write_segment_tlv(
 		goto fail7;
 
 	/* Unlock the partition */
-	ef10_nvram_partn_unlock(enp, partn, NULL);
+	(void) ef10_nvram_partn_unlock(enp, partn, NULL);
 
 	EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
 
@@ -1823,7 +1823,7 @@ ef10_nvram_partn_write_segment_tlv(
 fail4:
 	EFSYS_PROBE(fail4);
 
-	ef10_nvram_partn_unlock(enp, partn, NULL);
+	(void) ef10_nvram_partn_unlock(enp, partn, NULL);
 fail3:
 	EFSYS_PROBE(fail3);
 
diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c
index 7d27f7100..b92cadcbf 100644
--- a/drivers/net/sfc/base/ef10_tx.c
+++ b/drivers/net/sfc/base/ef10_tx.c
@@ -278,7 +278,7 @@ ef10_tx_qpio_enable(
 
 fail3:
 	EFSYS_PROBE(fail3);
-	ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+	(void) ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
 fail2:
 	EFSYS_PROBE(fail2);
 	etp->et_pio_size = 0;
@@ -296,10 +296,12 @@ ef10_tx_qpio_disable(
 
 	if (etp->et_pio_size != 0) {
 		/* Unlink the piobuf from this TXQ */
-		ef10_nic_pio_unlink(enp, etp->et_index);
+		if (ef10_nic_pio_unlink(enp, etp->et_index) != 0)
+			return;
 
 		/* Free the sub-allocated PIO block */
-		ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+		(void) ef10_nic_pio_free(enp, etp->et_pio_bufnum,
+		    etp->et_pio_blknum);
 		etp->et_pio_size = 0;
 		etp->et_pio_write_offset = 0;
 	}
diff --git a/drivers/net/sfc/base/efx_port.c b/drivers/net/sfc/base/efx_port.c
index 33a1a0843..5fff932be 100644
--- a/drivers/net/sfc/base/efx_port.c
+++ b/drivers/net/sfc/base/efx_port.c
@@ -37,7 +37,7 @@ efx_port_init(
 	epp->ep_emop->emo_reconfigure(enp);
 
 	/* Pick up current phy capababilities */
-	efx_port_poll(enp, NULL);
+	(void) efx_port_poll(enp, NULL);
 
 	/*
 	 * Turn on the PHY if available, otherwise reset it, and
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 02/37] net/sfc/base: fix invalid order of memset arguments
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 03/37] net/sfc/base: fix output buffer SAL annotation Andrew Rybchenko
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, stable

From: Martin Harvey <mharvey@solarflare.com>

Found by PreFAST.

Fixes: 3f2f0189dd44 ("net/sfc/base: add signed image layout support")
Cc: stable@dpdk.org

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_image.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/ef10_image.c b/drivers/net/sfc/base/ef10_image.c
index 6fb7e4764..0d8898762 100644
--- a/drivers/net/sfc/base/ef10_image.c
+++ b/drivers/net/sfc/base/ef10_image.c
@@ -704,7 +704,7 @@ efx_build_signed_image_write_buffer(
 	 * results in the layout used for the data chunks and chunk headers.
 	 */
 	/* END CSTYLED */
-	memset(bufferp, buffer_size, 0xFF);
+	memset(bufferp, 0xFF, buffer_size);
 
 	EFX_STATIC_ASSERT(sizeof (chunk_hdr) == SIGNED_IMAGE_CHUNK_HDR_LEN);
 	memset(&chunk_hdr, 0, SIGNED_IMAGE_CHUNK_HDR_LEN);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 03/37] net/sfc/base: fix output buffer SAL annotation
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 02/37] net/sfc/base: fix invalid order of memset arguments Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 04/37] net/sfc/base: highlight that image layout header generated Andrew Rybchenko
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, stable

From: Martin Harvey <mharvey@solarflare.com>

Found by PreFAST warnings.

Fixes: 3f2f0189dd44 ("net/sfc/base: add signed image layout support")
Cc: stable@dpdk.org

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_image.c | 3 ++-
 drivers/net/sfc/base/efx.h        | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_image.c b/drivers/net/sfc/base/ef10_image.c
index 0d8898762..c035e0df6 100644
--- a/drivers/net/sfc/base/ef10_image.c
+++ b/drivers/net/sfc/base/ef10_image.c
@@ -577,7 +577,8 @@ efx_check_reflash_image(
 
 	__checkReturn	efx_rc_t
 efx_build_signed_image_write_buffer(
-	__out		uint8_t			*bufferp,
+	__out_bcount(buffer_size)
+			uint8_t			*bufferp,
 	__in		uint32_t		buffer_size,
 	__in		efx_image_info_t	*infop,
 	__out		efx_image_header_t	**headerpp)
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 5108b9b1f..53cbc9858 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1689,7 +1689,8 @@ efx_check_reflash_image(
 
 extern	__checkReturn	efx_rc_t
 efx_build_signed_image_write_buffer(
-	__out		uint8_t			*bufferp,
+	__out_bcount(buffer_size)
+			uint8_t			*bufferp,
 	__in		uint32_t		buffer_size,
 	__in		efx_image_info_t	*infop,
 	__out		efx_image_header_t	**headerpp);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 04/37] net/sfc/base: highlight that image layout header generated
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (2 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 03/37] net/sfc/base: fix output buffer SAL annotation Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 05/37] net/sfc/base: fix erroneous SAL annotation for input buffers Andrew Rybchenko
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andrew Jackson

From: Andrew Jackson <ajackson@solarflare.com>

EF10 signed image layout header is generated from firmware sources.

Signed-off-by: Andrew Jackson <ajackson@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_signed_image_layout.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/sfc/base/ef10_signed_image_layout.h b/drivers/net/sfc/base/ef10_signed_image_layout.h
index a35d16012..c25ffe2f7 100644
--- a/drivers/net/sfc/base/ef10_signed_image_layout.h
+++ b/drivers/net/sfc/base/ef10_signed_image_layout.h
@@ -4,6 +4,14 @@
  * All rights reserved.
  */
 
+/*
+ * This is NOT the original source file. Do NOT edit it.
+ * To update the image layout headers, please edit the copy in
+ * the sfregistry repo and then, in that repo,
+ * "make layout_headers" or "make export" to
+ * regenerate and export all types of headers.
+ */
+
 /* These structures define the layouts for the signed firmware image binary
  * saved in NVRAM. The original image is in the Cryptographic message
  * syntax (CMS) format which contains the bootable firmware binary plus the
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 05/37] net/sfc/base: fix erroneous SAL annotation for input buffers
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (3 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 04/37] net/sfc/base: highlight that image layout header generated Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 06/37] net/sfc/base: properly align on line continuation Andrew Rybchenko
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, stable

From: Martin Harvey <mharvey@solarflare.com>

Fixes: d96a34d165b1 ("net/sfc/base: import NVRAM support")
Cc: stable@dpdk.org

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h  | 2 +-
 drivers/net/sfc/base/ef10_nvram.c | 2 +-
 drivers/net/sfc/base/efx_impl.h   | 2 +-
 drivers/net/sfc/base/efx_nvram.c  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 4751faf16..fb0d98875 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -453,7 +453,7 @@ ef10_nvram_partn_write(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in			unsigned int offset,
-	__out_bcount(size)	caddr_t data,
+	__in_bcount(size)	caddr_t data,
 	__in			size_t size);
 
 extern	__checkReturn		efx_rc_t
diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 0d885ccdf..46838dd75 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -2000,7 +2000,7 @@ ef10_nvram_partn_write(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in			unsigned int offset,
-	__out_bcount(size)	caddr_t data,
+	__in_bcount(size)	caddr_t data,
 	__in			size_t size)
 {
 	size_t chunk;
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 548834f90..637e31e0c 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -583,7 +583,7 @@ efx_mcdi_nvram_write(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in			uint32_t offset,
-	__out_bcount(size)	caddr_t data,
+	__in_bcount(size)	caddr_t data,
 	__in			size_t size);
 
 	__checkReturn		efx_rc_t
diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c
index be409c3af..f3107bbb5 100644
--- a/drivers/net/sfc/base/efx_nvram.c
+++ b/drivers/net/sfc/base/efx_nvram.c
@@ -865,7 +865,7 @@ efx_mcdi_nvram_write(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in			uint32_t offset,
-	__out_bcount(size)	caddr_t data,
+	__in_bcount(size)	caddr_t data,
 	__in			size_t size)
 {
 	efx_mcdi_req_t req;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 06/37] net/sfc/base: properly align on line continuation
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (4 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 05/37] net/sfc/base: fix erroneous SAL annotation for input buffers Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 07/37] net/sfc/base: add space after sizeof Andrew Rybchenko
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andy Moreton, stable

From: Andy Moreton <amoreton@solarflare.com>

Fixes: 19b64c6ac35f ("net/sfc/base: import libefx base")
Cc: stable@dpdk.org

Signed-off-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx_nic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index 6c162e035..6314ae2ff 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -559,7 +559,7 @@ efx_nic_reset(
 	 */
 	mod_flags = enp->en_mod_flags;
 	mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
-		    EFX_MOD_VPD | EFX_MOD_MON);
+	    EFX_MOD_VPD | EFX_MOD_MON);
 	EFSYS_ASSERT3U(mod_flags, ==, 0);
 	if (mod_flags != 0) {
 		rc = EINVAL;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 07/37] net/sfc/base: add space after sizeof
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (5 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 06/37] net/sfc/base: properly align on line continuation Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 08/37] net/sfc/base: fix build failure because of no declaration Andrew Rybchenko
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andy Moreton, stable

From: Andy Moreton <amoreton@solarflare.com>

Required by GLD cstyle.

Fixes: d4f4b8f9d260 ("net/sfc/base: make RxQ type data an union")
Cc: stable@dpdk.org

Signed-off-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx_rx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index 4fd73bab3..09933b41a 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -831,7 +831,7 @@ efx_rx_qcreate_packed_stream(
 {
 	efx_rxq_type_data_t type_data;
 
-	memset(&type_data, 0, sizeof(type_data));
+	memset(&type_data, 0, sizeof (type_data));
 
 	type_data.ertd_packed_stream.eps_buf_size = ps_buf_size;
 
@@ -867,7 +867,7 @@ efx_rx_qcreate_es_super_buffer(
 		goto fail1;
 	}
 
-	memset(&type_data, 0, sizeof(type_data));
+	memset(&type_data, 0, sizeof (type_data));
 
 	type_data.ertd_es_super_buffer.eessb_bufs_per_desc = n_bufs_per_desc;
 	type_data.ertd_es_super_buffer.eessb_max_dma_len = max_dma_len;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 08/37] net/sfc/base: fix build failure because of no declaration
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (6 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 07/37] net/sfc/base: add space after sizeof Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 09/37] net/sfc/base: add more definitions of partitions Andrew Rybchenko
                   ` (29 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: stable

Functions declared in mcdi_mon.h are implemented in mcdi_mon.c.
The build fails if compiler options require declaration before definition.

Fixes: dfb3b1ce15f6 ("net/sfc/base: import monitors access via MCDI")
Cc: stable@dpdk.org

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/mcdi_mon.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 940bd0265..8c0b6f0d9 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -6,6 +6,7 @@
 
 #include "efx.h"
 #include "efx_impl.h"
+#include "mcdi_mon.h"
 
 #if EFSYS_OPT_MON_MCDI
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 09/37] net/sfc/base: add more definitions of partitions
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (7 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 08/37] net/sfc/base: fix build failure because of no declaration Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 10/37] net/sfc/base: fix outer IPID field in TSO option descriptors Andrew Rybchenko
                   ` (28 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Paul Fox

From: Paul Fox <pfox@solarflare.com>

Add definitions of dynamic config and expansion ROM backup
partitions.

Signed-off-by: Paul Fox <pfox@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_nvram.c | 2 ++
 drivers/net/sfc/base/efx.h        | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 46838dd75..96ea5624a 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -2168,6 +2168,8 @@ static ef10_parttbl_entry_t medford2_parttbl[] = {
 	PARTN_MAP_ENTRY(LICENSE,		ALL,	LICENSE),
 	PARTN_MAP_ENTRY(EXPANSION_UEFI,		ALL,	UEFIROM),
 	PARTN_MAP_ENTRY(MUM_FIRMWARE,		ALL,	MUM_FIRMWARE),
+	PARTN_MAP_ENTRY(DYNCONFIG_DEFAULTS,	ALL,	DYNCONFIG_DEFAULTS),
+	PARTN_MAP_ENTRY(ROMCONFIG_DEFAULTS,	ALL,	ROMCONFIG_DEFAULTS),
 };
 
 static	__checkReturn		efx_rc_t
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 53cbc9858..baeffd934 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1483,6 +1483,8 @@ typedef enum efx_nvram_type_e {
 	EFX_NVRAM_LICENSE,
 	EFX_NVRAM_UEFIROM,
 	EFX_NVRAM_MUM_FIRMWARE,
+	EFX_NVRAM_DYNCONFIG_DEFAULTS,
+	EFX_NVRAM_ROMCONFIG_DEFAULTS,
 	EFX_NVRAM_NTYPES,
 } efx_nvram_type_t;
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 10/37] net/sfc/base: fix outer IPID field in TSO option descriptors
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (8 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 09/37] net/sfc/base: add more definitions of partitions Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 11/37] net/sfc/base: move empty efsys definitions to EFX headers Andrew Rybchenko
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Vijay Srivastava, stable

From: Vijay Srivastava <vijays@solarflare.com>

Fixes: 912e603706c5 ("net/sfc/base: add outer IP ID parameter to TSOv2 descriptor")
Cc: stable@dpdk.org

Signed-off-by: Vijay Srivastava <vijays@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_tx.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c
index b92cadcbf..e74d39540 100644
--- a/drivers/net/sfc/base/ef10_tx.c
+++ b/drivers/net/sfc/base/ef10_tx.c
@@ -639,22 +639,22 @@ ef10_tx_qdesc_tso2_create(
 
 	EFSYS_ASSERT(count >= EFX_TX_FATSOV2_OPT_NDESCS);
 
-	EFX_POPULATE_QWORD_6(edp[0].ed_eq,
+	EFX_POPULATE_QWORD_5(edp[0].ed_eq,
 			    ESF_DZ_TX_DESC_IS_OPT, 1,
 			    ESF_DZ_TX_OPTION_TYPE,
 			    ESE_DZ_TX_OPTION_DESC_TSO,
 			    ESF_DZ_TX_TSO_OPTION_TYPE,
 			    ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A,
 			    ESF_DZ_TX_TSO_IP_ID, ipv4_id,
-			    ESF_DZ_TX_TSO_OUTER_IPID, outer_ipv4_id,
 			    ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
-	EFX_POPULATE_QWORD_4(edp[1].ed_eq,
+	EFX_POPULATE_QWORD_5(edp[1].ed_eq,
 			    ESF_DZ_TX_DESC_IS_OPT, 1,
 			    ESF_DZ_TX_OPTION_TYPE,
 			    ESE_DZ_TX_OPTION_DESC_TSO,
 			    ESF_DZ_TX_TSO_OPTION_TYPE,
 			    ESE_DZ_TX_TSO_OPTION_DESC_FATSO2B,
-			    ESF_DZ_TX_TSO_TCP_MSS, tcp_mss);
+			    ESF_DZ_TX_TSO_TCP_MSS, tcp_mss,
+			    ESF_DZ_TX_TSO_OUTER_IPID, outer_ipv4_id);
 }
 
 	void
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 11/37] net/sfc/base: move empty efsys definitions to EFX headers
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (9 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 10/37] net/sfc/base: fix outer IPID field in TSO option descriptors Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 12/37] net/sfc/base: add check for TUNNEL module in NIC reset API Andrew Rybchenko
                   ` (26 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, Andrew Lee

From: Martin Harvey <mharvey@solarflare.com>

Move empty definitions for platform-specific annotations from efsys.h
to EFX headers.

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Lee <alee@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h        |   1 +
 drivers/net/sfc/base/efx_annote.h | 101 ++++++++++++++++++++++++++++++
 drivers/net/sfc/efsys.h           |  38 -----------
 3 files changed, 102 insertions(+), 38 deletions(-)
 create mode 100644 drivers/net/sfc/base/efx_annote.h

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index baeffd934..4c8983387 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -7,6 +7,7 @@
 #ifndef	_SYS_EFX_H
 #define	_SYS_EFX_H
 
+#include "efx_annote.h"
 #include "efsys.h"
 #include "efx_check.h"
 #include "efx_phy_ids.h"
diff --git a/drivers/net/sfc/base/efx_annote.h b/drivers/net/sfc/base/efx_annote.h
new file mode 100644
index 000000000..603260e22
--- /dev/null
+++ b/drivers/net/sfc/base/efx_annote.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2018 Solarflare Communications Inc.
+ * All rights reserved.
+ */
+
+#ifndef	_SYS_EFX_ANNOTE_H
+#define	_SYS_EFX_ANNOTE_H
+
+#if defined(_WIN32) || defined(_WIN64)
+#define	EFX_HAVE_WINDOWS_ANNOTATIONS 1
+#else
+#define	EFX_HAVE_WINDOWS_ANNOTATIONS 0
+#endif	/* defined(_WIN32) || defined(_WIN64) */
+
+#if defined(__sun)
+#define	EFX_HAVE_SOLARIS_ANNOTATIONS 1
+#else
+#define	EFX_HAVE_SOLARIS_ANNOTATIONS 0
+#endif	/* defined(__sun) */
+
+#if !EFX_HAVE_WINDOWS_ANNOTATIONS
+
+/* Ignore Windows SAL annotations on other platforms */
+#define	__in
+#define	__in_opt
+#define	__in_ecount(_n)
+#define	__in_ecount_opt(_n)
+#define	__in_bcount(_n)
+#define	__in_bcount_opt(_n)
+
+#define	__out
+#define	__out_opt
+#define	__out_ecount(_n)
+#define	__out_ecount_opt(_n)
+#define	__out_bcount(_n)
+#define	__out_bcount_opt(_n)
+#define	__out_bcount_part(_n, _l)
+#define	__out_bcount_part_opt(_n, _l)
+
+#define	__deref_out
+
+#define	__inout
+#define	__inout_opt
+#define	__inout_ecount(_n)
+#define	__inout_ecount_opt(_n)
+#define	__inout_bcount(_n)
+#define	__inout_bcount_opt(_n)
+#define	__inout_bcount_full_opt(_n)
+
+#define	__deref_out_bcount_opt(n)
+
+#define	__checkReturn
+#define	__success(_x)
+
+#define	__drv_when(_p, _c)
+
+#endif	/* !EFX_HAVE_WINDOWS_ANNOTATIONS */
+
+#if !EFX_HAVE_SOLARIS_ANNOTATIONS
+
+#if EFX_HAVE_WINDOWS_ANNOTATIONS
+
+/*
+ * Support some SunOS/Solaris style _NOTE() annotations
+ *
+ * At present with the facilities provided in the WDL and the SAL we can only
+ * easily act upon _NOTE(ARGUNUSED(arglist)) annotations.
+ *
+ * Intermediate macros to expand individual _NOTE annotation types into
+ * something the WDK or SAL can understand.  They shouldn't be used directly,
+ * for example EFX_NOTE_ARGUNUSED() is only used as an intermediate step on the
+ * transformation of _NOTE(ARGUNSED(arg1, arg2)) into
+ * UNREFERENCED_PARAMETER((arg1, arg2));
+ */
+#define	EFX_NOTE_ALIGNMENT(_fname, _n)
+#define	EFX_NOTE_ARGUNUSED(...)		UNREFERENCED_PARAMETER((__VA_ARGS__));
+#define	EFX_NOTE_CONSTANTCONDITION
+#define	EFX_NOTE_CONSTCOND
+#define	EFX_NOTE_EMPTY
+#define	EFX_NOTE_FALLTHROUGH
+#define	EFX_NOTE_FALLTHRU
+#define	EFX_NOTE_LINTED(_msg)
+#define	EFX_NOTE_NOTREACHED
+#define	EFX_NOTE_PRINTFLIKE(_n)
+#define	EFX_NOTE_SCANFLIKE(_n)
+#define	EFX_NOTE_VARARGS(_n)
+
+#define	_NOTE(_annotation)		EFX_NOTE_ ## _annotation
+
+#else
+
+/* Ignore Solaris annotations on other platforms */
+
+#define	_NOTE(_annotation)
+
+#endif	/* EFX_HAVE_WINDOWS_ANNOTATIONS */
+
+#endif	/* !EFX_HAVE_SOLARIS_ANNOTATIONS */
+
+#endif	/* _SYS_EFX_ANNOTE_H */
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index b9d2df581..0b4795da1 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -48,10 +48,6 @@ extern "C" {
 #include "efx_types.h"
 
 
-#ifndef _NOTE
-#define _NOTE(s)
-#endif
-
 typedef bool boolean_t;
 
 #ifndef B_FALSE
@@ -106,40 +102,6 @@ prefetch_read_once(const volatile void *addr)
 	rte_prefetch_non_temporal(addr);
 }
 
-/* Modifiers used for Windows builds */
-#define __in
-#define __in_opt
-#define __in_ecount(_n)
-#define __in_ecount_opt(_n)
-#define __in_bcount(_n)
-#define __in_bcount_opt(_n)
-
-#define __out
-#define __out_opt
-#define __out_ecount(_n)
-#define __out_ecount_opt(_n)
-#define __out_bcount(_n)
-#define __out_bcount_opt(_n)
-#define __out_bcount_part(_n, _l)
-#define __out_bcount_part_opt(_n, _l)
-
-#define __deref_out
-
-#define __inout
-#define __inout_opt
-#define __inout_ecount(_n)
-#define __inout_ecount_opt(_n)
-#define __inout_bcount(_n)
-#define __inout_bcount_opt(_n)
-#define __inout_bcount_full_opt(_n)
-
-#define __deref_out_bcount_opt(n)
-
-#define __checkReturn
-#define __success(_x)
-
-#define __drv_when(_p, _c)
-
 /* Code inclusion options */
 
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 12/37] net/sfc/base: add check for TUNNEL module in NIC reset API
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (10 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 11/37] net/sfc/base: move empty efsys definitions to EFX headers Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 13/37] net/sfc/base: refactor monitors support Andrew Rybchenko
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Vijay Srivastava, stable

From: Vijay Srivastava <vijays@solarflare.com>

Fixes: 17551f6dffcc ("net/sfc/base: add API to control UDP tunnel ports")
Cc: stable@dpdk.org

Signed-off-by: Vijay Srivastava <vijays@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx_nic.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index 6314ae2ff..0e8ed9c2a 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -549,7 +549,7 @@ efx_nic_reset(
 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
 	/*
-	 * All modules except the MCDI, PROBE, NVRAM, VPD, MON
+	 * All modules except the MCDI, PROBE, NVRAM, VPD, MON, TUNNEL
 	 * (which we do not reset here) must have been shut down or never
 	 * initialized.
 	 *
@@ -560,6 +560,9 @@ efx_nic_reset(
 	mod_flags = enp->en_mod_flags;
 	mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
 	    EFX_MOD_VPD | EFX_MOD_MON);
+#if EFSYS_OPT_TUNNEL
+	mod_flags &= ~EFX_MOD_TUNNEL;
+#endif /* EFSYS_OPT_TUNNEL */
 	EFSYS_ASSERT3U(mod_flags, ==, 0);
 	if (mod_flags != 0) {
 		rc = EINVAL;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 13/37] net/sfc/base: refactor monitors support
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (11 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 12/37] net/sfc/base: add check for TUNNEL module in NIC reset API Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 14/37] net/sfc/base: remove probes when a Tx queue is too full Andrew Rybchenko
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey

From: Martin Harvey <mharvey@solarflare.com>

Remove obsolete monitor types since Falcon SFN4000 series adapters
no longer supported by libefx.
Rename MCDI monitors to be consistent with YML.
The code may be simplified and generalized since only MCDI monitors
remain.

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h      | 158 ++++----
 drivers/net/sfc/base/efx_mon.c  | 623 ++++++++++++++++++++++++++++----
 drivers/net/sfc/base/mcdi_mon.c | 187 ++--------
 3 files changed, 695 insertions(+), 273 deletions(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 4c8983387..ffb6aad94 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -662,77 +662,74 @@ efx_mon_init(
 #define	EFX_MON_STATS_PAGE_SIZE 0x100
 #define	EFX_MON_MASK_ELEMENT_SIZE 32
 
-/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 400fdb0517af1fca */
+/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 78b65c8d5af9747b */
 typedef enum efx_mon_stat_e {
-	EFX_MON_STAT_2_5V,
-	EFX_MON_STAT_VCCP1,
-	EFX_MON_STAT_VCC,
-	EFX_MON_STAT_5V,
-	EFX_MON_STAT_12V,
-	EFX_MON_STAT_VCCP2,
-	EFX_MON_STAT_EXT_TEMP,
-	EFX_MON_STAT_INT_TEMP,
-	EFX_MON_STAT_AIN1,
-	EFX_MON_STAT_AIN2,
-	EFX_MON_STAT_INT_COOLING,
-	EFX_MON_STAT_EXT_COOLING,
-	EFX_MON_STAT_1V,
-	EFX_MON_STAT_1_2V,
-	EFX_MON_STAT_1_8V,
-	EFX_MON_STAT_3_3V,
-	EFX_MON_STAT_1_2VA,
-	EFX_MON_STAT_VREF,
-	EFX_MON_STAT_VAOE,
+	EFX_MON_STAT_CONTROLLER_TEMP,
+	EFX_MON_STAT_PHY_COMMON_TEMP,
+	EFX_MON_STAT_CONTROLLER_COOLING,
+	EFX_MON_STAT_PHY0_TEMP,
+	EFX_MON_STAT_PHY0_COOLING,
+	EFX_MON_STAT_PHY1_TEMP,
+	EFX_MON_STAT_PHY1_COOLING,
+	EFX_MON_STAT_IN_1V0,
+	EFX_MON_STAT_IN_1V2,
+	EFX_MON_STAT_IN_1V8,
+	EFX_MON_STAT_IN_2V5,
+	EFX_MON_STAT_IN_3V3,
+	EFX_MON_STAT_IN_12V0,
+	EFX_MON_STAT_IN_1V2A,
+	EFX_MON_STAT_IN_VREF,
+	EFX_MON_STAT_OUT_VAOE,
 	EFX_MON_STAT_AOE_TEMP,
 	EFX_MON_STAT_PSU_AOE_TEMP,
 	EFX_MON_STAT_PSU_TEMP,
-	EFX_MON_STAT_FAN0,
-	EFX_MON_STAT_FAN1,
-	EFX_MON_STAT_FAN2,
-	EFX_MON_STAT_FAN3,
-	EFX_MON_STAT_FAN4,
-	EFX_MON_STAT_VAOE_IN,
-	EFX_MON_STAT_IAOE,
-	EFX_MON_STAT_IAOE_IN,
+	EFX_MON_STAT_FAN_0,
+	EFX_MON_STAT_FAN_1,
+	EFX_MON_STAT_FAN_2,
+	EFX_MON_STAT_FAN_3,
+	EFX_MON_STAT_FAN_4,
+	EFX_MON_STAT_IN_VAOE,
+	EFX_MON_STAT_OUT_IAOE,
+	EFX_MON_STAT_IN_IAOE,
 	EFX_MON_STAT_NIC_POWER,
-	EFX_MON_STAT_0_9V,
-	EFX_MON_STAT_I0_9V,
-	EFX_MON_STAT_I1_2V,
-	EFX_MON_STAT_0_9V_ADC,
-	EFX_MON_STAT_INT_TEMP2,
-	EFX_MON_STAT_VREG_TEMP,
-	EFX_MON_STAT_VREG_0_9V_TEMP,
-	EFX_MON_STAT_VREG_1_2V_TEMP,
-	EFX_MON_STAT_INT_VPTAT,
-	EFX_MON_STAT_INT_ADC_TEMP,
-	EFX_MON_STAT_EXT_VPTAT,
-	EFX_MON_STAT_EXT_ADC_TEMP,
+	EFX_MON_STAT_IN_0V9,
+	EFX_MON_STAT_IN_I0V9,
+	EFX_MON_STAT_IN_I1V2,
+	EFX_MON_STAT_IN_0V9_ADC,
+	EFX_MON_STAT_CONTROLLER_2_TEMP,
+	EFX_MON_STAT_VREG_INTERNAL_TEMP,
+	EFX_MON_STAT_VREG_0V9_TEMP,
+	EFX_MON_STAT_VREG_1V2_TEMP,
+	EFX_MON_STAT_CONTROLLER_VPTAT,
+	EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP,
+	EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC,
+	EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC,
 	EFX_MON_STAT_AMBIENT_TEMP,
 	EFX_MON_STAT_AIRFLOW,
 	EFX_MON_STAT_VDD08D_VSS08D_CSR,
 	EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC,
 	EFX_MON_STAT_HOTPOINT_TEMP,
-	EFX_MON_STAT_PHY_POWER_SWITCH_PORT0,
-	EFX_MON_STAT_PHY_POWER_SWITCH_PORT1,
+	EFX_MON_STAT_PHY_POWER_PORT0,
+	EFX_MON_STAT_PHY_POWER_PORT1,
 	EFX_MON_STAT_MUM_VCC,
-	EFX_MON_STAT_0V9_A,
-	EFX_MON_STAT_I0V9_A,
-	EFX_MON_STAT_0V9_A_TEMP,
-	EFX_MON_STAT_0V9_B,
-	EFX_MON_STAT_I0V9_B,
-	EFX_MON_STAT_0V9_B_TEMP,
+	EFX_MON_STAT_IN_0V9_A,
+	EFX_MON_STAT_IN_I0V9_A,
+	EFX_MON_STAT_VREG_0V9_A_TEMP,
+	EFX_MON_STAT_IN_0V9_B,
+	EFX_MON_STAT_IN_I0V9_B,
+	EFX_MON_STAT_VREG_0V9_B_TEMP,
 	EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY,
-	EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXT_ADC,
+	EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC,
 	EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY,
-	EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXT_ADC,
+	EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC,
 	EFX_MON_STAT_CONTROLLER_MASTER_VPTAT,
 	EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP,
-	EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXT_ADC,
-	EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC,
+	EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC,
+	EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC,
 	EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT,
 	EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP,
-	EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXT_ADC,
-	EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC,
+	EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC,
+	EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC,
 	EFX_MON_STAT_SODIMM_VOUT,
 	EFX_MON_STAT_SODIMM_0_TEMP,
 	EFX_MON_STAT_SODIMM_1_TEMP,
@@ -741,12 +738,12 @@ typedef enum efx_mon_stat_e {
 	EFX_MON_STAT_CONTROLLER_TDIODE_TEMP,
 	EFX_MON_STAT_BOARD_FRONT_TEMP,
 	EFX_MON_STAT_BOARD_BACK_TEMP,
-	EFX_MON_STAT_I1V8,
-	EFX_MON_STAT_I2V5,
-	EFX_MON_STAT_I3V3,
-	EFX_MON_STAT_I12V0,
-	EFX_MON_STAT_1_3V,
-	EFX_MON_STAT_I1V3,
+	EFX_MON_STAT_IN_I1V8,
+	EFX_MON_STAT_IN_I2V5,
+	EFX_MON_STAT_IN_I3V3,
+	EFX_MON_STAT_IN_I12V0,
+	EFX_MON_STAT_IN_1V3,
+	EFX_MON_STAT_IN_I1V3,
 	EFX_MON_NSTATS
 } efx_mon_stat_t;
 
@@ -760,11 +757,33 @@ typedef enum efx_mon_stat_state_e {
 	EFX_MON_STAT_STATE_NO_READING = 4,
 } efx_mon_stat_state_t;
 
+typedef enum efx_mon_stat_unit_e {
+	EFX_MON_STAT_UNIT_UNKNOWN = 0,
+	EFX_MON_STAT_UNIT_BOOL,
+	EFX_MON_STAT_UNIT_TEMP_C,
+	EFX_MON_STAT_UNIT_VOLTAGE_MV,
+	EFX_MON_STAT_UNIT_CURRENT_MA,
+	EFX_MON_STAT_UNIT_POWER_W,
+	EFX_MON_STAT_UNIT_RPM,
+	EFX_MON_NUNITS
+} efx_mon_stat_unit_t;
+
 typedef struct efx_mon_stat_value_s {
-	uint16_t	emsv_value;
-	uint16_t	emsv_state;
+	uint16_t		emsv_value;
+	efx_mon_stat_state_t	emsv_state;
+	efx_mon_stat_unit_t	emsv_unit;
 } efx_mon_stat_value_t;
 
+typedef enum efx_mon_stat_portmask_e {
+	EFX_MON_STAT_PORTMAP_NONE = 0,
+	EFX_MON_STAT_PORTMAP_PORT0 = 1,
+	EFX_MON_STAT_PORTMAP_PORT1 = 2,
+	EFX_MON_STAT_PORTMAP_PORT2 = 3,
+	EFX_MON_STAT_PORTMAP_PORT3 = 4,
+	EFX_MON_STAT_PORTMAP_ALL = (-1),
+	EFX_MON_STAT_PORTMAP_UNKNOWN = (-2)
+} efx_mon_stat_portmask_t;
+
 #if EFSYS_OPT_NAMES
 
 extern					const char *
@@ -774,6 +793,21 @@ efx_mon_stat_name(
 
 #endif	/* EFSYS_OPT_NAMES */
 
+extern	__checkReturn			boolean_t
+efx_mon_mcdi_to_efx_stat(
+	__in				int mcdi_index,
+	__out				efx_mon_stat_t *statp);
+
+extern	__checkReturn			boolean_t
+efx_mon_get_stat_unit(
+	__in				efx_mon_stat_t stat,
+	__out				efx_mon_stat_unit_t *unitp);
+
+extern	__checkReturn			boolean_t
+efx_mon_get_stat_portmap(
+	__in				efx_mon_stat_t stat,
+	__out				efx_mon_stat_portmask_t *maskp);
+
 extern	__checkReturn			efx_rc_t
 efx_mon_stats_update(
 	__in				efx_nic_t *enp,
diff --git a/drivers/net/sfc/base/efx_mon.c b/drivers/net/sfc/base/efx_mon.c
index 9fc268ec1..34689921d 100644
--- a/drivers/net/sfc/base/efx_mon.c
+++ b/drivers/net/sfc/base/efx_mon.c
@@ -99,77 +99,74 @@ efx_mon_init(
 
 #if EFSYS_OPT_NAMES
 
-/* START MKCONFIG GENERATED MonitorStatNamesBlock 8150a068198c0f96 */
+/* START MKCONFIG GENERATED MonitorStatNamesBlock 277c17eda1a6d1a4 */
 static const char * const __mon_stat_name[] = {
-	"value_2_5v",
-	"value_vccp1",
-	"value_vcc",
-	"value_5v",
-	"value_12v",
-	"value_vccp2",
-	"value_ext_temp",
-	"value_int_temp",
-	"value_ain1",
-	"value_ain2",
+	"controller_temp",
+	"phy_common_temp",
 	"controller_cooling",
-	"ext_cooling",
-	"1v",
-	"1_2v",
-	"1_8v",
-	"3_3v",
-	"1_2va",
-	"vref",
-	"vaoe",
-	"aoe_temperature",
-	"psu_aoe_temperature",
-	"psu_temperature",
-	"fan0",
-	"fan1",
-	"fan2",
-	"fan3",
-	"fan4",
-	"vaoe_in",
-	"iaoe",
-	"iaoe_in",
+	"phy0_temp",
+	"phy0_cooling",
+	"phy1_temp",
+	"phy1_cooling",
+	"in_1v0",
+	"in_1v2",
+	"in_1v8",
+	"in_2v5",
+	"in_3v3",
+	"in_12v0",
+	"in_1v2a",
+	"in_vref",
+	"out_vaoe",
+	"aoe_temp",
+	"psu_aoe_temp",
+	"psu_temp",
+	"fan_0",
+	"fan_1",
+	"fan_2",
+	"fan_3",
+	"fan_4",
+	"in_vaoe",
+	"out_iaoe",
+	"in_iaoe",
 	"nic_power",
-	"0_9v",
-	"i0_9v",
-	"i1_2v",
-	"0_9v_adc",
-	"controller_temperature2",
-	"vreg_temperature",
-	"vreg_0_9v_temperature",
-	"vreg_1_2v_temperature",
-	"int_vptat",
-	"controller_internal_adc_temperature",
-	"ext_vptat",
-	"controller_external_adc_temperature",
-	"ambient_temperature",
+	"in_0v9",
+	"in_i0v9",
+	"in_i1v2",
+	"in_0v9_adc",
+	"controller_2_temp",
+	"vreg_internal_temp",
+	"vreg_0v9_temp",
+	"vreg_1v2_temp",
+	"controller_vptat",
+	"controller_internal_temp",
+	"controller_vptat_extadc",
+	"controller_internal_temp_extadc",
+	"ambient_temp",
 	"airflow",
 	"vdd08d_vss08d_csr",
 	"vdd08d_vss08d_csr_extadc",
-	"hotpoint_temperature",
-	"phy_power_switch_port0",
-	"phy_power_switch_port1",
+	"hotpoint_temp",
+	"phy_power_port0",
+	"phy_power_port1",
 	"mum_vcc",
-	"0v9_a",
-	"i0v9_a",
-	"0v9_a_temp",
-	"0v9_b",
-	"i0v9_b",
-	"0v9_b_temp",
+	"in_0v9_a",
+	"in_i0v9_a",
+	"vreg_0v9_a_temp",
+	"in_0v9_b",
+	"in_i0v9_b",
+	"vreg_0v9_b_temp",
 	"ccom_avreg_1v2_supply",
-	"ccom_avreg_1v2_supply_ext_adc",
+	"ccom_avreg_1v2_supply_extadc",
 	"ccom_avreg_1v8_supply",
-	"ccom_avreg_1v8_supply_ext_adc",
+	"ccom_avreg_1v8_supply_extadc",
 	"controller_master_vptat",
 	"controller_master_internal_temp",
-	"controller_master_vptat_ext_adc",
-	"controller_master_internal_temp_ext_adc",
+	"controller_master_vptat_extadc",
+	"controller_master_internal_temp_extadc",
 	"controller_slave_vptat",
 	"controller_slave_internal_temp",
-	"controller_slave_vptat_ext_adc",
-	"controller_slave_internal_temp_ext_adc",
+	"controller_slave_vptat_extadc",
+	"controller_slave_internal_temp_extadc",
 	"sodimm_vout",
 	"sodimm_0_temp",
 	"sodimm_1_temp",
@@ -178,16 +175,514 @@ static const char * const __mon_stat_name[] = {
 	"controller_tdiode_temp",
 	"board_front_temp",
 	"board_back_temp",
-	"i1v8",
-	"i2v5",
-	"i3v3",
-	"i12v0",
-	"1v3",
-	"i1v3",
+	"in_i1v8",
+	"in_i2v5",
+	"in_i3v3",
+	"in_i12v0",
+	"in_1v3",
+	"in_i1v3",
 };
 
 /* END MKCONFIG GENERATED MonitorStatNamesBlock */
 
+/* START MKCONFIG GENERATED MonitorMcdiMappingBlock 362875db87a4e7da */
+	__checkReturn			boolean_t
+efx_mon_mcdi_to_efx_stat(
+	__in				int mcdi_index,
+	__out				efx_mon_stat_t *statp)
+{
+
+	if ((mcdi_index % (MC_CMD_SENSOR_PAGE0_NEXT + 1)) ==
+	    MC_CMD_SENSOR_PAGE0_NEXT) {
+		*statp = EFX_MON_NSTATS;
+		return (B_FALSE);
+	}
+
+	switch (mcdi_index) {
+	case MC_CMD_SENSOR_IN_I0V9:
+		*statp = EFX_MON_STAT_IN_I0V9;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC:
+		*statp = EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT:
+		*statp = EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT;
+		break;
+	case MC_CMD_SENSOR_PSU_TEMP:
+		*statp = EFX_MON_STAT_PSU_TEMP;
+		break;
+	case MC_CMD_SENSOR_FAN_2:
+		*statp = EFX_MON_STAT_FAN_2;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC:
+		*statp = EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC;
+		break;
+	case MC_CMD_SENSOR_BOARD_BACK_TEMP:
+		*statp = EFX_MON_STAT_BOARD_BACK_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_1V3:
+		*statp = EFX_MON_STAT_IN_1V3;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP:
+		*statp = EFX_MON_STAT_CONTROLLER_TDIODE_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_2V5:
+		*statp = EFX_MON_STAT_IN_2V5;
+		break;
+	case MC_CMD_SENSOR_PHY_COMMON_TEMP:
+		*statp = EFX_MON_STAT_PHY_COMMON_TEMP;
+		break;
+	case MC_CMD_SENSOR_PHY1_TEMP:
+		*statp = EFX_MON_STAT_PHY1_TEMP;
+		break;
+	case MC_CMD_SENSOR_VREG_INTERNAL_TEMP:
+		*statp = EFX_MON_STAT_VREG_INTERNAL_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_1V0:
+		*statp = EFX_MON_STAT_IN_1V0;
+		break;
+	case MC_CMD_SENSOR_FAN_1:
+		*statp = EFX_MON_STAT_FAN_1;
+		break;
+	case MC_CMD_SENSOR_IN_1V2:
+		*statp = EFX_MON_STAT_IN_1V2;
+		break;
+	case MC_CMD_SENSOR_FAN_3:
+		*statp = EFX_MON_STAT_FAN_3;
+		break;
+	case MC_CMD_SENSOR_IN_1V2A:
+		*statp = EFX_MON_STAT_IN_1V2A;
+		break;
+	case MC_CMD_SENSOR_SODIMM_0_TEMP:
+		*statp = EFX_MON_STAT_SODIMM_0_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_1V8:
+		*statp = EFX_MON_STAT_IN_1V8;
+		break;
+	case MC_CMD_SENSOR_IN_VREF:
+		*statp = EFX_MON_STAT_IN_VREF;
+		break;
+	case MC_CMD_SENSOR_SODIMM_VOUT:
+		*statp = EFX_MON_STAT_SODIMM_VOUT;
+		break;
+	case MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY:
+		*statp = EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY;
+		break;
+	case MC_CMD_SENSOR_IN_I1V2:
+		*statp = EFX_MON_STAT_IN_I1V2;
+		break;
+	case MC_CMD_SENSOR_IN_I1V3:
+		*statp = EFX_MON_STAT_IN_I1V3;
+		break;
+	case MC_CMD_SENSOR_AIRFLOW:
+		*statp = EFX_MON_STAT_AIRFLOW;
+		break;
+	case MC_CMD_SENSOR_HOTPOINT_TEMP:
+		*statp = EFX_MON_STAT_HOTPOINT_TEMP;
+		break;
+	case MC_CMD_SENSOR_VDD08D_VSS08D_CSR:
+		*statp = EFX_MON_STAT_VDD08D_VSS08D_CSR;
+		break;
+	case MC_CMD_SENSOR_AOE_TEMP:
+		*statp = EFX_MON_STAT_AOE_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_I1V8:
+		*statp = EFX_MON_STAT_IN_I1V8;
+		break;
+	case MC_CMD_SENSOR_IN_I2V5:
+		*statp = EFX_MON_STAT_IN_I2V5;
+		break;
+	case MC_CMD_SENSOR_PHY1_COOLING:
+		*statp = EFX_MON_STAT_PHY1_COOLING;
+		break;
+	case MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC:
+		*statp = EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC;
+		break;
+	case MC_CMD_SENSOR_IN_0V9_ADC:
+		*statp = EFX_MON_STAT_IN_0V9_ADC;
+		break;
+	case MC_CMD_SENSOR_VREG_0V9_A_TEMP:
+		*statp = EFX_MON_STAT_VREG_0V9_A_TEMP;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT:
+		*statp = EFX_MON_STAT_CONTROLLER_MASTER_VPTAT;
+		break;
+	case MC_CMD_SENSOR_PHY0_VCC:
+		*statp = EFX_MON_STAT_PHY0_VCC;
+		break;
+	case MC_CMD_SENSOR_PHY0_COOLING:
+		*statp = EFX_MON_STAT_PHY0_COOLING;
+		break;
+	case MC_CMD_SENSOR_PSU_AOE_TEMP:
+		*statp = EFX_MON_STAT_PSU_AOE_TEMP;
+		break;
+	case MC_CMD_SENSOR_VREG_0V9_TEMP:
+		*statp = EFX_MON_STAT_VREG_0V9_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_I0V9_A:
+		*statp = EFX_MON_STAT_IN_I0V9_A;
+		break;
+	case MC_CMD_SENSOR_IN_I3V3:
+		*statp = EFX_MON_STAT_IN_I3V3;
+		break;
+	case MC_CMD_SENSOR_BOARD_FRONT_TEMP:
+		*statp = EFX_MON_STAT_BOARD_FRONT_TEMP;
+		break;
+	case MC_CMD_SENSOR_OUT_VAOE:
+		*statp = EFX_MON_STAT_OUT_VAOE;
+		break;
+	case MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC:
+		*statp = EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC;
+		break;
+	case MC_CMD_SENSOR_IN_I12V0:
+		*statp = EFX_MON_STAT_IN_I12V0;
+		break;
+	case MC_CMD_SENSOR_PHY_POWER_PORT1:
+		*statp = EFX_MON_STAT_PHY_POWER_PORT1;
+		break;
+	case MC_CMD_SENSOR_PHY_POWER_PORT0:
+		*statp = EFX_MON_STAT_PHY_POWER_PORT0;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC:
+		*statp = EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP:
+		*statp = EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_TEMP:
+		*statp = EFX_MON_STAT_CONTROLLER_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_IAOE:
+		*statp = EFX_MON_STAT_IN_IAOE;
+		break;
+	case MC_CMD_SENSOR_IN_VAOE:
+		*statp = EFX_MON_STAT_IN_VAOE;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC:
+		*statp = EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC;
+		break;
+	case MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY:
+		*statp = EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY;
+		break;
+	case MC_CMD_SENSOR_PHY1_VCC:
+		*statp = EFX_MON_STAT_PHY1_VCC;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_COOLING:
+		*statp = EFX_MON_STAT_CONTROLLER_COOLING;
+		break;
+	case MC_CMD_SENSOR_AMBIENT_TEMP:
+		*statp = EFX_MON_STAT_AMBIENT_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_3V3:
+		*statp = EFX_MON_STAT_IN_3V3;
+		break;
+	case MC_CMD_SENSOR_PHY0_TEMP:
+		*statp = EFX_MON_STAT_PHY0_TEMP;
+		break;
+	case MC_CMD_SENSOR_SODIMM_1_TEMP:
+		*statp = EFX_MON_STAT_SODIMM_1_TEMP;
+		break;
+	case MC_CMD_SENSOR_MUM_VCC:
+		*statp = EFX_MON_STAT_MUM_VCC;
+		break;
+	case MC_CMD_SENSOR_VREG_0V9_B_TEMP:
+		*statp = EFX_MON_STAT_VREG_0V9_B_TEMP;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP:
+		*statp = EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP;
+		break;
+	case MC_CMD_SENSOR_FAN_4:
+		*statp = EFX_MON_STAT_FAN_4;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_2_TEMP:
+		*statp = EFX_MON_STAT_CONTROLLER_2_TEMP;
+		break;
+	case MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC:
+		*statp = EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC;
+		break;
+	case MC_CMD_SENSOR_IN_0V9_A:
+		*statp = EFX_MON_STAT_IN_0V9_A;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC:
+		*statp = EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC;
+		break;
+	case MC_CMD_SENSOR_IN_0V9:
+		*statp = EFX_MON_STAT_IN_0V9;
+		break;
+	case MC_CMD_SENSOR_IN_I0V9_B:
+		*statp = EFX_MON_STAT_IN_I0V9_B;
+		break;
+	case MC_CMD_SENSOR_NIC_POWER:
+		*statp = EFX_MON_STAT_NIC_POWER;
+		break;
+	case MC_CMD_SENSOR_IN_12V0:
+		*statp = EFX_MON_STAT_IN_12V0;
+		break;
+	case MC_CMD_SENSOR_OUT_IAOE:
+		*statp = EFX_MON_STAT_OUT_IAOE;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_VPTAT:
+		*statp = EFX_MON_STAT_CONTROLLER_VPTAT;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC:
+		*statp = EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC;
+		break;
+	case MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP:
+		*statp = EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP;
+		break;
+	case MC_CMD_SENSOR_FAN_0:
+		*statp = EFX_MON_STAT_FAN_0;
+		break;
+	case MC_CMD_SENSOR_VREG_1V2_TEMP:
+		*statp = EFX_MON_STAT_VREG_1V2_TEMP;
+		break;
+	case MC_CMD_SENSOR_IN_0V9_B:
+		*statp = EFX_MON_STAT_IN_0V9_B;
+		break;
+	default:
+		*statp = EFX_MON_NSTATS;
+		break;
+	};
+
+	if (*statp == EFX_MON_NSTATS)
+		goto fail1;
+
+	return (B_TRUE);
+
+fail1:
+	EFSYS_PROBE1(fail1, boolean_t, B_TRUE);
+	return (B_FALSE);
+};
+
+/* END MKCONFIG GENERATED MonitorMcdiMappingBlock */
+
+/* START MKCONFIG GENERATED MonitorStatisticUnitsBlock 2d447c656cc2d01d */
+	__checkReturn			boolean_t
+efx_mon_get_stat_unit(
+	__in				efx_mon_stat_t stat,
+	__out				efx_mon_stat_unit_t *unitp)
+{
+	switch (stat) {
+	case EFX_MON_STAT_IN_1V0:
+	case EFX_MON_STAT_IN_1V2:
+	case EFX_MON_STAT_IN_1V8:
+	case EFX_MON_STAT_IN_2V5:
+	case EFX_MON_STAT_IN_3V3:
+	case EFX_MON_STAT_IN_12V0:
+	case EFX_MON_STAT_IN_1V2A:
+	case EFX_MON_STAT_IN_VREF:
+	case EFX_MON_STAT_OUT_VAOE:
+	case EFX_MON_STAT_IN_VAOE:
+	case EFX_MON_STAT_IN_0V9:
+	case EFX_MON_STAT_IN_0V9_ADC:
+	case EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC:
+	case EFX_MON_STAT_VDD08D_VSS08D_CSR:
+	case EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC:
+	case EFX_MON_STAT_MUM_VCC:
+	case EFX_MON_STAT_IN_0V9_A:
+	case EFX_MON_STAT_IN_0V9_B:
+	case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY:
+	case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC:
+	case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY:
+	case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT:
+	case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC:
+	case EFX_MON_STAT_SODIMM_VOUT:
+	case EFX_MON_STAT_PHY0_VCC:
+	case EFX_MON_STAT_PHY1_VCC:
+	case EFX_MON_STAT_IN_1V3:
+		*unitp = EFX_MON_STAT_UNIT_VOLTAGE_MV;
+		break;
+	case EFX_MON_STAT_CONTROLLER_TEMP:
+	case EFX_MON_STAT_PHY_COMMON_TEMP:
+	case EFX_MON_STAT_PHY0_TEMP:
+	case EFX_MON_STAT_PHY1_TEMP:
+	case EFX_MON_STAT_AOE_TEMP:
+	case EFX_MON_STAT_PSU_AOE_TEMP:
+	case EFX_MON_STAT_PSU_TEMP:
+	case EFX_MON_STAT_CONTROLLER_2_TEMP:
+	case EFX_MON_STAT_VREG_INTERNAL_TEMP:
+	case EFX_MON_STAT_VREG_0V9_TEMP:
+	case EFX_MON_STAT_VREG_1V2_TEMP:
+	case EFX_MON_STAT_CONTROLLER_VPTAT:
+	case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP:
+	case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC:
+	case EFX_MON_STAT_AMBIENT_TEMP:
+	case EFX_MON_STAT_HOTPOINT_TEMP:
+	case EFX_MON_STAT_VREG_0V9_A_TEMP:
+	case EFX_MON_STAT_VREG_0V9_B_TEMP:
+	case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP:
+	case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC:
+	case EFX_MON_STAT_SODIMM_0_TEMP:
+	case EFX_MON_STAT_SODIMM_1_TEMP:
+	case EFX_MON_STAT_CONTROLLER_TDIODE_TEMP:
+	case EFX_MON_STAT_BOARD_FRONT_TEMP:
+	case EFX_MON_STAT_BOARD_BACK_TEMP:
+		*unitp = EFX_MON_STAT_UNIT_TEMP_C;
+		break;
+	case EFX_MON_STAT_CONTROLLER_COOLING:
+	case EFX_MON_STAT_PHY0_COOLING:
+	case EFX_MON_STAT_PHY1_COOLING:
+	case EFX_MON_STAT_AIRFLOW:
+	case EFX_MON_STAT_PHY_POWER_PORT0:
+	case EFX_MON_STAT_PHY_POWER_PORT1:
+		*unitp = EFX_MON_STAT_UNIT_BOOL;
+		break;
+	case EFX_MON_STAT_NIC_POWER:
+		*unitp = EFX_MON_STAT_UNIT_POWER_W;
+		break;
+	case EFX_MON_STAT_OUT_IAOE:
+	case EFX_MON_STAT_IN_IAOE:
+	case EFX_MON_STAT_IN_I0V9:
+	case EFX_MON_STAT_IN_I1V2:
+	case EFX_MON_STAT_IN_I0V9_A:
+	case EFX_MON_STAT_IN_I0V9_B:
+	case EFX_MON_STAT_IN_I1V8:
+	case EFX_MON_STAT_IN_I2V5:
+	case EFX_MON_STAT_IN_I3V3:
+	case EFX_MON_STAT_IN_I12V0:
+	case EFX_MON_STAT_IN_I1V3:
+		*unitp = EFX_MON_STAT_UNIT_CURRENT_MA;
+		break;
+	case EFX_MON_STAT_FAN_0:
+	case EFX_MON_STAT_FAN_1:
+	case EFX_MON_STAT_FAN_2:
+	case EFX_MON_STAT_FAN_3:
+	case EFX_MON_STAT_FAN_4:
+		*unitp = EFX_MON_STAT_UNIT_RPM;
+		break;
+	default:
+		*unitp = EFX_MON_STAT_UNIT_UNKNOWN;
+		break;
+	};
+
+	if (*unitp == EFX_MON_STAT_UNIT_UNKNOWN)
+		goto fail1;
+
+	return (B_TRUE);
+
+fail1:
+	EFSYS_PROBE1(fail1, boolean_t, B_TRUE);
+	return (B_FALSE);
+};
+
+/* END MKCONFIG GENERATED MonitorStatisticUnitsBlock */
+
+/* START MKCONFIG GENERATED MonitorStatisticPortsBlock 1719b751d842534f */
+	__checkReturn			boolean_t
+efx_mon_get_stat_portmap(
+	__in				efx_mon_stat_t stat,
+	__out				efx_mon_stat_portmask_t *maskp)
+{
+
+	switch (stat) {
+	case EFX_MON_STAT_PHY1_TEMP:
+	case EFX_MON_STAT_PHY1_COOLING:
+	case EFX_MON_STAT_PHY_POWER_PORT1:
+		*maskp = EFX_MON_STAT_PORTMAP_PORT1;
+		break;
+	case EFX_MON_STAT_CONTROLLER_TEMP:
+	case EFX_MON_STAT_PHY_COMMON_TEMP:
+	case EFX_MON_STAT_CONTROLLER_COOLING:
+	case EFX_MON_STAT_IN_1V0:
+	case EFX_MON_STAT_IN_1V2:
+	case EFX_MON_STAT_IN_1V8:
+	case EFX_MON_STAT_IN_2V5:
+	case EFX_MON_STAT_IN_3V3:
+	case EFX_MON_STAT_IN_12V0:
+	case EFX_MON_STAT_IN_1V2A:
+	case EFX_MON_STAT_IN_VREF:
+	case EFX_MON_STAT_OUT_VAOE:
+	case EFX_MON_STAT_AOE_TEMP:
+	case EFX_MON_STAT_PSU_AOE_TEMP:
+	case EFX_MON_STAT_PSU_TEMP:
+	case EFX_MON_STAT_FAN_0:
+	case EFX_MON_STAT_FAN_1:
+	case EFX_MON_STAT_FAN_2:
+	case EFX_MON_STAT_FAN_3:
+	case EFX_MON_STAT_FAN_4:
+	case EFX_MON_STAT_IN_VAOE:
+	case EFX_MON_STAT_OUT_IAOE:
+	case EFX_MON_STAT_IN_IAOE:
+	case EFX_MON_STAT_NIC_POWER:
+	case EFX_MON_STAT_IN_0V9:
+	case EFX_MON_STAT_IN_I0V9:
+	case EFX_MON_STAT_IN_I1V2:
+	case EFX_MON_STAT_IN_0V9_ADC:
+	case EFX_MON_STAT_CONTROLLER_2_TEMP:
+	case EFX_MON_STAT_VREG_INTERNAL_TEMP:
+	case EFX_MON_STAT_VREG_0V9_TEMP:
+	case EFX_MON_STAT_VREG_1V2_TEMP:
+	case EFX_MON_STAT_CONTROLLER_VPTAT:
+	case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP:
+	case EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC:
+	case EFX_MON_STAT_AMBIENT_TEMP:
+	case EFX_MON_STAT_AIRFLOW:
+	case EFX_MON_STAT_VDD08D_VSS08D_CSR:
+	case EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC:
+	case EFX_MON_STAT_HOTPOINT_TEMP:
+	case EFX_MON_STAT_MUM_VCC:
+	case EFX_MON_STAT_IN_0V9_A:
+	case EFX_MON_STAT_IN_I0V9_A:
+	case EFX_MON_STAT_VREG_0V9_A_TEMP:
+	case EFX_MON_STAT_IN_0V9_B:
+	case EFX_MON_STAT_IN_I0V9_B:
+	case EFX_MON_STAT_VREG_0V9_B_TEMP:
+	case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY:
+	case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC:
+	case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY:
+	case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT:
+	case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP:
+	case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC:
+	case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC:
+	case EFX_MON_STAT_SODIMM_VOUT:
+	case EFX_MON_STAT_SODIMM_0_TEMP:
+	case EFX_MON_STAT_SODIMM_1_TEMP:
+	case EFX_MON_STAT_PHY0_VCC:
+	case EFX_MON_STAT_PHY1_VCC:
+	case EFX_MON_STAT_CONTROLLER_TDIODE_TEMP:
+	case EFX_MON_STAT_BOARD_FRONT_TEMP:
+	case EFX_MON_STAT_BOARD_BACK_TEMP:
+	case EFX_MON_STAT_IN_I1V8:
+	case EFX_MON_STAT_IN_I2V5:
+	case EFX_MON_STAT_IN_I3V3:
+	case EFX_MON_STAT_IN_I12V0:
+	case EFX_MON_STAT_IN_1V3:
+	case EFX_MON_STAT_IN_I1V3:
+		*maskp = EFX_MON_STAT_PORTMAP_ALL;
+		break;
+	case EFX_MON_STAT_PHY0_TEMP:
+	case EFX_MON_STAT_PHY0_COOLING:
+	case EFX_MON_STAT_PHY_POWER_PORT0:
+		*maskp = EFX_MON_STAT_PORTMAP_PORT0;
+		break;
+	default:
+		*maskp = EFX_MON_STAT_PORTMAP_UNKNOWN;
+		break;
+	};
+
+	if (*maskp == EFX_MON_STAT_PORTMAP_UNKNOWN)
+		goto fail1;
+
+	return (B_TRUE);
+
+fail1:
+	EFSYS_PROBE1(fail1, boolean_t, B_TRUE);
+	return (B_FALSE);
+};
+
+/* END MKCONFIG GENERATED MonitorStatisticPortsBlock */
+
 extern					const char *
 efx_mon_stat_name(
 	__in				efx_nic_t *enp,
diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 8c0b6f0d9..93e6b1e35 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -12,136 +12,9 @@
 
 #if EFSYS_OPT_MON_STATS
 
-#define	MCDI_MON_NEXT_PAGE  ((uint16_t)0xfffe)
-#define	MCDI_MON_INVALID_SENSOR ((uint16_t)0xfffd)
-#define	MCDI_MON_PAGE_SIZE 0x20
-
-/* Bitmasks of valid port(s) for each sensor */
-#define	MCDI_MON_PORT_NONE	(0x00)
-#define	MCDI_MON_PORT_P1	(0x01)
-#define	MCDI_MON_PORT_P2	(0x02)
-#define	MCDI_MON_PORT_P3	(0x04)
-#define	MCDI_MON_PORT_P4	(0x08)
-#define	MCDI_MON_PORT_Px	(0xFFFF)
-
 /* Get port mask from one-based MCDI port number */
 #define	MCDI_MON_PORT_MASK(_emip) (1U << ((_emip)->emi_port - 1))
 
-/* Entry for MCDI sensor in sensor map */
-#define	STAT(portmask, stat)	\
-	{ (MCDI_MON_PORT_##portmask), (EFX_MON_STAT_##stat) }
-
-/* Entry for sensor next page flag in sensor map */
-#define	STAT_NEXT_PAGE()	\
-	{ MCDI_MON_PORT_NONE, MCDI_MON_NEXT_PAGE }
-
-/* Placeholder for gaps in the array */
-#define	STAT_NO_SENSOR()	\
-	{ MCDI_MON_PORT_NONE, MCDI_MON_INVALID_SENSOR }
-
-/* Map from MC sensors to monitor statistics */
-static const struct mcdi_sensor_map_s {
-	uint16_t	msm_port_mask;
-	uint16_t	msm_stat;
-} mcdi_sensor_map[] = {
-	/* Sensor page 0		MC_CMD_SENSOR_xxx */
-	STAT(Px, INT_TEMP),		/* 0x00 CONTROLLER_TEMP */
-	STAT(Px, EXT_TEMP),		/* 0x01 PHY_COMMON_TEMP */
-	STAT(Px, INT_COOLING),		/* 0x02 CONTROLLER_COOLING */
-	STAT(P1, EXT_TEMP),		/* 0x03 PHY0_TEMP */
-	STAT(P1, EXT_COOLING),		/* 0x04 PHY0_COOLING */
-	STAT(P2, EXT_TEMP),		/* 0x05 PHY1_TEMP */
-	STAT(P2, EXT_COOLING),		/* 0x06 PHY1_COOLING */
-	STAT(Px, 1V),			/* 0x07 IN_1V0 */
-	STAT(Px, 1_2V),			/* 0x08 IN_1V2 */
-	STAT(Px, 1_8V),			/* 0x09 IN_1V8 */
-	STAT(Px, 2_5V),			/* 0x0a IN_2V5 */
-	STAT(Px, 3_3V),			/* 0x0b IN_3V3 */
-	STAT(Px, 12V),			/* 0x0c IN_12V0 */
-	STAT(Px, 1_2VA),		/* 0x0d IN_1V2A */
-	STAT(Px, VREF),			/* 0x0e IN_VREF */
-	STAT(Px, VAOE),			/* 0x0f OUT_VAOE */
-	STAT(Px, AOE_TEMP),		/* 0x10 AOE_TEMP */
-	STAT(Px, PSU_AOE_TEMP),		/* 0x11 PSU_AOE_TEMP */
-	STAT(Px, PSU_TEMP),		/* 0x12 PSU_TEMP */
-	STAT(Px, FAN0),			/* 0x13 FAN_0 */
-	STAT(Px, FAN1),			/* 0x14 FAN_1 */
-	STAT(Px, FAN2),			/* 0x15 FAN_2 */
-	STAT(Px, FAN3),			/* 0x16 FAN_3 */
-	STAT(Px, FAN4),			/* 0x17 FAN_4 */
-	STAT(Px, VAOE_IN),		/* 0x18 IN_VAOE */
-	STAT(Px, IAOE),			/* 0x19 OUT_IAOE */
-	STAT(Px, IAOE_IN),		/* 0x1a IN_IAOE */
-	STAT(Px, NIC_POWER),		/* 0x1b NIC_POWER */
-	STAT(Px, 0_9V),			/* 0x1c IN_0V9 */
-	STAT(Px, I0_9V),		/* 0x1d IN_I0V9 */
-	STAT(Px, I1_2V),		/* 0x1e IN_I1V2 */
-	STAT_NEXT_PAGE(),		/* 0x1f Next page flag (not a sensor) */
-
-	/* Sensor page 1		MC_CMD_SENSOR_xxx */
-	STAT(Px, 0_9V_ADC),		/* 0x20 IN_0V9_ADC */
-	STAT(Px, INT_TEMP2),		/* 0x21 CONTROLLER_2_TEMP */
-	STAT(Px, VREG_TEMP),		/* 0x22 VREG_INTERNAL_TEMP */
-	STAT(Px, VREG_0_9V_TEMP),	/* 0x23 VREG_0V9_TEMP */
-	STAT(Px, VREG_1_2V_TEMP),	/* 0x24 VREG_1V2_TEMP */
-	STAT(Px, INT_VPTAT),		/* 0x25 CTRLR. VPTAT */
-	STAT(Px, INT_ADC_TEMP),		/* 0x26 CTRLR. INTERNAL_TEMP */
-	STAT(Px, EXT_VPTAT),		/* 0x27 CTRLR. VPTAT_EXTADC */
-	STAT(Px, EXT_ADC_TEMP),		/* 0x28 CTRLR. INTERNAL_TEMP_EXTADC */
-	STAT(Px, AMBIENT_TEMP),		/* 0x29 AMBIENT_TEMP */
-	STAT(Px, AIRFLOW),		/* 0x2a AIRFLOW */
-	STAT(Px, VDD08D_VSS08D_CSR),	/* 0x2b VDD08D_VSS08D_CSR */
-	STAT(Px, VDD08D_VSS08D_CSR_EXTADC), /* 0x2c VDD08D_VSS08D_CSR_EXTADC */
-	STAT(Px, HOTPOINT_TEMP),	/* 0x2d HOTPOINT_TEMP */
-	STAT(P1, PHY_POWER_SWITCH_PORT0),   /* 0x2e PHY_POWER_SWITCH_PORT0 */
-	STAT(P2, PHY_POWER_SWITCH_PORT1),   /* 0x2f PHY_POWER_SWITCH_PORT1 */
-	STAT(Px, MUM_VCC),		/* 0x30 MUM_VCC */
-	STAT(Px, 0V9_A),		/* 0x31 0V9_A */
-	STAT(Px, I0V9_A),		/* 0x32 I0V9_A */
-	STAT(Px, 0V9_A_TEMP),		/* 0x33 0V9_A_TEMP */
-	STAT(Px, 0V9_B),		/* 0x34 0V9_B */
-	STAT(Px, I0V9_B),		/* 0x35 I0V9_B */
-	STAT(Px, 0V9_B_TEMP),		/* 0x36 0V9_B_TEMP */
-	STAT(Px, CCOM_AVREG_1V2_SUPPLY),  /* 0x37 CCOM_AVREG_1V2_SUPPLY */
-	STAT(Px, CCOM_AVREG_1V2_SUPPLY_EXT_ADC),
-					/* 0x38 CCOM_AVREG_1V2_SUPPLY_EXT_ADC */
-	STAT(Px, CCOM_AVREG_1V8_SUPPLY),  /* 0x39 CCOM_AVREG_1V8_SUPPLY */
-	STAT(Px, CCOM_AVREG_1V8_SUPPLY_EXT_ADC),
-					/* 0x3a CCOM_AVREG_1V8_SUPPLY_EXT_ADC */
-	STAT_NO_SENSOR(),		/* 0x3b (no sensor) */
-	STAT_NO_SENSOR(),		/* 0x3c (no sensor) */
-	STAT_NO_SENSOR(),		/* 0x3d (no sensor) */
-	STAT_NO_SENSOR(),		/* 0x3e (no sensor) */
-	STAT_NEXT_PAGE(),		/* 0x3f Next page flag (not a sensor) */
-
-	/* Sensor page 2		MC_CMD_SENSOR_xxx */
-	STAT(Px, CONTROLLER_MASTER_VPTAT),	   /* 0x40 MASTER_VPTAT */
-	STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP), /* 0x41 MASTER_INT_TEMP */
-	STAT(Px, CONTROLLER_MASTER_VPTAT_EXT_ADC), /* 0x42 MAST_VPTAT_EXT_ADC */
-	STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC),
-					/* 0x43 MASTER_INTERNAL_TEMP_EXT_ADC */
-	STAT(Px, CONTROLLER_SLAVE_VPTAT),	  /* 0x44 SLAVE_VPTAT */
-	STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP), /* 0x45 SLAVE_INTERNAL_TEMP */
-	STAT(Px, CONTROLLER_SLAVE_VPTAT_EXT_ADC), /* 0x46 SLAVE_VPTAT_EXT_ADC */
-	STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC),
-					/* 0x47 SLAVE_INTERNAL_TEMP_EXT_ADC */
-	STAT_NO_SENSOR(),		/* 0x48 (no sensor) */
-	STAT(Px, SODIMM_VOUT),		/* 0x49 SODIMM_VOUT */
-	STAT(Px, SODIMM_0_TEMP),	/* 0x4a SODIMM_0_TEMP */
-	STAT(Px, SODIMM_1_TEMP),	/* 0x4b SODIMM_1_TEMP */
-	STAT(Px, PHY0_VCC),		/* 0x4c PHY0_VCC */
-	STAT(Px, PHY1_VCC),		/* 0x4d PHY1_VCC */
-	STAT(Px, CONTROLLER_TDIODE_TEMP), /* 0x4e CONTROLLER_TDIODE_TEMP */
-	STAT(Px, BOARD_FRONT_TEMP),	/* 0x4f BOARD_FRONT_TEMP */
-	STAT(Px, BOARD_BACK_TEMP),	/* 0x50 BOARD_BACK_TEMP */
-	STAT(Px, I1V8),			/* 0x51 IN_I1V8 */
-	STAT(Px, I2V5),			/* 0x52 IN_I2V5 */
-	STAT(Px, I3V3),			/* 0x53 IN_I3V3 */
-	STAT(Px, I12V0),		/* 0x54 IN_I12V0 */
-	STAT(Px, 1_3V),			/* 0x55 IN_1V3 */
-	STAT(Px, I1V3),			/* 0x56 IN_I1V3 */
-};
-
 #define	MCDI_STATIC_SENSOR_ASSERT(_field)				\
 	EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field		\
 			    == EFX_MON_STAT_STATE_ ## _field)
@@ -156,10 +29,10 @@ mcdi_mon_decode_stats(
 	__inout_ecount_opt(EFX_MON_NSTATS)	efx_mon_stat_value_t *stat)
 {
 	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
-	uint16_t port_mask;
+	efx_mon_stat_portmask_t port_mask;
 	uint16_t sensor;
 	size_t sensor_max;
-	uint32_t stat_mask[(EFX_ARRAY_SIZE(mcdi_sensor_map) + 31) / 32];
+	uint32_t stat_mask[(EFX_MON_NSTATS + 31) / 32];
 	uint32_t idx = 0;
 	uint32_t page = 0;
 
@@ -170,13 +43,10 @@ mcdi_mon_decode_stats(
 	MCDI_STATIC_SENSOR_ASSERT(BROKEN);
 	MCDI_STATIC_SENSOR_ASSERT(NO_READING);
 
-	EFX_STATIC_ASSERT(sizeof (stat_mask[0]) * 8 ==
-	    EFX_MON_MASK_ELEMENT_SIZE);
-	sensor_max =
-	    MIN((8 * sensor_mask_size), EFX_ARRAY_SIZE(mcdi_sensor_map));
+	sensor_max = 8 * sensor_mask_size;
 
 	EFSYS_ASSERT(emip->emi_port > 0); /* MCDI port number is one-based */
-	port_mask = MCDI_MON_PORT_MASK(emip);
+	port_mask = (efx_mon_stat_portmask_t)MCDI_MON_PORT_MASK(emip);
 
 	memset(stat_mask, 0, sizeof (stat_mask));
 
@@ -191,19 +61,36 @@ mcdi_mon_decode_stats(
 	 * does not understand.
 	 */
 	for (sensor = 0; sensor < sensor_max; ++sensor) {
-		efx_mon_stat_t id = mcdi_sensor_map[sensor].msm_stat;
+		efx_mon_stat_t id;
+		efx_mon_stat_portmask_t stat_portmask = 0;
+		boolean_t decode_ok;
+		efx_mon_stat_unit_t stat_unit;
 
-		if ((sensor % MCDI_MON_PAGE_SIZE) == MC_CMD_SENSOR_PAGE0_NEXT) {
-			EFSYS_ASSERT3U(id, ==, MCDI_MON_NEXT_PAGE);
+		if ((sensor % (MC_CMD_SENSOR_PAGE0_NEXT + 1)) ==
+		    MC_CMD_SENSOR_PAGE0_NEXT) {
 			page++;
 			continue;
+			/* This sensor is one of the page boundary bits. */
 		}
+
 		if (~(sensor_mask[page]) & (1U << sensor))
 			continue;
+		/* This sensor not in DMA buffer */
+
 		idx++;
+		/*
+		 * Valid stat in DMA buffer that we need to increment over, even
+		 * if we couldn't look up the id
+		 */
+
+		decode_ok = efx_mon_mcdi_to_efx_stat(sensor, &id);
+		decode_ok =
+		    decode_ok && efx_mon_get_stat_portmap(id, &stat_portmask);
 
-		if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+		if (!(decode_ok && (stat_portmask & port_mask)))
 			continue;
+		/* Either bad decode, or don't know what port stat is on */
+
 		EFSYS_ASSERT(id < EFX_MON_NSTATS);
 
 		/*
@@ -229,6 +116,10 @@ mcdi_mon_decode_stats(
 
 			stat[id].emsv_state = (uint16_t)EFX_DWORD_FIELD(dword,
 			    MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
+
+			stat[id].emsv_unit =
+			    efx_mon_get_stat_unit(id, &stat_unit) ?
+			    stat_unit : EFX_MON_STAT_UNIT_UNKNOWN;
 		}
 	}
 
@@ -245,7 +136,7 @@ mcdi_mon_ev(
 	__out				efx_mon_stat_value_t *valuep)
 {
 	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
-	uint16_t port_mask;
+	efx_mon_stat_portmask_t port_mask, sensor_port_mask;
 	uint16_t sensor;
 	uint16_t state;
 	uint16_t value;
@@ -262,20 +153,22 @@ mcdi_mon_ev(
 	/* Hardware must support this MCDI sensor */
 	EFSYS_ASSERT3U(sensor, <,
 	    (8 * enp->en_nic_cfg.enc_mcdi_sensor_mask_size));
-	EFSYS_ASSERT((sensor % MCDI_MON_PAGE_SIZE) != MC_CMD_SENSOR_PAGE0_NEXT);
+	EFSYS_ASSERT((sensor % (MC_CMD_SENSOR_PAGE0_NEXT + 1)) !=
+	    MC_CMD_SENSOR_PAGE0_NEXT);
 	EFSYS_ASSERT(enp->en_nic_cfg.enc_mcdi_sensor_maskp != NULL);
-	EFSYS_ASSERT(
-	    (enp->en_nic_cfg.enc_mcdi_sensor_maskp[sensor/MCDI_MON_PAGE_SIZE] &
-	    (1U << (sensor % MCDI_MON_PAGE_SIZE))) != 0);
+	EFSYS_ASSERT((enp->en_nic_cfg.enc_mcdi_sensor_maskp[
+		    sensor / (MC_CMD_SENSOR_PAGE0_NEXT + 1)] &
+		(1U << (sensor % (MC_CMD_SENSOR_PAGE0_NEXT + 1)))) != 0);
 
-	/* But we don't have to understand it */
-	if (sensor >= EFX_ARRAY_SIZE(mcdi_sensor_map)) {
+	/* And we need to understand it, to get port-map */
+	if (!efx_mon_mcdi_to_efx_stat(sensor, &id)) {
 		rc = ENOTSUP;
 		goto fail1;
 	}
-	id = mcdi_sensor_map[sensor].msm_stat;
-	if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+	if (!(efx_mon_get_stat_portmap(id, &sensor_port_mask) &&
+		(port_mask && sensor_port_mask))) {
 		return (ENODEV);
+	}
 	EFSYS_ASSERT(id < EFX_MON_NSTATS);
 
 	*idp = id;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 14/37] net/sfc/base: remove probes when a Tx queue is too full
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (12 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 13/37] net/sfc/base: refactor monitors support Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 15/37] net/sfc/base: add generated description of sensors Andrew Rybchenko
                   ` (23 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Mark Spender

From: Mark Spender <mspender@solarflare.com>

No need for probe messages when a TxQ is too full for a post to be done.

Existing drivers check if there is room in the queue before posting
descriptors, even though efx_tx_qdesc_post() does the check itself.

The new SFN Windows driver doesn't perform the check before calling
efx_tx_qdesc_post(), but that means these probes can get frequently
printed out. It's normal driver behaviour so there's no need to print
an error.

Signed-off-by: Mark Spender <mspender@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_tx.c | 12 ++----------
 drivers/net/sfc/base/efx_tx.c  | 19 ++-----------------
 2 files changed, 4 insertions(+), 27 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c
index e74d39540..4d77d76d7 100644
--- a/drivers/net/sfc/base/ef10_tx.c
+++ b/drivers/net/sfc/base/ef10_tx.c
@@ -541,12 +541,9 @@ ef10_tx_qdesc_post(
 {
 	unsigned int added = *addedp;
 	unsigned int i;
-	efx_rc_t rc;
 
-	if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
-		rc = ENOSPC;
-		goto fail1;
-	}
+	if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
+		return (ENOSPC);
 
 	for (i = 0; i < ndescs; i++) {
 		efx_desc_t *edp = &ed[i];
@@ -566,11 +563,6 @@ ef10_tx_qdesc_post(
 
 	*addedp = added;
 	return (0);
-
-fail1:
-	EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
-	return (rc);
 }
 
 	void
diff --git a/drivers/net/sfc/base/efx_tx.c b/drivers/net/sfc/base/efx_tx.c
index da37580a6..bf1180a1e 100644
--- a/drivers/net/sfc/base/efx_tx.c
+++ b/drivers/net/sfc/base/efx_tx.c
@@ -572,19 +572,10 @@ efx_tx_qdesc_post(
 {
 	efx_nic_t *enp = etp->et_enp;
 	const efx_tx_ops_t *etxop = enp->en_etxop;
-	efx_rc_t rc;
 
 	EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
 
-	if ((rc = etxop->etxo_qdesc_post(etp, ed,
-	    ndescs, completed, addedp)) != 0)
-		goto fail1;
-
-	return (0);
-
-fail1:
-	EFSYS_PROBE1(fail1, efx_rc_t, rc);
-	return (rc);
+	return (etxop->etxo_qdesc_post(etp, ed, ndescs, completed, addedp));
 }
 
 	void
@@ -763,10 +754,9 @@ siena_tx_qpost(
 {
 	unsigned int added = *addedp;
 	unsigned int i;
-	int rc = ENOSPC;
 
 	if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
-		goto fail1;
+		return (ENOSPC);
 
 	for (i = 0; i < ndescs; i++) {
 		efx_buffer_t *ebp = &eb[i];
@@ -788,11 +778,6 @@ siena_tx_qpost(
 
 	*addedp = added;
 	return (0);
-
-fail1:
-	EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
-	return (rc);
 }
 
 static		void
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 15/37] net/sfc/base: add generated description of sensors
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (13 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 14/37] net/sfc/base: remove probes when a Tx queue is too full Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 16/37] net/sfc/base: check size of memory to read sensors data to Andrew Rybchenko
                   ` (22 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey

From: Martin Harvey <mharvey@solarflare.com>

Description of sensors is generated from firmware sources.

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h                 |   5 +
 drivers/net/sfc/base/efx_mcdi.h            |   4 +
 drivers/net/sfc/base/efx_mon.c             | 133 ++++++++++++++++++---
 drivers/net/sfc/base/mc_driver_pcol_strs.h | 102 ++++++++++++++++
 4 files changed, 229 insertions(+), 15 deletions(-)
 create mode 100644 drivers/net/sfc/base/mc_driver_pcol_strs.h

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index ffb6aad94..dae90bd6e 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -791,6 +791,11 @@ efx_mon_stat_name(
 	__in				efx_nic_t *enp,
 	__in				efx_mon_stat_t id);
 
+extern					const char *
+efx_mon_stat_description(
+	__in				efx_nic_t *enp,
+	__in				efx_mon_stat_t id);
+
 #endif	/* EFSYS_OPT_NAMES */
 
 extern	__checkReturn			boolean_t
diff --git a/drivers/net/sfc/base/efx_mcdi.h b/drivers/net/sfc/base/efx_mcdi.h
index 253a9e60b..d2cd1e9e1 100644
--- a/drivers/net/sfc/base/efx_mcdi.h
+++ b/drivers/net/sfc/base/efx_mcdi.h
@@ -10,6 +10,10 @@
 #include "efx.h"
 #include "efx_regs_mcdi.h"
 
+#if EFSYS_OPT_NAMES
+#include "mc_driver_pcol_strs.h"
+#endif /* EFSYS_OPT_NAMES */
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
diff --git a/drivers/net/sfc/base/efx_mon.c b/drivers/net/sfc/base/efx_mon.c
index 34689921d..91fa16ca0 100644
--- a/drivers/net/sfc/base/efx_mon.c
+++ b/drivers/net/sfc/base/efx_mon.c
@@ -185,7 +185,124 @@ static const char * const __mon_stat_name[] = {
 
 /* END MKCONFIG GENERATED MonitorStatNamesBlock */
 
-/* START MKCONFIG GENERATED MonitorMcdiMappingBlock 362875db87a4e7da */
+					const char *
+efx_mon_stat_name(
+	__in				efx_nic_t *enp,
+	__in				efx_mon_stat_t id)
+{
+	_NOTE(ARGUNUSED(enp))
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS);
+	return (__mon_stat_name[id]);
+}
+
+typedef struct _stat_description_t {
+	efx_mon_stat_t	stat;
+	const char	*desc;
+} stat_description_t;
+
+/* START MKCONFIG GENERATED MonitorStatDescriptionsBlock f072138f16d2e1f8 */
+static const char *__mon_stat_description[] = {
+	MC_CMD_SENSOR_CONTROLLER_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PHY_COMMON_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_COOLING_ENUM_STR,
+	MC_CMD_SENSOR_PHY0_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PHY0_COOLING_ENUM_STR,
+	MC_CMD_SENSOR_PHY1_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PHY1_COOLING_ENUM_STR,
+	MC_CMD_SENSOR_IN_1V0_ENUM_STR,
+	MC_CMD_SENSOR_IN_1V2_ENUM_STR,
+	MC_CMD_SENSOR_IN_1V8_ENUM_STR,
+	MC_CMD_SENSOR_IN_2V5_ENUM_STR,
+	MC_CMD_SENSOR_IN_3V3_ENUM_STR,
+	MC_CMD_SENSOR_IN_12V0_ENUM_STR,
+	MC_CMD_SENSOR_IN_1V2A_ENUM_STR,
+	MC_CMD_SENSOR_IN_VREF_ENUM_STR,
+	MC_CMD_SENSOR_OUT_VAOE_ENUM_STR,
+	MC_CMD_SENSOR_AOE_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PSU_AOE_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PSU_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_FAN_0_ENUM_STR,
+	MC_CMD_SENSOR_FAN_1_ENUM_STR,
+	MC_CMD_SENSOR_FAN_2_ENUM_STR,
+	MC_CMD_SENSOR_FAN_3_ENUM_STR,
+	MC_CMD_SENSOR_FAN_4_ENUM_STR,
+	MC_CMD_SENSOR_IN_VAOE_ENUM_STR,
+	MC_CMD_SENSOR_OUT_IAOE_ENUM_STR,
+	MC_CMD_SENSOR_IN_IAOE_ENUM_STR,
+	MC_CMD_SENSOR_NIC_POWER_ENUM_STR,
+	MC_CMD_SENSOR_IN_0V9_ENUM_STR,
+	MC_CMD_SENSOR_IN_I0V9_ENUM_STR,
+	MC_CMD_SENSOR_IN_I1V2_ENUM_STR,
+	MC_CMD_SENSOR_IN_0V9_ADC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_2_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_VREG_INTERNAL_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_VREG_0V9_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_VREG_1V2_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_VPTAT_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_AMBIENT_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_AIRFLOW_ENUM_STR,
+	MC_CMD_SENSOR_VDD08D_VSS08D_CSR_ENUM_STR,
+	MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_HOTPOINT_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PHY_POWER_PORT0_ENUM_STR,
+	MC_CMD_SENSOR_PHY_POWER_PORT1_ENUM_STR,
+	MC_CMD_SENSOR_MUM_VCC_ENUM_STR,
+	MC_CMD_SENSOR_IN_0V9_A_ENUM_STR,
+	MC_CMD_SENSOR_IN_I0V9_A_ENUM_STR,
+	MC_CMD_SENSOR_VREG_0V9_A_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_IN_0V9_B_ENUM_STR,
+	MC_CMD_SENSOR_IN_I0V9_B_ENUM_STR,
+	MC_CMD_SENSOR_VREG_0V9_B_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_ENUM_STR,
+	MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_ENUM_STR,
+	MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC_ENUM_STR,
+	MC_CMD_SENSOR_SODIMM_VOUT_ENUM_STR,
+	MC_CMD_SENSOR_SODIMM_0_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_SODIMM_1_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_PHY0_VCC_ENUM_STR,
+	MC_CMD_SENSOR_PHY1_VCC_ENUM_STR,
+	MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_BOARD_FRONT_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_BOARD_BACK_TEMP_ENUM_STR,
+	MC_CMD_SENSOR_IN_I1V8_ENUM_STR,
+	MC_CMD_SENSOR_IN_I2V5_ENUM_STR,
+	MC_CMD_SENSOR_IN_I3V3_ENUM_STR,
+	MC_CMD_SENSOR_IN_I12V0_ENUM_STR,
+	MC_CMD_SENSOR_IN_1V3_ENUM_STR,
+	MC_CMD_SENSOR_IN_I1V3_ENUM_STR,
+};
+
+/* END MKCONFIG GENERATED MonitorStatDescriptionsBlock */
+
+					const char *
+efx_mon_stat_description(
+	__in				efx_nic_t *enp,
+	__in				efx_mon_stat_t id)
+{
+	_NOTE(ARGUNUSED(enp))
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS);
+	return (__mon_stat_description[id]);
+}
+
+#endif	/* EFSYS_OPT_NAMES */
+
+/* START MKCONFIG GENERATED MonitorMcdiMappingBlock 173eee0a5599996a */
 	__checkReturn			boolean_t
 efx_mon_mcdi_to_efx_stat(
 	__in				int mcdi_index,
@@ -683,20 +800,6 @@ efx_mon_get_stat_portmap(
 
 /* END MKCONFIG GENERATED MonitorStatisticPortsBlock */
 
-extern					const char *
-efx_mon_stat_name(
-	__in				efx_nic_t *enp,
-	__in				efx_mon_stat_t id)
-{
-	_NOTE(ARGUNUSED(enp))
-	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
-
-	EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS);
-	return (__mon_stat_name[id]);
-}
-
-#endif	/* EFSYS_OPT_NAMES */
-
 	__checkReturn			efx_rc_t
 efx_mon_stats_update(
 	__in				efx_nic_t *enp,
diff --git a/drivers/net/sfc/base/mc_driver_pcol_strs.h b/drivers/net/sfc/base/mc_driver_pcol_strs.h
new file mode 100644
index 000000000..73d633cbc
--- /dev/null
+++ b/drivers/net/sfc/base/mc_driver_pcol_strs.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright 2008-2018 Solarflare Communications Inc.
+ * All rights reserved.
+ */
+
+/*
+ * This file is automatically generated. DO NOT EDIT IT.
+ * To make changes, edit the .yml files under firmwaresrc doc/mcdi/ and
+ * rebuild this file with "make -C doc mcdiheaders".
+ *
+ * The version of this file has MCDI strings really used in the libefx.
+ */
+
+#ifndef _MC_DRIVER_PCOL_STRS_H
+#define _MC_DRIVER_PCOL_STRS_H
+
+#define MC_CMD_SENSOR_CONTROLLER_TEMP_ENUM_STR "Controller temperature: degC"
+#define MC_CMD_SENSOR_PHY_COMMON_TEMP_ENUM_STR "Phy common temperature: degC"
+#define MC_CMD_SENSOR_CONTROLLER_COOLING_ENUM_STR "Controller cooling: bool"
+#define MC_CMD_SENSOR_PHY0_TEMP_ENUM_STR "Phy 0 temperature: degC"
+#define MC_CMD_SENSOR_PHY0_COOLING_ENUM_STR "Phy 0 cooling: bool"
+#define MC_CMD_SENSOR_PHY1_TEMP_ENUM_STR "Phy 1 temperature: degC"
+#define MC_CMD_SENSOR_PHY1_COOLING_ENUM_STR "Phy 1 cooling: bool"
+#define MC_CMD_SENSOR_IN_1V0_ENUM_STR "1.0v power: mV"
+#define MC_CMD_SENSOR_IN_1V2_ENUM_STR "1.2v power: mV"
+#define MC_CMD_SENSOR_IN_1V8_ENUM_STR "1.8v power: mV"
+#define MC_CMD_SENSOR_IN_2V5_ENUM_STR "2.5v power: mV"
+#define MC_CMD_SENSOR_IN_3V3_ENUM_STR "3.3v power: mV"
+#define MC_CMD_SENSOR_IN_12V0_ENUM_STR "12v power: mV"
+#define MC_CMD_SENSOR_IN_1V2A_ENUM_STR "1.2v analogue power: mV"
+#define MC_CMD_SENSOR_IN_VREF_ENUM_STR "reference voltage: mV"
+#define MC_CMD_SENSOR_OUT_VAOE_ENUM_STR "AOE FPGA power: mV"
+#define MC_CMD_SENSOR_AOE_TEMP_ENUM_STR "AOE FPGA temperature: degC"
+#define MC_CMD_SENSOR_PSU_AOE_TEMP_ENUM_STR "AOE FPGA PSU temperature: degC"
+#define MC_CMD_SENSOR_PSU_TEMP_ENUM_STR "AOE PSU temperature: degC"
+#define MC_CMD_SENSOR_FAN_0_ENUM_STR "Fan 0 speed: RPM"
+#define MC_CMD_SENSOR_FAN_1_ENUM_STR "Fan 1 speed: RPM"
+#define MC_CMD_SENSOR_FAN_2_ENUM_STR "Fan 2 speed: RPM"
+#define MC_CMD_SENSOR_FAN_3_ENUM_STR "Fan 3 speed: RPM"
+#define MC_CMD_SENSOR_FAN_4_ENUM_STR "Fan 4 speed: RPM"
+#define MC_CMD_SENSOR_IN_VAOE_ENUM_STR "AOE FPGA input power: mV"
+#define MC_CMD_SENSOR_OUT_IAOE_ENUM_STR "AOE FPGA current: mA"
+#define MC_CMD_SENSOR_IN_IAOE_ENUM_STR "AOE FPGA input current: mA"
+#define MC_CMD_SENSOR_NIC_POWER_ENUM_STR "NIC power consumption: W"
+#define MC_CMD_SENSOR_IN_0V9_ENUM_STR "0.9v power voltage: mV"
+#define MC_CMD_SENSOR_IN_I0V9_ENUM_STR "0.9v power current: mA"
+#define MC_CMD_SENSOR_IN_I1V2_ENUM_STR "1.2v power current: mA"
+#define MC_CMD_SENSOR_PAGE0_NEXT_ENUM_STR "Not a sensor: reserved for the next page flag"
+#define MC_CMD_SENSOR_IN_0V9_ADC_ENUM_STR "0.9v power voltage (at ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_2_TEMP_ENUM_STR "Controller temperature 2: degC"
+#define MC_CMD_SENSOR_VREG_INTERNAL_TEMP_ENUM_STR "Voltage regulator internal temperature: degC"
+#define MC_CMD_SENSOR_VREG_0V9_TEMP_ENUM_STR "0.9V voltage regulator temperature: degC"
+#define MC_CMD_SENSOR_VREG_1V2_TEMP_ENUM_STR "1.2V voltage regulator temperature: degC"
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT_ENUM_STR "controller internal temperature sensor voltage (internal ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_ENUM_STR "controller internal temperature (internal ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC_ENUM_STR "controller internal temperature sensor voltage (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC_ENUM_STR "controller internal temperature (external ADC): degC"
+#define MC_CMD_SENSOR_AMBIENT_TEMP_ENUM_STR "ambient temperature: degC"
+#define MC_CMD_SENSOR_AIRFLOW_ENUM_STR "air flow: bool"
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_ENUM_STR "voltage between VSS08D and VSS08D at CSR: mV"
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC_ENUM_STR "voltage between VSS08D and VSS08D at CSR (external ADC): mV"
+#define MC_CMD_SENSOR_HOTPOINT_TEMP_ENUM_STR "Hotpoint temperature: degC"
+#define MC_CMD_SENSOR_PHY_POWER_PORT0_ENUM_STR "Port 0 PHY power switch over-current: bool"
+#define MC_CMD_SENSOR_PHY_POWER_PORT1_ENUM_STR "Port 1 PHY power switch over-current: bool"
+#define MC_CMD_SENSOR_MUM_VCC_ENUM_STR "Mop-up microcontroller reference voltage: mV"
+#define MC_CMD_SENSOR_IN_0V9_A_ENUM_STR "0.9v power phase A voltage: mV"
+#define MC_CMD_SENSOR_IN_I0V9_A_ENUM_STR "0.9v power phase A current: mA"
+#define MC_CMD_SENSOR_VREG_0V9_A_TEMP_ENUM_STR "0.9V voltage regulator phase A temperature: degC"
+#define MC_CMD_SENSOR_IN_0V9_B_ENUM_STR "0.9v power phase B voltage: mV"
+#define MC_CMD_SENSOR_IN_I0V9_B_ENUM_STR "0.9v power phase B current: mA"
+#define MC_CMD_SENSOR_VREG_0V9_B_TEMP_ENUM_STR "0.9V voltage regulator phase B temperature: degC"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_ENUM_STR "CCOM AVREG 1v2 supply (interval ADC): mV"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC_ENUM_STR "CCOM AVREG 1v2 supply (external ADC): mV"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_ENUM_STR "CCOM AVREG 1v8 supply (interval ADC): mV"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC_ENUM_STR "CCOM AVREG 1v8 supply (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_RTS_ENUM_STR "CCOM RTS temperature: degC"
+#define MC_CMD_SENSOR_PAGE1_NEXT_ENUM_STR "Not a sensor: reserved for the next page flag"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_ENUM_STR "controller internal temperature sensor voltage on master core (internal ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_ENUM_STR "controller internal temperature on master core (internal ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC_ENUM_STR "controller internal temperature sensor voltage on master core (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC_ENUM_STR "controller internal temperature on master core (external ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_ENUM_STR "controller internal temperature on slave core sensor voltage (internal ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_ENUM_STR "controller internal temperature on slave core (internal ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC_ENUM_STR "controller internal temperature on slave core sensor voltage (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC_ENUM_STR "controller internal temperature on slave core (external ADC): degC"
+#define MC_CMD_SENSOR_SODIMM_VOUT_ENUM_STR "Voltage supplied to the SODIMMs from their power supply: mV"
+#define MC_CMD_SENSOR_SODIMM_0_TEMP_ENUM_STR "Temperature of SODIMM 0 (if installed): degC"
+#define MC_CMD_SENSOR_SODIMM_1_TEMP_ENUM_STR "Temperature of SODIMM 1 (if installed): degC"
+#define MC_CMD_SENSOR_PHY0_VCC_ENUM_STR "Voltage supplied to the QSFP #0 from their power supply: mV"
+#define MC_CMD_SENSOR_PHY1_VCC_ENUM_STR "Voltage supplied to the QSFP #1 from their power supply: mV"
+#define MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP_ENUM_STR "Controller die temperature (TDIODE): degC"
+#define MC_CMD_SENSOR_BOARD_FRONT_TEMP_ENUM_STR "Board temperature (front): degC"
+#define MC_CMD_SENSOR_BOARD_BACK_TEMP_ENUM_STR "Board temperature (back): degC"
+#define MC_CMD_SENSOR_IN_I1V8_ENUM_STR "1.8v power current: mA"
+#define MC_CMD_SENSOR_IN_I2V5_ENUM_STR "2.5v power current: mA"
+#define MC_CMD_SENSOR_IN_I3V3_ENUM_STR "3.3v power current: mA"
+#define MC_CMD_SENSOR_IN_I12V0_ENUM_STR "12v power current: mA"
+#define MC_CMD_SENSOR_IN_1V3_ENUM_STR "1.3v power: mV"
+#define MC_CMD_SENSOR_IN_I1V3_ENUM_STR "1.3v power current: mA"
+
+#endif /* _MC_DRIVER_PCOL_STRS_H */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 16/37] net/sfc/base: check size of memory to read sensors data to
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (14 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 15/37] net/sfc/base: add generated description of sensors Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits Andrew Rybchenko
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, stable

From: Martin Harvey <mharvey@solarflare.com>

Size of provided memory should be consistent with specified size.

Fixes: dfb3b1ce15f6 ("net/sfc/base: import monitors access via MCDI")
Cc: stable@dpdk.org

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/mcdi_mon.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 93e6b1e35..68bbc575d 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -194,6 +194,12 @@ efx_mcdi_read_sensors(
 	uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN,
 			    MC_CMD_READ_SENSORS_EXT_OUT_LEN)];
 	uint32_t addr_lo, addr_hi;
+	efx_rc_t rc;
+
+	if (EFSYS_MEM_SIZE(esmp) < size) {
+		rc = EINVAL;
+		goto fail1;
+	}
 
 	req.emr_cmd = MC_CMD_READ_SENSORS;
 	req.emr_in_buf = payload;
@@ -211,6 +217,11 @@ efx_mcdi_read_sensors(
 	efx_mcdi_execute(enp, &req);
 
 	return (req.emr_rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
 }
 
 static	__checkReturn	efx_rc_t
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (15 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 16/37] net/sfc/base: check size of memory to read sensors data to Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 18/37] net/sfc/base: add buffer editing functions to boot config Andrew Rybchenko
                   ` (20 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey

From: Martin Harvey <mharvey@solarflare.com>

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h      |  12 +++
 drivers/net/sfc/base/efx_impl.h |   2 +
 drivers/net/sfc/base/efx_mon.c  |  17 +++-
 drivers/net/sfc/base/mcdi_mon.c | 171 ++++++++++++++++++++++++++++++++
 drivers/net/sfc/base/mcdi_mon.h |   5 +
 5 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index dae90bd6e..099f9df67 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -774,6 +774,13 @@ typedef struct efx_mon_stat_value_s {
 	efx_mon_stat_unit_t	emsv_unit;
 } efx_mon_stat_value_t;
 
+typedef struct efx_mon_limit_value_s {
+	uint16_t			emlv_warning_min;
+	uint16_t			emlv_warning_max;
+	uint16_t			emlv_fatal_min;
+	uint16_t			emlv_fatal_max;
+} efx_mon_stat_limits_t;
+
 typedef enum efx_mon_stat_portmask_e {
 	EFX_MON_STAT_PORTMAP_NONE = 0,
 	EFX_MON_STAT_PORTMAP_PORT0 = 1,
@@ -819,6 +826,11 @@ efx_mon_stats_update(
 	__in				efsys_mem_t *esmp,
 	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_value_t *values);
 
+extern	__checkReturn			efx_rc_t
+efx_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values);
+
 #endif	/* EFSYS_OPT_MON_STATS */
 
 extern		void
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 637e31e0c..0764df5de 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -317,6 +317,8 @@ typedef struct efx_mon_ops_s {
 #if EFSYS_OPT_MON_STATS
 	efx_rc_t	(*emo_stats_update)(efx_nic_t *, efsys_mem_t *,
 					    efx_mon_stat_value_t *);
+	efx_rc_t	(*emo_limits_update)(efx_nic_t *,
+					     efx_mon_stat_limits_t *);
 #endif	/* EFSYS_OPT_MON_STATS */
 } efx_mon_ops_t;
 
diff --git a/drivers/net/sfc/base/efx_mon.c b/drivers/net/sfc/base/efx_mon.c
index 91fa16ca0..f28775d04 100644
--- a/drivers/net/sfc/base/efx_mon.c
+++ b/drivers/net/sfc/base/efx_mon.c
@@ -38,7 +38,8 @@ efx_mon_name(
 #if EFSYS_OPT_MON_MCDI
 static const efx_mon_ops_t	__efx_mon_mcdi_ops = {
 #if EFSYS_OPT_MON_STATS
-	mcdi_mon_stats_update		/* emo_stats_update */
+	mcdi_mon_stats_update,		/* emo_stats_update */
+	mcdi_mon_limits_update,		/* emo_limits_update */
 #endif	/* EFSYS_OPT_MON_STATS */
 };
 #endif
@@ -815,6 +816,20 @@ efx_mon_stats_update(
 	return (emop->emo_stats_update(enp, esmp, values));
 }
 
+	__checkReturn			efx_rc_t
+efx_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values)
+{
+	efx_mon_t *emp = &(enp->en_mon);
+	const efx_mon_ops_t *emop = emp->em_emop;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON);
+
+	return (emop->emo_limits_update(enp, values));
+}
+
 #endif	/* EFSYS_OPT_MON_STATS */
 
 		void
diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 68bbc575d..0e860168a 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -334,6 +334,87 @@ efx_mcdi_sensor_info(
 	return (rc);
 }
 
+static	__checkReturn		efx_rc_t
+efx_mcdi_sensor_info_page(
+	__in			efx_nic_t *enp,
+	__in			uint32_t page,
+	__out			uint32_t *mask_part,
+	__out_ecount((sizeof (*mask_part) * 8) - 1)
+				efx_mon_stat_limits_t *limits)
+{
+	efx_mcdi_req_t req;
+	uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+		MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+	efx_rc_t rc;
+	uint32_t mask_copy;
+	efx_dword_t *maskp;
+	efx_qword_t *limit_info;
+
+	EFSYS_ASSERT(mask_part != NULL);
+	EFSYS_ASSERT(limits != NULL);
+
+	memset(limits, 0,
+	    ((sizeof (*mask_part) * 8) - 1) * sizeof (efx_mon_stat_limits_t));
+
+	(void) memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_SENSOR_INFO;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+	MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page);
+
+	efx_mcdi_execute(enp, &req);
+
+	rc = req.emr_rc;
+
+	if (rc != 0)
+		goto fail1;
+
+	EFSYS_ASSERT(sizeof (*limit_info) ==
+	    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN);
+	maskp = MCDI_OUT2(req, efx_dword_t, SENSOR_INFO_OUT_MASK);
+	limit_info = (efx_qword_t *)(maskp + 1);
+
+	*mask_part = maskp->ed_u32[0];
+	mask_copy = *mask_part;
+
+	/* Copy an entry for all but the highest bit set. */
+	while (mask_copy) {
+
+		if (mask_copy == (1U << MC_CMD_SENSOR_PAGE0_NEXT)) {
+			/* Only next page bit set. */
+			mask_copy = 0;
+		} else {
+			/* Clear lowest bit */
+			mask_copy = mask_copy & ~(mask_copy ^ (mask_copy - 1));
+			/* And copy out limit entry into buffer */
+			limits->emlv_warning_min = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1);
+
+			limits->emlv_warning_max = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1);
+
+			limits->emlv_fatal_min = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2);
+
+			limits->emlv_fatal_max = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2);
+
+			limits++;
+			limit_info++;
+		}
+	}
+
+	return (rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
 	__checkReturn			efx_rc_t
 mcdi_mon_stats_update(
 	__in				efx_nic_t *enp,
@@ -356,6 +437,96 @@ mcdi_mon_stats_update(
 
 	return (0);
 
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+static		void
+lowest_set_bit(
+	__in	uint32_t input_mask,
+	__out	uint32_t *lowest_bit_mask,
+	__out	uint32_t *lowest_bit_num
+)
+{
+	uint32_t x;
+	uint32_t set_bit, bit_index;
+
+	x = (input_mask ^ (input_mask - 1));
+	set_bit = (x + 1) >> 1;
+	if (!set_bit)
+		set_bit = (1U << 31U);
+
+	bit_index = 0;
+	if (set_bit & 0xFFFF0000)
+		bit_index += 16;
+	if (set_bit & 0xFF00FF00)
+		bit_index += 8;
+	if (set_bit & 0xF0F0F0F0)
+		bit_index += 4;
+	if (set_bit & 0xCCCCCCCC)
+		bit_index += 2;
+	if (set_bit & 0xAAAAAAAA)
+		bit_index += 1;
+
+	*lowest_bit_mask = set_bit;
+	*lowest_bit_num = bit_index;
+}
+
+	__checkReturn			efx_rc_t
+mcdi_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values)
+{
+	efx_rc_t rc;
+	uint32_t page;
+	uint32_t page_mask;
+	uint32_t limit_index;
+	efx_mon_stat_limits_t limits[sizeof (page_mask) * 8];
+	efx_mon_stat_t stat;
+
+	page = 0;
+	page--;
+	do {
+		page++;
+
+		rc = efx_mcdi_sensor_info_page(enp, page, &page_mask, limits);
+		if (rc != 0)
+			goto fail1;
+
+		limit_index = 0;
+		while (page_mask) {
+			uint32_t set_bit;
+			uint32_t page_index;
+			uint32_t mcdi_index;
+
+			if (page_mask == (1U << MC_CMD_SENSOR_PAGE0_NEXT))
+				break;
+
+			lowest_set_bit(page_mask, &set_bit, &page_index);
+			page_mask = page_mask & ~set_bit;
+
+			mcdi_index =
+			    page_index + (sizeof (page_mask) * 8 * page);
+
+			/*
+			 * This can fail if MCDI reports newer stats than the
+			 * drivers understand, or the bit is the next page bit.
+			 *
+			 * Driver needs to be tolerant of this.
+			 */
+			if (!efx_mon_mcdi_to_efx_stat(mcdi_index, &stat))
+				continue;
+
+			values[stat] = limits[limit_index];
+			limit_index++;
+		}
+
+	} while (page_mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT));
+
+	return (rc);
+
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
diff --git a/drivers/net/sfc/base/mcdi_mon.h b/drivers/net/sfc/base/mcdi_mon.h
index 5aa6a6a27..5eba09018 100644
--- a/drivers/net/sfc/base/mcdi_mon.h
+++ b/drivers/net/sfc/base/mcdi_mon.h
@@ -39,6 +39,11 @@ mcdi_mon_stats_update(
 	__in				efsys_mem_t *esmp,
 	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_value_t *values);
 
+extern	__checkReturn			efx_rc_t
+mcdi_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values);
+
 #endif	/* EFSYS_OPT_MON_STATS */
 
 #endif /* EFSYS_OPT_MON_MCDI */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 18/37] net/sfc/base: add buffer editing functions to boot config
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (16 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 19/37] net/sfc/base: add accessor for default port mode Andrew Rybchenko
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Richard Houldsworth

From: Richard Houldsworth <rhouldsworth@solarflare.com>

Functions to process the DHCP option list format used by the expansion
ROM config buffers, to support extracting and updating of individual
options.
The initial use case is the driver presenting the global and per-PF
options as separate items, with the driver implementing the
synchronization of global options across the configuration buffers
for all PFs.

Signed-off-by: Richard Houldsworth <rhouldsworth@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h         |  81 ++++
 drivers/net/sfc/base/efx_annote.h  |   1 +
 drivers/net/sfc/base/efx_bootcfg.c | 641 ++++++++++++++++++++++++++---
 3 files changed, 672 insertions(+), 51 deletions(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 099f9df67..3c3227739 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1662,6 +1662,87 @@ efx_bootcfg_write(
 	__in_bcount(size)	uint8_t *data,
 	__in			size_t size);
 
+
+/*
+ * Processing routines for buffers arranged in the DHCP/BOOTP option format
+ * (see https://tools.ietf.org/html/rfc1533)
+ *
+ * Summarising the format: the buffer is a sequence of options. All options
+ * begin with a tag octet, which uniquely identifies the option.  Fixed-
+ * length options without data consist of only a tag octet.  Only options PAD
+ * (0) and END (255) are fixed length.  All other options are variable-length
+ * with a length octet following the tag octet.  The value of the length
+ * octet does not include the two octets specifying the tag and length.  The
+ * length octet is followed by "length" octets of data.
+ *
+ * Option data may be a sequence of sub-options in the same format. The data
+ * content of the encapsulating option is one or more encapsulated sub-options,
+ * with no terminating END tag is required.
+ *
+ * To be valid, the top-level sequence of options should be terminated by an
+ * END tag. The buffer should be padded with the PAD byte.
+ *
+ * When stored to NVRAM, the DHCP option format buffer is preceded by a
+ * checksum octet. The full buffer (including after the END tag) contributes
+ * to the checksum, hence the need to fill the buffer to the end with PAD.
+ */
+
+#define	EFX_DHCP_END ((uint8_t)0xff)
+#define	EFX_DHCP_PAD ((uint8_t)0)
+
+#define	EFX_DHCP_ENCAP_OPT(encapsulator, encapsulated) \
+  (uint16_t)(((encapsulator) << 8) | (encapsulated))
+
+extern	__checkReturn		uint8_t
+efx_dhcp_csum(
+	__in_bcount(size)	uint8_t const *data,
+	__in			size_t size);
+
+extern	__checkReturn		efx_rc_t
+efx_dhcp_verify(
+	__in_bcount(size)	uint8_t const *data,
+	__in			size_t size,
+	__out_opt		size_t *usedp);
+
+extern	__checkReturn	efx_rc_t
+efx_dhcp_find_tag(
+	__in_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt,
+	__deref_out			uint8_t **valuepp,
+	__out				size_t *value_lengthp);
+
+extern	__checkReturn	efx_rc_t
+efx_dhcp_find_end(
+	__in_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__deref_out			uint8_t **endpp);
+
+
+extern	__checkReturn	efx_rc_t
+efx_dhcp_delete_tag(
+	__inout_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt);
+
+extern	__checkReturn	efx_rc_t
+efx_dhcp_add_tag(
+	__inout_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt,
+	__in_bcount_opt(value_length)	uint8_t *valuep,
+	__in				size_t value_length);
+
+extern	__checkReturn	efx_rc_t
+efx_dhcp_update_tag(
+	__inout_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt,
+	__in				uint8_t *value_locationp,
+	__in_bcount_opt(value_length)	uint8_t *valuep,
+	__in				size_t value_length);
+
+
 #endif	/* EFSYS_OPT_BOOTCFG */
 
 #if EFSYS_OPT_IMAGE_LAYOUT
diff --git a/drivers/net/sfc/base/efx_annote.h b/drivers/net/sfc/base/efx_annote.h
index 603260e22..671aaed3b 100644
--- a/drivers/net/sfc/base/efx_annote.h
+++ b/drivers/net/sfc/base/efx_annote.h
@@ -39,6 +39,7 @@
 #define	__out_bcount_part_opt(_n, _l)
 
 #define	__deref_out
+#define	__deref_inout
 
 #define	__inout
 #define	__inout_opt
diff --git a/drivers/net/sfc/base/efx_bootcfg.c b/drivers/net/sfc/base/efx_bootcfg.c
index 715e18e8c..3b0401e89 100644
--- a/drivers/net/sfc/base/efx_bootcfg.c
+++ b/drivers/net/sfc/base/efx_bootcfg.c
@@ -19,8 +19,33 @@
 #define	BOOTCFG_PER_PF   0x800
 #define	BOOTCFG_PF_COUNT 16
 
-#define	DHCP_END ((uint8_t)0xff)
-#define	DHCP_PAD ((uint8_t)0)
+#define	DHCP_OPT_HAS_VALUE(opt) \
+	(((opt) > EFX_DHCP_PAD) && ((opt) < EFX_DHCP_END))
+
+#define	DHCP_MAX_VALUE 255
+
+#define	DHCP_ENCAPSULATOR(encap_opt) ((encap_opt) >> 8)
+#define	DHCP_ENCAPSULATED(encap_opt) ((encap_opt) & 0xff)
+#define	DHCP_IS_ENCAP_OPT(opt) DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATOR(opt))
+
+typedef struct efx_dhcp_tag_hdr_s {
+	uint8_t		tag;
+	uint8_t		length;
+} efx_dhcp_tag_hdr_t;
+
+/*
+ * Length calculations for tags with value field. PAD and END
+ * have a fixed length of 1, with no length or value field.
+ */
+#define	DHCP_FULL_TAG_LENGTH(hdr) \
+	(sizeof (efx_dhcp_tag_hdr_t) + (hdr)->length)
+
+#define	DHCP_NEXT_TAG(hdr) \
+	((efx_dhcp_tag_hdr_t *)(((uint8_t *)(hdr)) + \
+	DHCP_FULL_TAG_LENGTH((hdr))))
+
+#define	DHCP_CALC_TAG_LENGTH(payload_len) \
+	((payload_len) + sizeof (efx_dhcp_tag_hdr_t))
 
 
 /* Report the layout of bootcfg sectors in NVRAM partition. */
@@ -110,14 +135,11 @@ efx_bootcfg_sector_info(
 }
 
 
-static	__checkReturn		uint8_t
-efx_bootcfg_csum(
-	__in			efx_nic_t *enp,
+	__checkReturn		uint8_t
+efx_dhcp_csum(
 	__in_bcount(size)	uint8_t const *data,
 	__in			size_t size)
 {
-	_NOTE(ARGUNUSED(enp))
-
 	unsigned int pos;
 	uint8_t checksum = 0;
 
@@ -126,9 +148,8 @@ efx_bootcfg_csum(
 	return (checksum);
 }
 
-static	__checkReturn		efx_rc_t
-efx_bootcfg_verify(
-	__in			efx_nic_t *enp,
+	__checkReturn		efx_rc_t
+efx_dhcp_verify(
 	__in_bcount(size)	uint8_t const *data,
 	__in			size_t size,
 	__out_opt		size_t *usedp)
@@ -144,12 +165,12 @@ efx_bootcfg_verify(
 
 		/* Consume tag */
 		tag = data[offset];
-		if (tag == DHCP_END) {
+		if (tag == EFX_DHCP_END) {
 			offset++;
 			used = offset;
 			break;
 		}
-		if (tag == DHCP_PAD) {
+		if (tag == EFX_DHCP_PAD) {
 			offset++;
 			continue;
 		}
@@ -171,8 +192,8 @@ efx_bootcfg_verify(
 		used = offset;
 	}
 
-	/* Checksum the entire sector, including bytes after any DHCP_END */
-	if (efx_bootcfg_csum(enp, data, size) != 0) {
+	/* Checksum the entire sector, including bytes after any EFX_DHCP_END */
+	if (efx_dhcp_csum(data, size) != 0) {
 		rc = EINVAL;
 		goto fail3;
 	}
@@ -192,6 +213,516 @@ efx_bootcfg_verify(
 	return (rc);
 }
 
+/*
+ * Walk the entire tag set looking for option. The sought option may be
+ * encapsulated. ENOENT indicates the walk completed without finding the
+ * option. If we run out of buffer during the walk the function will return
+ * ENOSPC.
+ */
+static	efx_rc_t
+efx_dhcp_walk_tags(
+	__deref_inout	uint8_t **tagpp,
+	__inout		size_t *buffer_sizep,
+	__in		uint16_t opt)
+{
+	efx_rc_t rc = 0;
+	boolean_t is_encap = B_FALSE;
+
+	if (DHCP_IS_ENCAP_OPT(opt)) {
+		/*
+		 * Look for the encapsulator and, if found, limit ourselves
+		 * to its payload. If it's not found then the entire tag
+		 * cannot be found, so the encapsulated opt search is
+		 * skipped.
+		 */
+		rc = efx_dhcp_walk_tags(tagpp, buffer_sizep,
+		    DHCP_ENCAPSULATOR(opt));
+		if (rc == 0) {
+			*buffer_sizep = ((efx_dhcp_tag_hdr_t *)*tagpp)->length;
+			(*tagpp) += sizeof (efx_dhcp_tag_hdr_t);
+		}
+		opt = DHCP_ENCAPSULATED(opt);
+		is_encap = B_TRUE;
+	}
+
+	EFSYS_ASSERT(!DHCP_IS_ENCAP_OPT(opt));
+
+	while (rc == 0) {
+		size_t size;
+
+		if (*buffer_sizep == 0) {
+			rc = ENOSPC;
+			goto fail1;
+		}
+
+		if (DHCP_ENCAPSULATED(**tagpp) == opt)
+			break;
+
+		if ((**tagpp) == EFX_DHCP_END) {
+			rc = ENOENT;
+			break;
+		} else if ((**tagpp) == EFX_DHCP_PAD) {
+			size = 1;
+		} else {
+			if (*buffer_sizep < sizeof (efx_dhcp_tag_hdr_t)) {
+				rc = ENOSPC;
+				goto fail2;
+			}
+
+			size =
+			    DHCP_FULL_TAG_LENGTH((efx_dhcp_tag_hdr_t *)*tagpp);
+		}
+
+		if (size > *buffer_sizep) {
+			rc = ENOSPC;
+			goto fail3;
+		}
+
+		(*tagpp) += size;
+		(*buffer_sizep) -= size;
+
+		if ((*buffer_sizep == 0) && is_encap) {
+			/* Search within encapulator tag finished */
+			rc = ENOENT;
+			break;
+		}
+	}
+
+	/*
+	 * Returns 0 if found otherwise ENOENT indicating search finished
+	 * correctly
+	 */
+	return (rc);
+
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+/*
+ * Locate value buffer for option in the given buffer.
+ * Returns 0 if found, ENOENT indicating search finished
+ * correctly, otherwise search failed before completion.
+ */
+	__checkReturn	efx_rc_t
+efx_dhcp_find_tag(
+	__in_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt,
+	__deref_out			uint8_t **valuepp,
+	__out				size_t *value_lengthp)
+{
+	efx_rc_t rc;
+	uint8_t *tagp = bufferp;
+	size_t len = buffer_length;
+
+	rc = efx_dhcp_walk_tags(&tagp, &len, opt);
+	if (rc == 0) {
+		efx_dhcp_tag_hdr_t *hdrp;
+
+		hdrp = (efx_dhcp_tag_hdr_t *)tagp;
+		*valuepp = (uint8_t *)(&hdrp[1]);
+		*value_lengthp = hdrp->length;
+	} else if (rc != ENOENT) {
+		goto fail1;
+	}
+
+	return (rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+/*
+ * Locate the end tag in the given buffer.
+ * Returns 0 if found, ENOENT indicating search finished
+ * correctly but end tag was not found; otherwise search
+ * failed before completion.
+ */
+	__checkReturn	efx_rc_t
+efx_dhcp_find_end(
+	__in_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__deref_out			uint8_t **endpp)
+{
+	efx_rc_t rc;
+	uint8_t *endp = bufferp;
+	size_t len = buffer_length;
+
+	rc = efx_dhcp_walk_tags(&endp, &len, EFX_DHCP_END);
+	if (rc == 0)
+		*endpp = endp;
+	else if (rc != ENOENT)
+		goto fail1;
+
+	return (rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+
+/*
+ * Delete the given tag from anywhere in the buffer. Copes with
+ * encapsulated tags, and updates or deletes the encapsulating opt as
+ * necessary.
+ */
+	__checkReturn	efx_rc_t
+efx_dhcp_delete_tag(
+	__inout_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt)
+{
+	efx_rc_t rc;
+	efx_dhcp_tag_hdr_t *hdrp;
+	size_t len;
+	uint8_t *startp;
+	uint8_t *endp;
+
+	len = buffer_length;
+	startp = bufferp;
+
+	if (!DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATED(opt))) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	rc = efx_dhcp_walk_tags(&startp, &len, opt);
+	if (rc != 0)
+		goto fail1;
+
+	hdrp = (efx_dhcp_tag_hdr_t *)startp;
+
+	if (DHCP_IS_ENCAP_OPT(opt)) {
+		uint8_t tag_length = DHCP_FULL_TAG_LENGTH(hdrp);
+		uint8_t *encapp = bufferp;
+		efx_dhcp_tag_hdr_t *encap_hdrp;
+
+		len = buffer_length;
+		rc = efx_dhcp_walk_tags(&encapp, &len,
+		    DHCP_ENCAPSULATOR(opt));
+		if (rc != 0)
+			goto fail2;
+
+		encap_hdrp = (efx_dhcp_tag_hdr_t *)encapp;
+		if (encap_hdrp->length > tag_length) {
+			encap_hdrp->length = (uint8_t)(
+			    (size_t)encap_hdrp->length - tag_length);
+		} else {
+			/* delete the encapsulating tag */
+			hdrp = encap_hdrp;
+		}
+	}
+
+	startp = (uint8_t *)hdrp;
+	endp = (uint8_t *)DHCP_NEXT_TAG(hdrp);
+
+	if (startp < bufferp) {
+		rc = EINVAL;
+		goto fail3;
+	}
+
+	if (endp > &bufferp[buffer_length]) {
+		rc = EINVAL;
+		goto fail4;
+	}
+
+	memmove(startp, endp,
+		buffer_length - (endp - bufferp));
+
+	return (0);
+
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+/*
+ * Write the tag header into write_pointp and optionally copies the payload
+ * into the space following.
+ */
+static	void
+efx_dhcp_write_tag(
+	__in		uint8_t *write_pointp,
+	__in		uint16_t opt,
+	__in_bcount_opt(value_length)
+			uint8_t *valuep,
+	__in		size_t value_length)
+{
+	efx_dhcp_tag_hdr_t *hdrp = (efx_dhcp_tag_hdr_t *)write_pointp;
+	hdrp->tag = DHCP_ENCAPSULATED(opt);
+	hdrp->length = (uint8_t)value_length;
+	if ((value_length > 0) && (valuep != NULL))
+		memcpy(&hdrp[1], valuep, value_length);
+}
+
+/*
+ * Add the given tag to the end of the buffer. Copes with creating an
+ * encapsulated tag, and updates or creates the encapsulating opt as
+ * necessary.
+ */
+	__checkReturn	efx_rc_t
+efx_dhcp_add_tag(
+	__inout_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt,
+	__in_bcount_opt(value_length)	uint8_t *valuep,
+	__in				size_t value_length)
+{
+	efx_rc_t rc;
+	efx_dhcp_tag_hdr_t *encap_hdrp = NULL;
+	uint8_t *insert_pointp = NULL;
+	uint8_t *endp;
+	size_t available_space;
+	size_t added_length;
+	size_t search_size;
+	uint8_t *searchp;
+
+	if (!DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATED(opt))) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if (value_length > DHCP_MAX_VALUE) {
+		rc = EINVAL;
+		goto fail2;
+	}
+
+	if ((value_length > 0) && (valuep == NULL)) {
+		rc = EINVAL;
+		goto fail3;
+	}
+
+	endp = bufferp;
+	available_space = buffer_length;
+	rc = efx_dhcp_walk_tags(&endp, &available_space, EFX_DHCP_END);
+	if (rc != 0)
+		goto fail4;
+
+	searchp = bufferp;
+	search_size = buffer_length;
+	if (DHCP_IS_ENCAP_OPT(opt)) {
+		rc = efx_dhcp_walk_tags(&searchp, &search_size,
+		    DHCP_ENCAPSULATOR(opt));
+		if (rc == 0) {
+			encap_hdrp = (efx_dhcp_tag_hdr_t *)searchp;
+
+			/* Check encapsulated tag is not present */
+			search_size = encap_hdrp->length;
+			rc = efx_dhcp_walk_tags(&searchp, &search_size,
+			    opt);
+			if (rc != ENOENT) {
+				rc = EINVAL;
+				goto fail5;
+			}
+
+			/* Check encapsulator will not overflow */
+			if (((size_t)encap_hdrp->length +
+			    DHCP_CALC_TAG_LENGTH(value_length)) >
+			    DHCP_MAX_VALUE) {
+				rc = E2BIG;
+				goto fail6;
+			}
+
+			/* Insert at start of existing encapsulator */
+			insert_pointp = (uint8_t *)&encap_hdrp[1];
+			opt = DHCP_ENCAPSULATED(opt);
+		} else if (rc == ENOENT) {
+			encap_hdrp = NULL;
+		} else {
+			goto fail7;
+		}
+	} else {
+		/* Check unencapsulated tag is not present */
+		rc = efx_dhcp_walk_tags(&searchp, &search_size,
+		    opt);
+		if (rc != ENOENT) {
+			rc = EINVAL;
+			goto fail8;
+		}
+	}
+
+	if (insert_pointp == NULL) {
+		/* Insert at end of existing tags */
+		insert_pointp = endp;
+	}
+
+	/* Includes the new encapsulator tag hdr if required */
+	added_length = DHCP_CALC_TAG_LENGTH(value_length) +
+	    (DHCP_IS_ENCAP_OPT(opt) ? sizeof (efx_dhcp_tag_hdr_t) : 0);
+
+	if (available_space <= added_length) {
+		rc = ENOMEM;
+		goto fail9;
+	}
+
+	memmove(insert_pointp + added_length, insert_pointp,
+	    available_space - added_length);
+
+	if (DHCP_IS_ENCAP_OPT(opt)) {
+		/* Create new encapsulator header */
+		added_length -= sizeof (efx_dhcp_tag_hdr_t);
+		efx_dhcp_write_tag(insert_pointp,
+		    DHCP_ENCAPSULATOR(opt), NULL, added_length);
+		insert_pointp += sizeof (efx_dhcp_tag_hdr_t);
+	} else if (encap_hdrp)
+		/* Modify existing encapsulator header */
+		encap_hdrp->length +=
+		    ((uint8_t)DHCP_CALC_TAG_LENGTH(value_length));
+
+	efx_dhcp_write_tag(insert_pointp, opt, valuep, value_length);
+
+	return (0);
+
+fail9:
+	EFSYS_PROBE(fail9);
+fail8:
+	EFSYS_PROBE(fail8);
+fail7:
+	EFSYS_PROBE(fail7);
+fail6:
+	EFSYS_PROBE(fail6);
+fail5:
+	EFSYS_PROBE(fail5);
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+/*
+ * Update an existing tag to the new value. Copes with encapsulated
+ * tags, and updates the encapsulating opt as necessary.
+ */
+	__checkReturn	efx_rc_t
+efx_dhcp_update_tag(
+	__inout_bcount(buffer_length)	uint8_t *bufferp,
+	__in				size_t buffer_length,
+	__in				uint16_t opt,
+	__in				uint8_t *value_locationp,
+	__in_bcount_opt(value_length)	uint8_t *valuep,
+	__in				size_t value_length)
+{
+	efx_rc_t rc;
+	uint8_t *write_pointp = value_locationp - sizeof (efx_dhcp_tag_hdr_t);
+	efx_dhcp_tag_hdr_t *hdrp = (efx_dhcp_tag_hdr_t *)write_pointp;
+	efx_dhcp_tag_hdr_t *encap_hdrp = NULL;
+	size_t old_length;
+
+	if (!DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATED(opt))) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if (value_length > DHCP_MAX_VALUE) {
+		rc = EINVAL;
+		goto fail2;
+	}
+
+	if ((value_length > 0) && (valuep == NULL)) {
+		rc = EINVAL;
+		goto fail3;
+	}
+
+	old_length = hdrp->length;
+
+	if (old_length < value_length) {
+		uint8_t *endp = bufferp;
+		size_t available_space = buffer_length;
+
+		rc = efx_dhcp_walk_tags(&endp, &available_space,
+		    EFX_DHCP_END);
+		if (rc != 0)
+			goto fail4;
+
+		if (available_space < (value_length - old_length)) {
+			rc = EINVAL;
+			goto fail5;
+		}
+	}
+
+	if (DHCP_IS_ENCAP_OPT(opt)) {
+		uint8_t *encapp = bufferp;
+		size_t following_encap = buffer_length;
+		size_t new_length;
+
+		rc = efx_dhcp_walk_tags(&encapp, &following_encap,
+		    DHCP_ENCAPSULATOR(opt));
+		if (rc != 0)
+			goto fail6;
+
+		encap_hdrp = (efx_dhcp_tag_hdr_t *)encapp;
+
+		new_length = ((size_t)encap_hdrp->length +
+		    value_length - old_length);
+		/* Check encapsulator will not overflow */
+		if (new_length > DHCP_MAX_VALUE) {
+			rc = E2BIG;
+			goto fail7;
+		}
+
+		encap_hdrp->length = (uint8_t)new_length;
+	}
+
+	/*
+	 * Move the following data up/down to accomodate the new payload
+	 * length.
+	 */
+	if (old_length != value_length) {
+		uint8_t *destp = (uint8_t *)DHCP_NEXT_TAG(hdrp) +
+		    value_length - old_length;
+		size_t count = &bufferp[buffer_length] -
+		    (uint8_t *)DHCP_NEXT_TAG(hdrp);
+
+		memmove(destp, DHCP_NEXT_TAG(hdrp), count);
+	}
+
+	EFSYS_ASSERT(hdrp->tag == DHCP_ENCAPSULATED(opt));
+	efx_dhcp_write_tag(write_pointp, opt, valuep, value_length);
+
+	return (0);
+
+fail7:
+	EFSYS_PROBE(fail7);
+fail6:
+	EFSYS_PROBE(fail6);
+fail5:
+	EFSYS_PROBE(fail5);
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+
 /*
  * Copy bootcfg sector data to a target buffer which may differ in size.
  * Optionally corrects format errors in source buffer.
@@ -206,17 +737,19 @@ efx_bootcfg_copy_sector(
 	__in			size_t data_size,
 	__in			boolean_t handle_format_errors)
 {
+	_NOTE(ARGUNUSED(enp))
+
 	size_t used_bytes;
 	efx_rc_t rc;
 
-	/* Minimum buffer is checksum byte and DHCP_END terminator */
+	/* Minimum buffer is checksum byte and EFX_DHCP_END terminator */
 	if (data_size < 2) {
 		rc = ENOSPC;
 		goto fail1;
 	}
 
 	/* Verify that the area is correctly formatted and checksummed */
-	rc = efx_bootcfg_verify(enp, sector, sector_length,
+	rc = efx_dhcp_verify(sector, sector_length,
 				    &used_bytes);
 
 	if (!handle_format_errors) {
@@ -224,8 +757,8 @@ efx_bootcfg_copy_sector(
 			goto fail2;
 
 		if ((used_bytes < 2) ||
-		    (sector[used_bytes - 1] != DHCP_END)) {
-			/* Block too short, or DHCP_END missing */
+		    (sector[used_bytes - 1] != EFX_DHCP_END)) {
+			/* Block too short, or EFX_DHCP_END missing */
 			rc = ENOENT;
 			goto fail3;
 		}
@@ -234,24 +767,24 @@ efx_bootcfg_copy_sector(
 	/* Synthesize empty format on verification failure */
 	if (rc != 0 || used_bytes == 0) {
 		sector[0] = 0;
-		sector[1] = DHCP_END;
+		sector[1] = EFX_DHCP_END;
 		used_bytes = 2;
 	}
-	EFSYS_ASSERT(used_bytes >= 2);	/* checksum and DHCP_END */
+	EFSYS_ASSERT(used_bytes >= 2);	/* checksum and EFX_DHCP_END */
 	EFSYS_ASSERT(used_bytes <= sector_length);
 	EFSYS_ASSERT(sector_length >= 2);
 
 	/*
-	 * Legacy bootcfg sectors don't terminate with a DHCP_END character.
-	 * Modify the returned payload so it does.
+	 * Legacy bootcfg sectors don't terminate with an EFX_DHCP_END
+	 * character. Modify the returned payload so it does.
 	 * Reinitialise the sector if there isn't room for the character.
 	 */
-	if (sector[used_bytes - 1] != DHCP_END) {
+	if (sector[used_bytes - 1] != EFX_DHCP_END) {
 		if (used_bytes >= sector_length) {
 			sector[0] = 0;
 			used_bytes = 1;
 		}
-		sector[used_bytes] = DHCP_END;
+		sector[used_bytes] = EFX_DHCP_END;
 		++used_bytes;
 	}
 
@@ -274,10 +807,11 @@ efx_bootcfg_copy_sector(
 		(void) memset(data + used_bytes, 0, data_size - used_bytes);
 
 	/*
-	 * The checksum includes trailing data after any DHCP_END character,
-	 * which we've just modified (by truncation or appending DHCP_END).
+	 * The checksum includes trailing data after any EFX_DHCP_END
+	 * character, which we've just modified (by truncation or appending
+	 * EFX_DHCP_END).
 	 */
-	data[0] -= efx_bootcfg_csum(enp, data, data_size);
+	data[0] -= efx_dhcp_csum(data, data_size);
 
 	return (0);
 
@@ -307,7 +841,7 @@ efx_bootcfg_read(
 	efx_rc_t rc;
 	uint32_t sector_number;
 
-	/* Minimum buffer is checksum byte and DHCP_END terminator */
+	/* Minimum buffer is checksum byte and EFX_DHCP_END terminator */
 	if (size < 2) {
 		rc = ENOSPC;
 		goto fail1;
@@ -343,10 +877,10 @@ efx_bootcfg_read(
 	}
 
 	/*
-	 * We need to read the entire BOOTCFG sector to ensure we read all the
-	 * tags, because legacy bootcfg sectors are not guaranteed to end with
-	 * a DHCP_END character. If the user hasn't supplied a sufficiently
-	 * large buffer then use our own buffer.
+	 * We need to read the entire BOOTCFG sector to ensure we read all
+	 * tags, because legacy bootcfg sectors are not guaranteed to end
+	 * with an EFX_DHCP_END character. If the user hasn't supplied a
+	 * sufficiently large buffer then use our own buffer.
 	 */
 	if (sector_length > size) {
 		EFSYS_KMEM_ALLOC(enp->en_esip, sector_length, payload);
@@ -370,28 +904,29 @@ efx_bootcfg_read(
 		goto fail9;
 
 	/* Verify that the area is correctly formatted and checksummed */
-	rc = efx_bootcfg_verify(enp, payload, sector_length,
+	rc = efx_dhcp_verify(payload, sector_length,
 	    &used_bytes);
 	if (rc != 0 || used_bytes == 0) {
 		payload[0] = 0;
-		payload[1] = DHCP_END;
+		payload[1] = EFX_DHCP_END;
 		used_bytes = 2;
 	}
 
-	EFSYS_ASSERT(used_bytes >= 2);	/* checksum and DHCP_END */
+	EFSYS_ASSERT(used_bytes >= 2);	/* checksum and EFX_DHCP_END */
 	EFSYS_ASSERT(used_bytes <= sector_length);
 
 	/*
-	 * Legacy bootcfg sectors don't terminate with a DHCP_END character.
-	 * Modify the returned payload so it does. BOOTCFG_MAX_SIZE is by
-	 * definition large enough for any valid (per-port) bootcfg sector,
-	 * so reinitialise the sector if there isn't room for the character.
+	 * Legacy bootcfg sectors don't terminate with an EFX_DHCP_END
+	 * character. Modify the returned payload so it does.
+	 * BOOTCFG_MAX_SIZE is by definition large enough for any valid
+	 * (per-port) bootcfg sector, so reinitialise the sector if there
+	 * isn't room for the character.
 	 */
-	if (payload[used_bytes - 1] != DHCP_END) {
+	if (payload[used_bytes - 1] != EFX_DHCP_END) {
 		if (used_bytes >= sector_length)
 			used_bytes = 1;
 
-		payload[used_bytes] = DHCP_END;
+		payload[used_bytes] = EFX_DHCP_END;
 		++used_bytes;
 	}
 
@@ -417,10 +952,10 @@ efx_bootcfg_read(
 		(void) memset(data + used_bytes, 0, size - used_bytes);
 
 	/*
-	 * The checksum includes trailing data after any DHCP_END character,
-	 * which we've just modified (by truncation or appending DHCP_END).
+	 * The checksum includes trailing data after any EFX_DHCP_END character,
+	 * which we've just modified (by truncation or appending EFX_DHCP_END).
 	 */
-	data[0] -= efx_bootcfg_csum(enp, data, size);
+	data[0] -= efx_dhcp_csum(data, size);
 
 	return (0);
 
@@ -490,12 +1025,16 @@ efx_bootcfg_write(
 		goto fail3;
 	}
 
-	if ((rc = efx_bootcfg_verify(enp, data, size, &used_bytes)) != 0)
+	if ((rc = efx_dhcp_verify(data, size, &used_bytes)) != 0)
 		goto fail4;
 
-	/* The caller *must* terminate their block with a DHCP_END character */
-	if ((used_bytes < 2) || ((uint8_t)data[used_bytes - 1] != DHCP_END)) {
-		/* Block too short or DHCP_END missing */
+	/*
+	 * The caller *must* terminate their block with a EFX_DHCP_END
+	 * character
+	 */
+	if ((used_bytes < 2) || ((uint8_t)data[used_bytes - 1] !=
+	    EFX_DHCP_END)) {
+		/* Block too short or EFX_DHCP_END missing */
 		rc = ENOENT;
 		goto fail5;
 	}
@@ -528,13 +1067,13 @@ efx_bootcfg_write(
 		goto fail9;
 
 	/*
-	 * Insert the BOOTCFG sector into the partition, Zero out all data after
-	 * the DHCP_END tag, and adjust the checksum.
+	 * Insert the BOOTCFG sector into the partition, Zero out all data
+	 * after the EFX_DHCP_END tag, and adjust the checksum.
 	 */
 	(void) memset(partn_data + sector_offset, 0x0, sector_length);
 	(void) memcpy(partn_data + sector_offset, data, used_bytes);
 
-	checksum = efx_bootcfg_csum(enp, data, used_bytes);
+	checksum = efx_dhcp_csum(data, used_bytes);
 	partn_data[sector_offset] -= checksum;
 
 	if ((rc = efx_nvram_erase(enp, EFX_NVRAM_BOOTROM_CFG)) != 0)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 19/37] net/sfc/base: add accessor for default port mode
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (17 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 18/37] net/sfc/base: add buffer editing functions to boot config Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 20/37] net/sfc/base: generalise EF10 NVRAM buffer interface Andrew Rybchenko
                   ` (18 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Richard Houldsworth

From: Richard Houldsworth <rhouldsworth@solarflare.com>

Extend efx_mcdi_get_port_modes() to optionally pass on the default
port mode field. This provides a more direct way of handling the case
where the dynamic config does not specify the port mode than the
alternative of a lookup table indexed by MCFW subtype.

Signed-off-by: Richard Houldsworth <rhouldsworth@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h    |  3 ++-
 drivers/net/sfc/base/ef10_nic.c     | 13 ++++++++++---
 drivers/net/sfc/base/hunt_nic.c     |  3 ++-
 drivers/net/sfc/base/medford2_nic.c |  2 +-
 drivers/net/sfc/base/medford_nic.c  |  2 +-
 5 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index fb0d98875..2abd699a0 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -1128,7 +1128,8 @@ extern	__checkReturn	efx_rc_t
 efx_mcdi_get_port_modes(
 	__in		efx_nic_t *enp,
 	__out		uint32_t *modesp,
-	__out_opt	uint32_t *current_modep);
+	__out_opt	uint32_t *current_modep,
+	__out_opt	uint32_t *default_modep);
 
 extern	__checkReturn	efx_rc_t
 ef10_nic_get_port_mode_bandwidth(
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index d1985b3c5..9145c389c 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -63,7 +63,8 @@ efx_mcdi_get_port_assignment(
 efx_mcdi_get_port_modes(
 	__in		efx_nic_t *enp,
 	__out		uint32_t *modesp,
-	__out_opt	uint32_t *current_modep)
+	__out_opt	uint32_t *current_modep,
+	__out_opt	uint32_t *default_modep)
 {
 	efx_mcdi_req_t req;
 	uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
@@ -110,6 +111,11 @@ efx_mcdi_get_port_modes(
 					    GET_PORT_MODES_OUT_CURRENT_MODE);
 	}
 
+	if (default_modep != NULL) {
+		*default_modep = MCDI_OUT_DWORD(req,
+					    GET_PORT_MODES_OUT_DEFAULT_MODE);
+	}
+
 	return (0);
 
 fail3:
@@ -1635,13 +1641,14 @@ ef10_external_port_mapping(
 	int32_t count = 1; /* Default 1-1 mapping */
 	int32_t offset = 1; /* Default starting external port number */
 
-	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current)) != 0) {
+	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current,
+		    NULL)) != 0) {
 		/*
 		 * No current port mode information (i.e. Huntington)
 		 * - infer mapping from available modes
 		 */
 		if ((rc = efx_mcdi_get_port_modes(enp,
-			    &port_modes, NULL)) != 0) {
+			    &port_modes, NULL, NULL)) != 0) {
 			/*
 			 * No port mode information available
 			 * - use default mapping
diff --git a/drivers/net/sfc/base/hunt_nic.c b/drivers/net/sfc/base/hunt_nic.c
index 16ea81d23..1bec3c485 100644
--- a/drivers/net/sfc/base/hunt_nic.c
+++ b/drivers/net/sfc/base/hunt_nic.c
@@ -30,7 +30,8 @@ hunt_nic_get_required_pcie_bandwidth(
 	 * capable mode is in use.
 	 */
 
-	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, NULL)) != 0) {
+	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
+		    NULL, NULL)) != 0) {
 		/* No port mode info available */
 		bandwidth = 0;
 		goto out;
diff --git a/drivers/net/sfc/base/medford2_nic.c b/drivers/net/sfc/base/medford2_nic.c
index 7f5ad1757..b36e54bab 100644
--- a/drivers/net/sfc/base/medford2_nic.c
+++ b/drivers/net/sfc/base/medford2_nic.c
@@ -23,7 +23,7 @@ medford2_nic_get_required_pcie_bandwidth(
 	/* FIXME: support new Medford2 dynamic port modes */
 
 	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
-				    &current_mode)) != 0) {
+				    &current_mode, NULL)) != 0) {
 		/* No port mode info available. */
 		bandwidth = 0;
 		goto out;
diff --git a/drivers/net/sfc/base/medford_nic.c b/drivers/net/sfc/base/medford_nic.c
index 6dc895f5b..96f3a1204 100644
--- a/drivers/net/sfc/base/medford_nic.c
+++ b/drivers/net/sfc/base/medford_nic.c
@@ -21,7 +21,7 @@ medford_nic_get_required_pcie_bandwidth(
 	efx_rc_t rc;
 
 	if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
-				    &current_mode)) != 0) {
+				    &current_mode, NULL)) != 0) {
 		/* No port mode info available. */
 		bandwidth = 0;
 		goto out;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 20/37] net/sfc/base: generalise EF10 NVRAM buffer interface
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (18 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 19/37] net/sfc/base: add accessor for default port mode Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 21/37] net/sfc/base: avoid usage of too big arrays on stack Andrew Rybchenko
                   ` (17 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Richard Houldsworth

From: Richard Houldsworth <rhouldsworth@solarflare.com>

The SFN driver's PartitionControl WMI object requires an API to parse
and filter partition data in TLV format, particularly for the Dynamic
Config partition. The ef10_nvram_buffer functions provide this
functionality but are tied to use with license partition only.
Modify functions so they are applicable to all TLV partitions and add
functions to support in-place tag modification.

Signed-off-by: Richard Houldsworth <rhouldsworth@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h  |  43 +++++++--
 drivers/net/sfc/base/ef10_nvram.c | 153 ++++++++++++++++++++++++------
 drivers/net/sfc/base/efx_impl.h   |   2 +-
 drivers/net/sfc/base/efx_lic.c    |  15 ++-
 drivers/net/sfc/base/efx_nvram.c  |   2 +-
 5 files changed, 174 insertions(+), 41 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 2abd699a0..503f02362 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -477,17 +477,21 @@ ef10_nvram_partn_set_version(
 
 extern	__checkReturn		efx_rc_t
 ef10_nvram_buffer_validate(
-	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in_bcount(buffer_size)
 				caddr_t bufferp,
 	__in			size_t buffer_size);
 
+extern			void
+ef10_nvram_buffer_init(
+	__out_bcount(buffer_size)
+				caddr_t bufferp,
+	__in			size_t buffer_size);
+
 extern	__checkReturn		efx_rc_t
 ef10_nvram_buffer_create(
-	__in			efx_nic_t *enp,
-	__in			uint16_t partn_type,
-	__in_bcount(buffer_size)
+	__in			uint32_t partn_type,
+	__out_bcount(buffer_size)
 				caddr_t bufferp,
 	__in			size_t buffer_size);
 
@@ -515,6 +519,16 @@ ef10_nvram_buffer_find_item(
 	__out			uint32_t *startp,
 	__out			uint32_t *lengthp);
 
+extern	__checkReturn		efx_rc_t
+ef10_nvram_buffer_peek_item(
+	__in_bcount(buffer_size)
+				caddr_t bufferp,
+	__in			size_t buffer_size,
+	__in			uint32_t offset,
+	__out			uint32_t *tagp,
+	__out			uint32_t *lengthp,
+	__out			uint32_t *value_offsetp);
+
 extern	__checkReturn		efx_rc_t
 ef10_nvram_buffer_get_item(
 	__in_bcount(buffer_size)
@@ -522,9 +536,10 @@ ef10_nvram_buffer_get_item(
 	__in			size_t buffer_size,
 	__in			uint32_t offset,
 	__in			uint32_t length,
-	__out_bcount_part(item_max_size, *lengthp)
-				caddr_t itemp,
-	__in			size_t item_max_size,
+	__out			uint32_t *tagp,
+	__out_bcount_part(value_max_size, *lengthp)
+				caddr_t valuep,
+	__in			size_t value_max_size,
 	__out			uint32_t *lengthp);
 
 extern	__checkReturn		efx_rc_t
@@ -533,7 +548,19 @@ ef10_nvram_buffer_insert_item(
 				caddr_t bufferp,
 	__in			size_t buffer_size,
 	__in			uint32_t offset,
-	__in_bcount(length)	caddr_t keyp,
+	__in			uint32_t tag,
+	__in_bcount(length)	caddr_t valuep,
+	__in			uint32_t length,
+	__out			uint32_t *lengthp);
+
+extern	__checkReturn		efx_rc_t
+ef10_nvram_buffer_modify_item(
+	__in_bcount(buffer_size)
+				caddr_t bufferp,
+	__in			size_t buffer_size,
+	__in			uint32_t offset,
+	__in			uint32_t tag,
+	__in_bcount(length)	caddr_t valuep,
 	__in			uint32_t length,
 	__out			uint32_t *lengthp);
 
diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 96ea5624a..8d1b64f25 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -203,14 +203,14 @@ tlv_validate_state(
 
 	if (tlv_tag(cursor) != TLV_TAG_END) {
 		/* Check current item has space for tag and length */
-		if (cursor->current > (cursor->limit - 2)) {
+		if (cursor->current > (cursor->limit - 1)) {
 			cursor->current = NULL;
 			rc = EFAULT;
 			goto fail3;
 		}
 
-		/* Check we have value data for current item and another tag */
-		if (tlv_next_item_ptr(cursor) > (cursor->limit - 1)) {
+		/* Check we have value data for current item and an END tag */
+		if (tlv_next_item_ptr(cursor) > cursor->limit) {
 			cursor->current = NULL;
 			rc = EFAULT;
 			goto fail4;
@@ -635,7 +635,6 @@ tlv_update_partition_len_and_cks(
 /* Validate buffer contents (before writing to flash) */
 	__checkReturn		efx_rc_t
 ef10_nvram_buffer_validate(
-	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in_bcount(partn_size)	caddr_t partn_data,
 	__in			size_t partn_size)
@@ -648,7 +647,6 @@ ef10_nvram_buffer_validate(
 	int pos;
 	efx_rc_t rc;
 
-	_NOTE(ARGUNUSED(enp, partn))
 	EFX_STATIC_ASSERT(sizeof (*header) <= EF10_NVRAM_CHUNK);
 
 	if ((partn_data == NULL) || (partn_size == 0)) {
@@ -675,26 +673,32 @@ ef10_nvram_buffer_validate(
 		goto fail4;
 	}
 
+	/* Check partition header matches partn */
+	if (__LE_TO_CPU_16(header->type_id) != partn) {
+		rc = EINVAL;
+		goto fail5;
+	}
+
 	/* Check partition ends with PARTITION_TRAILER and END tags */
 	if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
 		rc = EINVAL;
-		goto fail5;
+		goto fail6;
 	}
 	trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
 
 	if ((rc = tlv_advance(&cursor)) != 0) {
 		rc = EINVAL;
-		goto fail6;
+		goto fail7;
 	}
 	if (tlv_tag(&cursor) != TLV_TAG_END) {
 		rc = EINVAL;
-		goto fail7;
+		goto fail8;
 	}
 
 	/* Check generation counts are consistent */
 	if (trailer->generation != header->generation) {
 		rc = EINVAL;
-		goto fail8;
+		goto fail9;
 	}
 
 	/* Verify partition checksum */
@@ -704,11 +708,13 @@ ef10_nvram_buffer_validate(
 	}
 	if (cksum != 0) {
 		rc = EINVAL;
-		goto fail9;
+		goto fail10;
 	}
 
 	return (0);
 
+fail10:
+	EFSYS_PROBE(fail10);
 fail9:
 	EFSYS_PROBE(fail9);
 fail8:
@@ -731,13 +737,24 @@ ef10_nvram_buffer_validate(
 	return (rc);
 }
 
+			void
+ef10_nvram_buffer_init(
+	__out_bcount(buffer_size)
+				caddr_t bufferp,
+	__in			size_t buffer_size)
+{
+	uint32_t *buf = (uint32_t *)bufferp;
+
+	memset(buf, 0xff, buffer_size);
 
+	tlv_init_block(buf);
+}
 
 	__checkReturn		efx_rc_t
 ef10_nvram_buffer_create(
-	__in			efx_nic_t *enp,
-	__in			uint16_t partn_type,
-	__in_bcount(partn_size)	caddr_t partn_data,
+	__in			uint32_t partn_type,
+	__out_bcount(partn_size)
+				caddr_t partn_data,
 	__in			size_t partn_size)
 {
 	uint32_t *buf = (uint32_t *)partn_data;
@@ -753,9 +770,8 @@ ef10_nvram_buffer_create(
 		goto fail1;
 	}
 
-	memset(buf, 0xff, partn_size);
+	ef10_nvram_buffer_init(partn_data, partn_size);
 
-	tlv_init_block(buf);
 	if ((rc = tlv_init_cursor(&cursor, buf,
 	    (uint32_t *)((uint8_t *)buf + partn_size),
 	    buf)) != 0) {
@@ -787,7 +803,7 @@ ef10_nvram_buffer_create(
 		goto fail6;
 
 	/* Check that the partition is valid. */
-	if ((rc = ef10_nvram_buffer_validate(enp, partn_type,
+	if ((rc = ef10_nvram_buffer_validate(partn_type,
 	    partn_data, partn_size)) != 0)
 		goto fail7;
 
@@ -958,6 +974,48 @@ ef10_nvram_buffer_find_item(
 	return (B_FALSE);
 }
 
+	__checkReturn		efx_rc_t
+ef10_nvram_buffer_peek_item(
+	__in_bcount(buffer_size)
+				caddr_t bufferp,
+	__in			size_t buffer_size,
+	__in			uint32_t offset,
+	__out			uint32_t *tagp,
+	__out			uint32_t *lengthp,
+	__out			uint32_t *value_offsetp)
+{
+	efx_rc_t rc;
+	tlv_cursor_t cursor;
+	uint32_t tag;
+
+	if ((rc = tlv_init_cursor_at_offset(&cursor, (uint8_t *)bufferp,
+			buffer_size, offset)) != 0) {
+		goto fail1;
+	}
+
+	tag = tlv_tag(&cursor);
+	*tagp = tag;
+	if (tag == TLV_TAG_END) {
+		/*
+		 * To allow stepping over the END tag, report the full tag
+		 * length and a zero length value.
+		 */
+		*lengthp = sizeof (tag);
+		*value_offsetp = sizeof (tag);
+	} else {
+		*lengthp = byte_offset(tlv_next_item_ptr(&cursor),
+			    cursor.current);
+		*value_offsetp = byte_offset((uint32_t *)tlv_value(&cursor),
+			    cursor.current);
+	}
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
 	__checkReturn		efx_rc_t
 ef10_nvram_buffer_get_item(
 	__in_bcount(buffer_size)
@@ -965,16 +1023,17 @@ ef10_nvram_buffer_get_item(
 	__in			size_t buffer_size,
 	__in			uint32_t offset,
 	__in			uint32_t length,
-	__out_bcount_part(item_max_size, *lengthp)
-				caddr_t itemp,
-	__in			size_t item_max_size,
+	__out			uint32_t *tagp,
+	__out_bcount_part(value_max_size, *lengthp)
+				caddr_t valuep,
+	__in			size_t value_max_size,
 	__out			uint32_t *lengthp)
 {
 	efx_rc_t rc;
 	tlv_cursor_t cursor;
-	uint32_t item_length;
+	uint32_t value_length;
 
-	if (item_max_size < length) {
+	if (buffer_size < (offset + length)) {
 		rc = ENOSPC;
 		goto fail1;
 	}
@@ -984,14 +1043,15 @@ ef10_nvram_buffer_get_item(
 		goto fail2;
 	}
 
-	item_length = tlv_length(&cursor);
-	if (length < item_length) {
+	value_length = tlv_length(&cursor);
+	if (value_max_size < value_length) {
 		rc = ENOSPC;
 		goto fail3;
 	}
-	memcpy(itemp, tlv_value(&cursor), item_length);
+	memcpy(valuep, tlv_value(&cursor), value_length);
 
-	*lengthp = item_length;
+	*tagp = tlv_tag(&cursor);
+	*lengthp = value_length;
 
 	return (0);
 
@@ -1011,7 +1071,8 @@ ef10_nvram_buffer_insert_item(
 				caddr_t bufferp,
 	__in			size_t buffer_size,
 	__in			uint32_t offset,
-	__in_bcount(length)	caddr_t keyp,
+	__in			uint32_t tag,
+	__in_bcount(length)	caddr_t valuep,
 	__in			uint32_t length,
 	__out			uint32_t *lengthp)
 {
@@ -1023,7 +1084,44 @@ ef10_nvram_buffer_insert_item(
 		goto fail1;
 	}
 
-	rc = tlv_insert(&cursor, TLV_TAG_LICENSE, (uint8_t *)keyp, length);
+	rc = tlv_insert(&cursor, tag, (uint8_t *)valuep, length);
+
+	if (rc != 0)
+		goto fail2;
+
+	*lengthp = byte_offset(tlv_next_item_ptr(&cursor),
+		    cursor.current);
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn		efx_rc_t
+ef10_nvram_buffer_modify_item(
+	__in_bcount(buffer_size)
+				caddr_t bufferp,
+	__in			size_t buffer_size,
+	__in			uint32_t offset,
+	__in			uint32_t tag,
+	__in_bcount(length)	caddr_t valuep,
+	__in			uint32_t length,
+	__out			uint32_t *lengthp)
+{
+	efx_rc_t rc;
+	tlv_cursor_t cursor;
+
+	if ((rc = tlv_init_cursor_at_offset(&cursor, (uint8_t *)bufferp,
+			buffer_size, offset)) != 0) {
+		goto fail1;
+	}
+
+	rc = tlv_modify(&cursor, tag, (uint8_t *)valuep, length);
 
 	if (rc != 0) {
 		goto fail2;
@@ -1042,6 +1140,7 @@ ef10_nvram_buffer_insert_item(
 	return (rc);
 }
 
+
 	__checkReturn		efx_rc_t
 ef10_nvram_buffer_delete_item(
 	__in_bcount(buffer_size)
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 0764df5de..78df43018 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -509,7 +509,7 @@ typedef struct efx_nvram_ops_s {
 					    uint32_t *, uint16_t *);
 	efx_rc_t	(*envo_partn_set_version)(efx_nic_t *, uint32_t,
 					    uint16_t *);
-	efx_rc_t	(*envo_buffer_validate)(efx_nic_t *, uint32_t,
+	efx_rc_t	(*envo_buffer_validate)(uint32_t,
 					    caddr_t, size_t);
 } efx_nvram_ops_t;
 #endif /* EFSYS_OPT_NVRAM */
diff --git a/drivers/net/sfc/base/efx_lic.c b/drivers/net/sfc/base/efx_lic.c
index 49c00347f..2b06e2d1e 100644
--- a/drivers/net/sfc/base/efx_lic.c
+++ b/drivers/net/sfc/base/efx_lic.c
@@ -1158,10 +1158,12 @@ efx_lic_v3_read_key(
 	__in			size_t key_max_size,
 	__out			uint32_t *lengthp)
 {
+	uint32_t tag;
+
 	_NOTE(ARGUNUSED(enp))
 
 	return ef10_nvram_buffer_get_item(bufferp, buffer_size,
-		    offset, length, keyp, key_max_size, lengthp);
+		    offset, length, &tag, keyp, key_max_size, lengthp);
 }
 
 	__checkReturn		efx_rc_t
@@ -1179,7 +1181,7 @@ efx_lic_v3_write_key(
 	EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
 
 	return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
-		    offset, keyp, length, lengthp);
+		    offset, TLV_TAG_LICENSE, keyp, length, lengthp);
 }
 
 	__checkReturn		efx_rc_t
@@ -1221,8 +1223,10 @@ efx_lic_v3_create_partition(
 {
 	efx_rc_t rc;
 
+	_NOTE(ARGUNUSED(enp))
+
 	/* Construct empty partition */
-	if ((rc = ef10_nvram_buffer_create(enp,
+	if ((rc = ef10_nvram_buffer_create(
 	    NVRAM_PARTITION_TYPE_LICENSE,
 	    bufferp, buffer_size)) != 0) {
 		rc = EFAULT;
@@ -1246,13 +1250,16 @@ efx_lic_v3_finish_partition(
 {
 	efx_rc_t rc;
 
+	_NOTE(ARGUNUSED(enp))
+
 	if ((rc = ef10_nvram_buffer_finish(bufferp,
 			buffer_size)) != 0) {
 		goto fail1;
 	}
 
 	/* Validate completed partition */
-	if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE,
+	if ((rc = ef10_nvram_buffer_validate(
+					NVRAM_PARTITION_TYPE_LICENSE,
 					bufferp, buffer_size)) != 0) {
 		goto fail2;
 	}
diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c
index f3107bbb5..9000fe886 100644
--- a/drivers/net/sfc/base/efx_nvram.c
+++ b/drivers/net/sfc/base/efx_nvram.c
@@ -468,7 +468,7 @@ efx_nvram_validate(
 		goto fail1;
 
 	if (envop->envo_buffer_validate != NULL) {
-		if ((rc = envop->envo_buffer_validate(enp, partn,
+		if ((rc = envop->envo_buffer_validate(partn,
 			    partn_data, partn_size)) != 0)
 			goto fail2;
 	}
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 21/37] net/sfc/base: avoid usage of too big arrays on stack
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (19 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 20/37] net/sfc/base: generalise EF10 NVRAM buffer interface Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 22/37] net/sfc/base: add information if TSO workaround is required Andrew Rybchenko
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Martin Harvey, stable

From: Martin Harvey <mharvey@solarflare.com>

Found by PreFAST static analysis.

Fixes: 1dae25112a54 ("net/sfc/base: import built-in selftest")
Fixes: d96a34d165b1 ("net/sfc/base: import NVRAM support")
Cc: stable@dpdk.org

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_phy.c  | 18 +++++++++++++++---
 drivers/net/sfc/base/efx_nvram.c | 27 ++++++++++++++++++---------
 2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_phy.c b/drivers/net/sfc/base/ef10_phy.c
index 84acb70a1..e9c7b40e4 100644
--- a/drivers/net/sfc/base/ef10_phy.c
+++ b/drivers/net/sfc/base/ef10_phy.c
@@ -583,14 +583,26 @@ ef10_bist_poll(
 	unsigned long *valuesp,
 	__in			size_t count)
 {
+	/*
+	 * MCDI_CTL_SDU_LEN_MAX_V1 is large enough cover all BIST results,
+	 * whilst not wasting stack.
+	 */
+	uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN, MCDI_CTL_SDU_LEN_MAX_V1)];
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
-			    MCDI_CTL_SDU_LEN_MAX)];
 	uint32_t value_mask = 0;
 	uint32_t result;
 	efx_rc_t rc;
 
+	EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_LEN <=
+	    MCDI_CTL_SDU_LEN_MAX_V1);
+	EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_SFT9001_LEN <=
+	    MCDI_CTL_SDU_LEN_MAX_V1);
+	EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_MRSFP_LEN <=
+	    MCDI_CTL_SDU_LEN_MAX_V1);
+	EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_MEM_LEN <=
+	    MCDI_CTL_SDU_LEN_MAX_V1);
+
 	_NOTE(ARGUNUSED(type))
 
 	(void) memset(payload, 0, sizeof (payload));
@@ -598,7 +610,7 @@ ef10_bist_poll(
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
 	req.emr_out_buf = payload;
-	req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
+	req.emr_out_length = MCDI_CTL_SDU_LEN_MAX_V1;
 
 	efx_mcdi_execute(enp, &req);
 
diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c
index 9000fe886..d7b1a6778 100644
--- a/drivers/net/sfc/base/efx_nvram.c
+++ b/drivers/net/sfc/base/efx_nvram.c
@@ -869,23 +869,27 @@ efx_mcdi_nvram_write(
 	__in			size_t size)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
-			    MCDI_CTL_SDU_LEN_MAX_V2)];
+	uint8_t *payload;
 	efx_rc_t rc;
 	size_t max_data_size;
+	size_t payload_len = enp->en_nic_cfg.enc_mcdi_max_payload_length;
 
-	max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
-	    - MC_CMD_NVRAM_WRITE_IN_LEN(0);
-	EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
-	EFSYS_ASSERT3U(max_data_size, <,
-		    enp->en_nic_cfg.enc_mcdi_max_payload_length);
+	max_data_size = payload_len - MC_CMD_NVRAM_WRITE_IN_LEN(0);
+	EFSYS_ASSERT3U(payload_len, >, 0);
+	EFSYS_ASSERT3U(max_data_size, <, payload_len);
 
 	if (size > max_data_size) {
 		rc = EINVAL;
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
+	EFSYS_KMEM_ALLOC(enp->en_esip, payload_len, payload);
+	if (payload == NULL) {
+		rc = ENOMEM;
+		goto fail2;
+	}
+
+	(void) memset(payload, 0, payload_len);
 	req.emr_cmd = MC_CMD_NVRAM_WRITE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
@@ -903,11 +907,16 @@ efx_mcdi_nvram_write(
 
 	if (req.emr_rc != 0) {
 		rc = req.emr_rc;
-		goto fail2;
+		goto fail3;
 	}
 
+	EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload);
+
 	return (0);
 
+fail3:
+	EFSYS_PROBE(fail3);
+	EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload);
 fail2:
 	EFSYS_PROBE(fail2);
 fail1:
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 22/37] net/sfc/base: add information if TSO workaround is required
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (20 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 21/37] net/sfc/base: avoid usage of too big arrays on stack Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 23/37] net/sfc/base: fix out of bounds read when dereferencing sdup Andrew Rybchenko
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Mark Spender

From: Mark Spender <mspender@solarflare.com>

In SF bug 61297 it's been confirmed that the hardware does not always
calculate the TCP checksum correctly with TSO sends.

The value of the Total Length field (IPv4) or Payload Length field
(IPv6) is the critical factor. We're sufficiently confident that if
these fields are zero then the checksum will be calculated correctly.

The information may be used by the drivers to check if the workaround is
required when FATSOv2 is implemented.

Signed-off-by: Mark Spender <mspender@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h          | 1 +
 drivers/net/sfc/base/hunt_nic.c     | 3 +++
 drivers/net/sfc/base/medford2_nic.c | 3 +++
 drivers/net/sfc/base/medford_nic.c  | 3 +++
 4 files changed, 10 insertions(+)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 3c3227739..2356a9294 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1292,6 +1292,7 @@ typedef struct efx_nic_cfg_s {
 	boolean_t		enc_bug35388_workaround;
 	boolean_t		enc_bug41750_workaround;
 	boolean_t		enc_bug61265_workaround;
+	boolean_t		enc_bug61297_workaround;
 	boolean_t		enc_rx_batching_enabled;
 	/* Maximum number of descriptors completed in an rx event. */
 	uint32_t		enc_rx_batch_max;
diff --git a/drivers/net/sfc/base/hunt_nic.c b/drivers/net/sfc/base/hunt_nic.c
index 1bec3c485..70c042f3f 100644
--- a/drivers/net/sfc/base/hunt_nic.c
+++ b/drivers/net/sfc/base/hunt_nic.c
@@ -190,6 +190,9 @@ hunt_board_cfg(
 
 	encp->enc_bug61265_workaround = B_FALSE; /* Medford only */
 
+	/* Checksums for TSO sends can be incorrect on Huntington. */
+	encp->enc_bug61297_workaround = B_TRUE;
+
 	/* Alignment for receive packet DMA buffers */
 	encp->enc_rx_buf_align_start = 1;
 	encp->enc_rx_buf_align_end = 64; /* RX DMA end padding */
diff --git a/drivers/net/sfc/base/medford2_nic.c b/drivers/net/sfc/base/medford2_nic.c
index b36e54bab..3efc35886 100644
--- a/drivers/net/sfc/base/medford2_nic.c
+++ b/drivers/net/sfc/base/medford2_nic.c
@@ -96,6 +96,9 @@ medford2_board_cfg(
 	else
 		goto fail1;
 
+	/* Checksums for TSO sends should always be correct on Medford2. */
+	encp->enc_bug61297_workaround = B_FALSE;
+
 	/* Get clock frequencies (in MHz). */
 	if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0)
 		goto fail2;
diff --git a/drivers/net/sfc/base/medford_nic.c b/drivers/net/sfc/base/medford_nic.c
index 96f3a1204..4f1896343 100644
--- a/drivers/net/sfc/base/medford_nic.c
+++ b/drivers/net/sfc/base/medford_nic.c
@@ -94,6 +94,9 @@ medford_board_cfg(
 	else
 		goto fail1;
 
+	/* Checksums for TSO sends can be incorrect on Medford. */
+	encp->enc_bug61297_workaround = B_TRUE;
+
 	/* Get clock frequencies (in MHz). */
 	if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0)
 		goto fail2;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 23/37] net/sfc/base: fix out of bounds read when dereferencing sdup
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (21 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 22/37] net/sfc/base: add information if TSO workaround is required Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 24/37] net/sfc/base: add routine to check for hardware presence Andrew Rybchenko
                   ` (14 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Gautam Dawar, stable

From: Gautam Dawar <gdawar@solarflare.com>

Introduce and use macro to make sure that MCDI buffers allocated
on stack are rounded up properly.

Fixes: 6f619653b9b1 ("net/sfc/base: import MCDI implementation")
Fixes: f7dc06bf35f2 ("net/sfc/base: import 5xxx/6xxx family support")
Fixes: e7cd430c864f ("net/sfc/base: import SFN7xxx family support")
Fixes: 1dae25112a54 ("net/sfc/base: import built-in selftest")
Fixes: 0a7864349106 ("net/sfc/base: import PHY statistics")
Fixes: 8c7c723dfe7c ("net/sfc/base: import MAC statistics")
Fixes: 5935cd8c47d3 ("net/sfc/base: import RSS support")
Fixes: 9ee64bd404fc ("net/sfc/base: import loopback control")
Fixes: dfb3b1ce15f6 ("net/sfc/base: import monitors access via MCDI")
Fixes: d96a34d165b1 ("net/sfc/base: import NVRAM support")
Fixes: 05fce2ce8451 ("net/sfc/base: import libefx licensing")
Fixes: ba6afee9a81e ("net/sfc/base: add advanced function to extract FW version")
Fixes: c7815c1d1f20 ("net/sfc/base: use proper MCDI command for encap filters")
Fixes: 17551f6dffcc ("net/sfc/base: add API to control UDP tunnel ports")
Fixes: eff9b666eae5 ("net/sfc/base: move RxDP config get to EF10 NIC code")
Fixes: 4aab7f07a645 ("net/sfc/base: refactor EF10 get datapath capabilities")
Fixes: 480a13044b8b ("net/sfc/base: support FW subvariant choice")
Fixes: 6f60cc4a78b6 ("net/sfc/base: support equal stride super-buffer Rx mode")
Fixes: 9a733758c046 ("net/sfc/base: support MARK and FLAG actions in filters")
Cc: stable@dpdk.org

Signed-off-by: Gautam Dawar <gdawar@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_ev.c     | 28 ++++-----
 drivers/net/sfc/base/ef10_filter.c | 15 ++---
 drivers/net/sfc/base/ef10_intr.c   |  5 +-
 drivers/net/sfc/base/ef10_mac.c    | 20 +++----
 drivers/net/sfc/base/ef10_nic.c    | 93 ++++++++++++------------------
 drivers/net/sfc/base/ef10_phy.c    | 19 +++---
 drivers/net/sfc/base/ef10_rx.c     | 35 +++++------
 drivers/net/sfc/base/ef10_tx.c     | 10 ++--
 drivers/net/sfc/base/efx_lic.c     | 39 +++++--------
 drivers/net/sfc/base/efx_mcdi.c    | 82 +++++++++++---------------
 drivers/net/sfc/base/efx_mcdi.h    | 11 ++++
 drivers/net/sfc/base/efx_nic.c     |  5 +-
 drivers/net/sfc/base/efx_nvram.c   | 40 +++++--------
 drivers/net/sfc/base/efx_tunnel.c  |  6 +-
 drivers/net/sfc/base/mcdi_mon.c    | 17 +++---
 drivers/net/sfc/base/siena_mac.c   |  9 ++-
 drivers/net/sfc/base/siena_nic.c   |  5 +-
 drivers/net/sfc/base/siena_nvram.c |  5 +-
 drivers/net/sfc/base/siena_phy.c   | 28 ++++-----
 19 files changed, 199 insertions(+), 273 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_ev.c b/drivers/net/sfc/base/ef10_ev.c
index 7f89a7bf0..287550605 100644
--- a/drivers/net/sfc/base/ef10_ev.c
+++ b/drivers/net/sfc/base/ef10_ev.c
@@ -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(EFX_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(EFX_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;
@@ -603,8 +599,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;
diff --git a/drivers/net/sfc/base/ef10_filter.c b/drivers/net/sfc/base/ef10_filter.c
index a4d97f99c..30a4892df 100644
--- a/drivers/net/sfc/base/ef10_filter.c
+++ b/drivers/net/sfc/base/ef10_filter.c
@@ -172,12 +172,11 @@ efx_mcdi_filter_op_add(
 	__inout		ef10_filter_handle_t *handle)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_FILTER_OP_V3_IN_LEN,
-			    MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_V3_IN_LEN,
+		MC_CMD_FILTER_OP_EXT_OUT_LEN);
 	efx_filter_match_flags_t match_flags;
 	efx_rc_t rc;
 
-	memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_FILTER_OP;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_FILTER_OP_V3_IN_LEN;
@@ -376,11 +375,10 @@ efx_mcdi_filter_op_delete(
 	__inout		ef10_filter_handle_t *handle)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_FILTER_OP_EXT_IN_LEN,
-			    MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_EXT_IN_LEN,
+		MC_CMD_FILTER_OP_EXT_OUT_LEN);
 	efx_rc_t rc;
 
-	memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_FILTER_OP;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_FILTER_OP_EXT_IN_LEN;
@@ -950,13 +948,12 @@ efx_mcdi_get_parser_disp_info(
 	__out				size_t *list_lengthp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
-			    MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
+		MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX);
 	size_t matches_count;
 	size_t list_size;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PARSER_DISP_INFO;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PARSER_DISP_INFO_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_intr.c b/drivers/net/sfc/base/ef10_intr.c
index 1ffe266b1..efa157125 100644
--- a/drivers/net/sfc/base/ef10_intr.c
+++ b/drivers/net/sfc/base/ef10_intr.c
@@ -51,8 +51,8 @@ efx_mcdi_trigger_interrupt(
 	__in		unsigned int level)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
-			    MC_CMD_TRIGGER_INTERRUPT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
+		MC_CMD_TRIGGER_INTERRUPT_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
@@ -64,7 +64,6 @@ efx_mcdi_trigger_interrupt(
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_mac.c b/drivers/net/sfc/base/ef10_mac.c
index c14010732..a4a6d9ec8 100644
--- a/drivers/net/sfc/base/ef10_mac.c
+++ b/drivers/net/sfc/base/ef10_mac.c
@@ -75,11 +75,10 @@ efx_mcdi_vadapter_set_mac(
 {
 	efx_port_t *epp = &(enp->en_port);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
-			    MC_CMD_VADAPTOR_SET_MAC_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
+		MC_CMD_VADAPTOR_SET_MAC_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN;
@@ -141,11 +140,10 @@ efx_mcdi_mtu_set(
 	__in		uint32_t mtu)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SET_MAC_EXT_IN_LEN,
-			    MC_CMD_SET_MAC_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN,
+		MC_CMD_SET_MAC_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_MAC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN;
@@ -178,11 +176,10 @@ efx_mcdi_mtu_get(
 	__out		size_t *mtu)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SET_MAC_EXT_IN_LEN,
-			    MC_CMD_SET_MAC_V2_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN,
+		MC_CMD_SET_MAC_V2_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_MAC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN;
@@ -274,11 +271,10 @@ ef10_mac_reconfigure(
 {
 	efx_port_t *epp = &(enp->en_port);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
-			    MC_CMD_SET_MAC_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_IN_LEN,
+		MC_CMD_SET_MAC_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_MAC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index 9145c389c..332f6ef81 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -20,15 +20,14 @@ efx_mcdi_get_port_assignment(
 	__out		uint32_t *portp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
-			    MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
+		MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
 	    enp->en_family == EFX_FAMILY_MEDFORD ||
 	    enp->en_family == EFX_FAMILY_MEDFORD2);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
@@ -67,15 +66,14 @@ efx_mcdi_get_port_modes(
 	__out_opt	uint32_t *default_modep)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
-			    MC_CMD_GET_PORT_MODES_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_MODES_IN_LEN,
+		MC_CMD_GET_PORT_MODES_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
 	    enp->en_family == EFX_FAMILY_MEDFORD ||
 	    enp->en_family == EFX_FAMILY_MEDFORD2);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PORT_MODES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
@@ -180,13 +178,12 @@ efx_mcdi_vadaptor_alloc(
 	__in			uint32_t port_id)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
-			    MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_ALLOC_IN_LEN,
+		MC_CMD_VADAPTOR_ALLOC_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
@@ -219,11 +216,10 @@ efx_mcdi_vadaptor_free(
 	__in			uint32_t port_id)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
-			    MC_CMD_VADAPTOR_FREE_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_FREE_IN_LEN,
+		MC_CMD_VADAPTOR_FREE_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_VADAPTOR_FREE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
@@ -253,15 +249,14 @@ efx_mcdi_get_mac_address_pf(
 	__out_ecount_opt(6)	uint8_t mac_addrp[6])
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
-			    MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
+		MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
 	    enp->en_family == EFX_FAMILY_MEDFORD ||
 	    enp->en_family == EFX_FAMILY_MEDFORD2);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
@@ -312,15 +307,14 @@ efx_mcdi_get_mac_address_vf(
 	__out_ecount_opt(6)	uint8_t mac_addrp[6])
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
-			    MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
+		MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
 	    enp->en_family == EFX_FAMILY_MEDFORD ||
 	    enp->en_family == EFX_FAMILY_MEDFORD2);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
@@ -377,15 +371,14 @@ efx_mcdi_get_clock(
 	__out		uint32_t *dpcpu_freqp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
-			    MC_CMD_GET_CLOCK_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CLOCK_IN_LEN,
+		MC_CMD_GET_CLOCK_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
 	    enp->en_family == EFX_FAMILY_MEDFORD ||
 	    enp->en_family == EFX_FAMILY_MEDFORD2);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_CLOCK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
@@ -435,12 +428,11 @@ efx_mcdi_get_rxdp_config(
 	__out		uint32_t *end_paddingp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
-			    MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RXDP_CONFIG_IN_LEN,
+		MC_CMD_GET_RXDP_CONFIG_OUT_LEN);
 	uint32_t end_padding;
 	efx_rc_t rc;
 
-	memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
@@ -495,11 +487,10 @@ efx_mcdi_get_vector_cfg(
 	__out_opt	uint32_t *vf_nvecp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
-			    MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_VECTOR_CFG_IN_LEN,
+		MC_CMD_GET_VECTOR_CFG_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
@@ -545,8 +536,8 @@ efx_mcdi_alloc_vis(
 	__out		uint32_t *vi_shiftp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
-			    MC_CMD_ALLOC_VIS_EXT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN,
+		MC_CMD_ALLOC_VIS_EXT_OUT_LEN);
 	efx_rc_t rc;
 
 	if (vi_countp == NULL) {
@@ -554,7 +545,6 @@ efx_mcdi_alloc_vis(
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_ALLOC_VIS;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
@@ -637,8 +627,8 @@ efx_mcdi_alloc_piobuf(
 	__out		efx_piobuf_handle_t *handlep)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
-			    MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN,
+		MC_CMD_ALLOC_PIOBUF_OUT_LEN);
 	efx_rc_t rc;
 
 	if (handlep == NULL) {
@@ -646,7 +636,6 @@ efx_mcdi_alloc_piobuf(
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
@@ -685,11 +674,10 @@ efx_mcdi_free_piobuf(
 	__in		efx_piobuf_handle_t handle)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
-			    MC_CMD_FREE_PIOBUF_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN,
+		MC_CMD_FREE_PIOBUF_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_FREE_PIOBUF;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
@@ -720,11 +708,10 @@ efx_mcdi_link_piobuf(
 	__in		efx_piobuf_handle_t handle)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
-			    MC_CMD_LINK_PIOBUF_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN,
+		MC_CMD_LINK_PIOBUF_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_LINK_PIOBUF;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
@@ -755,11 +742,10 @@ efx_mcdi_unlink_piobuf(
 	__in		uint32_t vi_index)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
-			    MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN,
+		MC_CMD_UNLINK_PIOBUF_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
@@ -957,11 +943,10 @@ ef10_mcdi_get_pf_count(
 	__out		uint32_t *pf_countp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PF_COUNT_IN_LEN,
-			    MC_CMD_GET_PF_COUNT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN,
+		MC_CMD_GET_PF_COUNT_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PF_COUNT;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN;
@@ -1001,15 +986,14 @@ ef10_get_datapath_caps(
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
-			    MC_CMD_GET_CAPABILITIES_V5_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN,
+		MC_CMD_GET_CAPABILITIES_V5_OUT_LEN);
 	efx_rc_t rc;
 
 	if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
 		goto fail1;
 
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_CAPABILITIES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
@@ -2046,8 +2030,8 @@ ef10_nic_reset(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
-			    MC_CMD_ENTITY_RESET_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN,
+		MC_CMD_ENTITY_RESET_OUT_LEN);
 	efx_rc_t rc;
 
 	/* ef10_nic_reset() is called to recover from BADASSERT failures. */
@@ -2056,7 +2040,6 @@ ef10_nic_reset(
 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
 		goto fail2;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_ENTITY_RESET;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
@@ -2393,11 +2376,10 @@ efx_mcdi_get_nic_global(
 	__out		uint32_t *valuep)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_NIC_GLOBAL_IN_LEN,
-			    MC_CMD_GET_NIC_GLOBAL_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN,
+		MC_CMD_GET_NIC_GLOBAL_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_NIC_GLOBAL;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN;
@@ -2437,10 +2419,9 @@ efx_mcdi_set_nic_global(
 	__in		uint32_t value)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MC_CMD_SET_NIC_GLOBAL_IN_LEN];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_NIC_GLOBAL;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_phy.c b/drivers/net/sfc/base/ef10_phy.c
index e9c7b40e4..a1f59ff1c 100644
--- a/drivers/net/sfc/base/ef10_phy.c
+++ b/drivers/net/sfc/base/ef10_phy.c
@@ -242,11 +242,10 @@ ef10_phy_get_link(
 	__out		ef10_link_state_t *elsp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
-			    MC_CMD_GET_LINK_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LINK_IN_LEN,
+		MC_CMD_GET_LINK_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_LINK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
@@ -301,8 +300,8 @@ ef10_phy_reconfigure(
 {
 	efx_port_t *epp = &(enp->en_port);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN,
-			    MC_CMD_SET_LINK_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_LINK_IN_LEN,
+		MC_CMD_SET_LINK_OUT_LEN);
 	uint32_t cap_mask;
 #if EFSYS_OPT_PHY_LED_CONTROL
 	unsigned int led_mode;
@@ -316,7 +315,6 @@ ef10_phy_reconfigure(
 	if (supported == B_FALSE)
 		goto out;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_LINK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
@@ -464,12 +462,11 @@ ef10_phy_verify(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
-			    MC_CMD_GET_PHY_STATE_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_STATE_IN_LEN,
+		MC_CMD_GET_PHY_STATE_OUT_LEN);
 	uint32_t state;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PHY_STATE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
@@ -587,7 +584,8 @@ ef10_bist_poll(
 	 * MCDI_CTL_SDU_LEN_MAX_V1 is large enough cover all BIST results,
 	 * whilst not wasting stack.
 	 */
-	uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN, MCDI_CTL_SDU_LEN_MAX_V1)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_POLL_BIST_IN_LEN,
+		MCDI_CTL_SDU_LEN_MAX_V1);
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
 	uint32_t value_mask = 0;
@@ -605,7 +603,6 @@ ef10_bist_poll(
 
 	_NOTE(ARGUNUSED(type))
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_POLL_BIST;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 313a36918..17678b517 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -29,8 +29,8 @@ efx_mcdi_init_rxq(
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_INIT_RXQ_V3_IN_LEN,
-			    MC_CMD_INIT_RXQ_V3_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_RXQ_V3_IN_LEN,
+		MC_CMD_INIT_RXQ_V3_OUT_LEN);
 	int npages = EFX_RXQ_NBUFS(ndescs);
 	int i;
 	efx_qword_t *dma_addr;
@@ -73,7 +73,6 @@ efx_mcdi_init_rxq(
 		want_outer_classes = B_FALSE;
 	}
 
-	(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_V3_IN_LEN;
@@ -146,11 +145,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;
@@ -188,8 +186,8 @@ efx_mcdi_rss_context_alloc(
 	__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;
@@ -211,7 +209,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;
@@ -274,8 +271,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) {
@@ -283,7 +280,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;
@@ -324,8 +320,8 @@ efx_mcdi_rss_context_set_flags(
 	efx_rx_hash_type_t type_ipv6_tcp;
 	efx_rx_hash_type_t modes;
 	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;
 
 	EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_LBN ==
@@ -350,7 +346,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;
@@ -439,8 +434,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) {
@@ -448,7 +443,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;
@@ -496,8 +490,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;
 
@@ -506,7 +500,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;
diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c
index 4d77d76d7..5f3df42b9 100644
--- a/drivers/net/sfc/base/ef10_tx.c
+++ b/drivers/net/sfc/base/ef10_tx.c
@@ -31,8 +31,8 @@ efx_mcdi_init_txq(
 	__in		efsys_mem_t *esmp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_MAX_BUFS),
-			    MC_CMD_INIT_TXQ_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_MAX_BUFS),
+		MC_CMD_INIT_TXQ_OUT_LEN);
 	efx_qword_t *dma_addr;
 	uint64_t addr;
 	int npages;
@@ -53,7 +53,6 @@ efx_mcdi_init_txq(
 		goto fail2;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_INIT_TXQ;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_INIT_TXQ_IN_LEN(npages);
@@ -120,11 +119,10 @@ efx_mcdi_fini_txq(
 	__in		uint32_t instance)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_FINI_TXQ_IN_LEN,
-			    MC_CMD_FINI_TXQ_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_TXQ_IN_LEN,
+		MC_CMD_FINI_TXQ_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_FINI_TXQ;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_FINI_TXQ_IN_LEN;
diff --git a/drivers/net/sfc/base/efx_lic.c b/drivers/net/sfc/base/efx_lic.c
index 2b06e2d1e..2a6da2647 100644
--- a/drivers/net/sfc/base/efx_lic.c
+++ b/drivers/net/sfc/base/efx_lic.c
@@ -301,12 +301,11 @@ efx_mcdi_fc_license_update_license(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_FC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
@@ -347,13 +346,12 @@ efx_mcdi_fc_license_get_key_stats(
 	__out		efx_key_stats_t *eksp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN,
-			    MC_CMD_FC_OUT_LICENSE_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
+		MC_CMD_FC_OUT_LICENSE_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_FC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
@@ -663,8 +661,8 @@ efx_mcdi_licensed_app_state(
 	__out		boolean_t *licensedp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
-			    MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
+		MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
 	uint32_t app_state;
 	efx_rc_t rc;
 
@@ -676,7 +674,6 @@ efx_mcdi_licensed_app_state(
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
@@ -722,12 +719,11 @@ efx_mcdi_licensing_update_licenses(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MC_CMD_LICENSING_IN_LEN];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_LICENSING;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
@@ -765,13 +761,12 @@ efx_mcdi_licensing_get_key_stats(
 	__out		efx_key_stats_t *eksp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN,
-			    MC_CMD_LICENSING_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
+		MC_CMD_LICENSING_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_LICENSING;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
@@ -829,13 +824,12 @@ efx_mcdi_licensing_v3_update_licenses(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_LICENSING_V3;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
@@ -866,14 +860,13 @@ efx_mcdi_licensing_v3_report_license(
 	__out		efx_key_stats_t *eksp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN,
-			    MC_CMD_LICENSING_V3_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
+		MC_CMD_LICENSING_V3_OUT_LEN);
 	efx_rc_t rc;
 
 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_LICENSING_V3;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
@@ -930,15 +923,14 @@ efx_mcdi_licensing_v3_app_state(
 	__out		boolean_t *licensedp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
-			    MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
+		MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
 	uint32_t app_state;
 	efx_rc_t rc;
 
 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
@@ -990,8 +982,8 @@ efx_mcdi_licensing_v3_get_id(
 			uint8_t *bufferp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
-			    MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
+		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
 	efx_rc_t rc;
 
 	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
@@ -1002,7 +994,6 @@ efx_mcdi_licensing_v3_get_id(
 		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
 		req.emr_out_buf = bufferp;
 		req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
-		(void) memset(payload, 0, sizeof (payload));
 	} else {
 		/* Request full buffer */
 		req.emr_in_buf = bufferp;
diff --git a/drivers/net/sfc/base/efx_mcdi.c b/drivers/net/sfc/base/efx_mcdi.c
index d4ebcf265..84d8452e4 100644
--- a/drivers/net/sfc/base/efx_mcdi.c
+++ b/drivers/net/sfc/base/efx_mcdi.c
@@ -900,10 +900,10 @@ efx_mcdi_version(
 	__out_opt		efx_mcdi_boot_t *statusp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MAX(MC_CMD_GET_VERSION_IN_LEN,
-				MC_CMD_GET_VERSION_OUT_LEN),
-			    MAX(MC_CMD_GET_BOOT_STATUS_IN_LEN,
-				MC_CMD_GET_BOOT_STATUS_OUT_LEN))];
+	EFX_MCDI_DECLARE_BUF(payload,
+		MAX(MC_CMD_GET_VERSION_IN_LEN, MC_CMD_GET_BOOT_STATUS_IN_LEN),
+		MAX(MC_CMD_GET_VERSION_OUT_LEN,
+			MC_CMD_GET_BOOT_STATUS_OUT_LEN));
 	efx_word_t *ver_words;
 	uint16_t version[4];
 	uint32_t build;
@@ -912,7 +912,6 @@ efx_mcdi_version(
 
 	EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_VERSION;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_VERSION_IN_LEN;
@@ -1018,12 +1017,11 @@ efx_mcdi_get_capabilities(
 	__out_opt	uint32_t *tso2ncp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
-			    MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN,
+		MC_CMD_GET_CAPABILITIES_V2_OUT_LEN);
 	boolean_t v2_capable;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_CAPABILITIES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
@@ -1086,7 +1084,8 @@ efx_mcdi_do_reboot(
 	__in		efx_nic_t *enp,
 	__in		boolean_t after_assertion)
 {
-	uint8_t payload[MAX(MC_CMD_REBOOT_IN_LEN, MC_CMD_REBOOT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_REBOOT_IN_LEN,
+		MC_CMD_REBOOT_OUT_LEN);
 	efx_mcdi_req_t req;
 	efx_rc_t rc;
 
@@ -1099,7 +1098,6 @@ efx_mcdi_do_reboot(
 	 */
 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_REBOOT;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
@@ -1150,8 +1148,8 @@ efx_mcdi_read_assertion(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
-			    MC_CMD_GET_ASSERTS_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_ASSERTS_IN_LEN,
+		MC_CMD_GET_ASSERTS_OUT_LEN);
 	const char *reason;
 	unsigned int flags;
 	unsigned int index;
@@ -1252,11 +1250,10 @@ efx_mcdi_drv_attach(
 	__in		boolean_t attach)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_DRV_ATTACH_IN_LEN,
-			    MC_CMD_DRV_ATTACH_EXT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRV_ATTACH_IN_LEN,
+		MC_CMD_DRV_ATTACH_EXT_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_DRV_ATTACH;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
@@ -1311,11 +1308,10 @@ efx_mcdi_get_board_cfg(
 {
 	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
-			    MC_CMD_GET_BOARD_CFG_OUT_LENMIN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_BOARD_CFG_IN_LEN,
+		MC_CMD_GET_BOARD_CFG_OUT_LENMIN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_BOARD_CFG;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
@@ -1391,11 +1387,10 @@ efx_mcdi_get_resource_limits(
 	__out_opt	uint32_t *ntxqp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
-			    MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
+		MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_RESOURCE_LIMITS_IN_LEN;
@@ -1438,8 +1433,8 @@ efx_mcdi_get_phy_cfg(
 	efx_port_t *epp = &(enp->en_port);
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PHY_CFG_IN_LEN,
-			    MC_CMD_GET_PHY_CFG_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_CFG_IN_LEN,
+		MC_CMD_GET_PHY_CFG_OUT_LEN);
 #if EFSYS_OPT_NAMES
 	const char *namep;
 	size_t namelen;
@@ -1447,7 +1442,6 @@ efx_mcdi_get_phy_cfg(
 	uint32_t phy_media_type;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PHY_CFG;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PHY_CFG_IN_LEN;
@@ -1686,11 +1680,10 @@ efx_mcdi_bist_start(
 	__in			efx_bist_type_t type)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_START_BIST_IN_LEN,
-			    MC_CMD_START_BIST_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_START_BIST_IN_LEN,
+		MC_CMD_START_BIST_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_START_BIST;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_START_BIST_IN_LEN;
@@ -1749,11 +1742,10 @@ efx_mcdi_log_ctrl(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_LOG_CTRL_IN_LEN,
-			    MC_CMD_LOG_CTRL_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LOG_CTRL_IN_LEN,
+		MC_CMD_LOG_CTRL_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_LOG_CTRL;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
@@ -1798,8 +1790,8 @@ efx_mcdi_mac_stats(
 	__in		uint16_t period_ms)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN,
-			    MC_CMD_MAC_STATS_V2_OUT_DMA_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_MAC_STATS_IN_LEN,
+		MC_CMD_MAC_STATS_V2_OUT_DMA_LEN);
 	int clear = (action == EFX_STATS_CLEAR);
 	int upload = (action == EFX_STATS_UPLOAD);
 	int enable = (action == EFX_STATS_ENABLE_NOEVENTS);
@@ -1807,7 +1799,6 @@ efx_mcdi_mac_stats(
 	int disable = (action == EFX_STATS_DISABLE);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_MAC_STATS;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_MAC_STATS_IN_LEN;
@@ -1979,11 +1970,10 @@ efx_mcdi_get_function_info(
 	__out_opt		uint32_t *vfp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_FUNCTION_INFO_IN_LEN,
-			    MC_CMD_GET_FUNCTION_INFO_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_FUNCTION_INFO_IN_LEN,
+		MC_CMD_GET_FUNCTION_INFO_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_FUNCTION_INFO;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_FUNCTION_INFO_IN_LEN;
@@ -2024,11 +2014,10 @@ efx_mcdi_privilege_mask(
 	__out			uint32_t *maskp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_PRIVILEGE_MASK_IN_LEN,
-			    MC_CMD_PRIVILEGE_MASK_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PRIVILEGE_MASK_IN_LEN,
+		MC_CMD_PRIVILEGE_MASK_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
@@ -2073,11 +2062,10 @@ efx_mcdi_set_workaround(
 	__out_opt		uint32_t *flagsp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_WORKAROUND_IN_LEN,
-			    MC_CMD_WORKAROUND_EXT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_WORKAROUND_IN_LEN,
+		MC_CMD_WORKAROUND_EXT_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_WORKAROUND;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_WORKAROUND_IN_LEN;
@@ -2117,10 +2105,9 @@ efx_mcdi_get_workarounds(
 	__out_opt		uint32_t *enabledp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MC_CMD_GET_WORKAROUNDS_OUT_LEN];
+	EFX_MCDI_DECLARE_BUF(payload, 0, MC_CMD_GET_WORKAROUNDS_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
 	req.emr_in_buf = NULL;
 	req.emr_in_length = 0;
@@ -2166,14 +2153,13 @@ efx_mcdi_get_phy_media_info(
 	__out_bcount(len)	uint8_t *data)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN,
-			    MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(
-				EFX_PHY_MEDIA_INFO_PAGE_SIZE))];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN,
+		MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(
+			EFX_PHY_MEDIA_INFO_PAGE_SIZE));
 	efx_rc_t rc;
 
 	EFSYS_ASSERT((uint32_t)offset + len <= EFX_PHY_MEDIA_INFO_PAGE_SIZE);
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PHY_MEDIA_INFO;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN;
diff --git a/drivers/net/sfc/base/efx_mcdi.h b/drivers/net/sfc/base/efx_mcdi.h
index d2cd1e9e1..40072405e 100644
--- a/drivers/net/sfc/base/efx_mcdi.h
+++ b/drivers/net/sfc/base/efx_mcdi.h
@@ -384,6 +384,17 @@ efx_mcdi_phy_module_get_info(
 	(((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) ==		\
 	(MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv))
 
+/*
+ * The buffer size must be a multiple of dword to ensure that MCDI works
+ * properly with Siena based boards (which use on-chip buffer). Also, it
+ * should be at minimum the size of two dwords to allow space for extended
+ * error responses if the request/response buffer sizes are smaller.
+ */
+#define EFX_MCDI_DECLARE_BUF(_name, _in_len, _out_len)			\
+	uint8_t _name[P2ROUNDUP(MAX(MAX(_in_len, _out_len),		\
+				    (2 * sizeof (efx_dword_t))),	\
+				sizeof (efx_dword_t))] = {0}
+
 typedef enum efx_mcdi_feature_id_e {
 	EFX_MCDI_FEATURE_FW_UPDATE = 0,
 	EFX_MCDI_FEATURE_LINK_CONTROL,
diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index 0e8ed9c2a..c364bffba 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -789,13 +789,12 @@ efx_mcdi_get_loopback_modes(
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
-			    MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
+		MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN);
 	efx_qword_t mask;
 	efx_qword_t modes;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c
index d7b1a6778..5296c59b8 100644
--- a/drivers/net/sfc/base/efx_nvram.c
+++ b/drivers/net/sfc/base/efx_nvram.c
@@ -514,12 +514,11 @@ efx_mcdi_nvram_partitions(
 	__out			unsigned int *npartnp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
-			    MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_PARTITIONS_IN_LEN,
+		MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
 	unsigned int npartn;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
@@ -577,11 +576,10 @@ efx_mcdi_nvram_metadata(
 	__in			size_t size)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
-			    MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_METADATA_IN_LEN,
+		MC_CMD_NVRAM_METADATA_OUT_LENMAX);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_METADATA;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
@@ -667,12 +665,11 @@ efx_mcdi_nvram_info(
 	__out_opt		uint32_t *erase_sizep,
 	__out_opt		uint32_t *write_sizep)
 {
-	uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
-			    MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_INFO_IN_LEN,
+		MC_CMD_NVRAM_INFO_V2_OUT_LEN);
 	efx_mcdi_req_t req;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_INFO;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
@@ -728,12 +725,11 @@ efx_mcdi_nvram_update_start(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn)
 {
-	uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
-			    MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
+		MC_CMD_NVRAM_UPDATE_START_OUT_LEN);
 	efx_mcdi_req_t req;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN;
@@ -770,8 +766,8 @@ efx_mcdi_nvram_read(
 	__in			uint32_t mode)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
-			    MC_CMD_NVRAM_READ_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_READ_IN_V2_LEN,
+		MC_CMD_NVRAM_READ_OUT_LENMAX);
 	efx_rc_t rc;
 
 	if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
@@ -779,7 +775,6 @@ efx_mcdi_nvram_read(
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_READ;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
@@ -825,11 +820,10 @@ efx_mcdi_nvram_erase(
 	__in			size_t size)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
-			    MC_CMD_NVRAM_ERASE_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_ERASE_IN_LEN,
+		MC_CMD_NVRAM_ERASE_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_ERASE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
@@ -939,12 +933,11 @@ efx_mcdi_nvram_update_finish(
 {
 	const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
-			    MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
+		MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN);
 	uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN;
@@ -1010,12 +1003,11 @@ efx_mcdi_nvram_test(
 	__in			uint32_t partn)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
-			    MC_CMD_NVRAM_TEST_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TEST_IN_LEN,
+		MC_CMD_NVRAM_TEST_OUT_LEN);
 	int result;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_TEST;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
diff --git a/drivers/net/sfc/base/efx_tunnel.c b/drivers/net/sfc/base/efx_tunnel.c
index 399fd540b..edb6be028 100644
--- a/drivers/net/sfc/base/efx_tunnel.c
+++ b/drivers/net/sfc/base/efx_tunnel.c
@@ -40,8 +40,9 @@ efx_mcdi_set_tunnel_encap_udp_ports(
 	__out			boolean_t *resetting)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX,
-			    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload,
+		MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX,
+		MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN);
 	efx_word_t flags;
 	efx_rc_t rc;
 	unsigned int i;
@@ -52,7 +53,6 @@ efx_mcdi_set_tunnel_encap_udp_ports(
 	else
 		entries_num = etcp->etc_udp_entries_num;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS;
 	req.emr_in_buf = payload;
 	req.emr_in_length =
diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 0e860168a..b53de0d68 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -191,8 +191,8 @@ efx_mcdi_read_sensors(
 	__in		uint32_t size)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN,
-			    MC_CMD_READ_SENSORS_EXT_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_READ_SENSORS_EXT_IN_LEN,
+		MC_CMD_READ_SENSORS_EXT_OUT_LEN);
 	uint32_t addr_lo, addr_hi;
 	efx_rc_t rc;
 
@@ -230,8 +230,8 @@ efx_mcdi_sensor_info_npages(
 	__out		uint32_t *npagesp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
-			    MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+		MC_CMD_SENSOR_INFO_OUT_LENMAX);
 	int page;
 	efx_rc_t rc;
 
@@ -274,8 +274,8 @@ efx_mcdi_sensor_info(
 	__in			size_t npages)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
-			    MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+		MC_CMD_SENSOR_INFO_OUT_LENMAX);
 	uint32_t page;
 	efx_rc_t rc;
 
@@ -343,8 +343,8 @@ efx_mcdi_sensor_info_page(
 				efx_mon_stat_limits_t *limits)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
-		MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+		MC_CMD_SENSOR_INFO_OUT_LENMAX);
 	efx_rc_t rc;
 	uint32_t mask_copy;
 	efx_dword_t *maskp;
@@ -356,7 +356,6 @@ efx_mcdi_sensor_info_page(
 	memset(limits, 0,
 	    ((sizeof (*mask_part) * 8) - 1) * sizeof (efx_mon_stat_limits_t));
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SENSOR_INFO;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
diff --git a/drivers/net/sfc/base/siena_mac.c b/drivers/net/sfc/base/siena_mac.c
index f8857cdd5..928dfc340 100644
--- a/drivers/net/sfc/base/siena_mac.c
+++ b/drivers/net/sfc/base/siena_mac.c
@@ -68,14 +68,13 @@ siena_mac_reconfigure(
 	efx_port_t *epp = &(enp->en_port);
 	efx_oword_t multicast_hash[2];
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,
-				MC_CMD_SET_MAC_OUT_LEN),
-			    MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,
-				MC_CMD_SET_MCAST_HASH_OUT_LEN))];
+	EFX_MCDI_DECLARE_BUF(payload,
+		MAX(MC_CMD_SET_MAC_IN_LEN, MC_CMD_SET_MCAST_HASH_IN_LEN),
+		MAX(MC_CMD_SET_MAC_OUT_LEN, MC_CMD_SET_MCAST_HASH_OUT_LEN));
+
 	unsigned int fcntl;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_MAC;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c
index 31eef80b9..8a58986e8 100644
--- a/drivers/net/sfc/base/siena_nic.c
+++ b/drivers/net/sfc/base/siena_nic.c
@@ -18,11 +18,10 @@ siena_nic_get_partn_mask(
 	__out			unsigned int *maskp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
-			    MC_CMD_NVRAM_TYPES_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
+		MC_CMD_NVRAM_TYPES_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_NVRAM_TYPES;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
diff --git a/drivers/net/sfc/base/siena_nvram.c b/drivers/net/sfc/base/siena_nvram.c
index 8cdd2df70..b8ea8a757 100644
--- a/drivers/net/sfc/base/siena_nvram.c
+++ b/drivers/net/sfc/base/siena_nvram.c
@@ -418,12 +418,11 @@ siena_nvram_get_subtype(
 	__out			uint32_t *subtypep)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
-			    MC_CMD_GET_BOARD_CFG_OUT_LENMAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_BOARD_CFG_IN_LEN,
+		MC_CMD_GET_BOARD_CFG_OUT_LENMAX);
 	efx_word_t *fw_list;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_BOARD_CFG;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
diff --git a/drivers/net/sfc/base/siena_phy.c b/drivers/net/sfc/base/siena_phy.c
index 4b2190d38..7eec9c747 100644
--- a/drivers/net/sfc/base/siena_phy.c
+++ b/drivers/net/sfc/base/siena_phy.c
@@ -169,11 +169,10 @@ siena_phy_get_link(
 	__out		siena_link_state_t *slsp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
-			    MC_CMD_GET_LINK_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LINK_IN_LEN,
+		MC_CMD_GET_LINK_OUT_LEN);
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_LINK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
@@ -244,10 +243,9 @@ siena_phy_reconfigure(
 {
 	efx_port_t *epp = &(enp->en_port);
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MAX(MC_CMD_SET_ID_LED_IN_LEN,
-				MC_CMD_SET_ID_LED_OUT_LEN),
-			    MAX(MC_CMD_SET_LINK_IN_LEN,
-				MC_CMD_SET_LINK_OUT_LEN))];
+	EFX_MCDI_DECLARE_BUF(payload,
+		MAX(MC_CMD_SET_ID_LED_IN_LEN, MC_CMD_SET_LINK_IN_LEN),
+		MAX(MC_CMD_SET_ID_LED_OUT_LEN, MC_CMD_SET_LINK_OUT_LEN));
 	uint32_t cap_mask;
 #if EFSYS_OPT_PHY_LED_CONTROL
 	unsigned int led_mode;
@@ -255,7 +253,6 @@ siena_phy_reconfigure(
 	unsigned int speed;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_SET_LINK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
@@ -361,12 +358,11 @@ siena_phy_verify(
 	__in		efx_nic_t *enp)
 {
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
-			    MC_CMD_GET_PHY_STATE_OUT_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_STATE_IN_LEN,
+		MC_CMD_GET_PHY_STATE_OUT_LEN);
 	uint32_t state;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_GET_PHY_STATE;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
@@ -530,8 +526,8 @@ siena_phy_stats_update(
 	uint32_t vmask = encp->enc_mcdi_phy_stat_mask;
 	uint64_t smask;
 	efx_mcdi_req_t req;
-	uint8_t payload[MAX(MC_CMD_PHY_STATS_IN_LEN,
-			    MC_CMD_PHY_STATS_OUT_DMA_LEN)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PHY_STATS_IN_LEN,
+		MC_CMD_PHY_STATS_OUT_DMA_LEN);
 	efx_rc_t rc;
 
 	if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_PHY_STATS_SIZE)) {
@@ -539,7 +535,6 @@ siena_phy_stats_update(
 		goto fail1;
 	}
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_PHY_STATS;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_PHY_STATS_IN_LEN;
@@ -626,14 +621,13 @@ siena_phy_bist_poll(
 	__in			size_t count)
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
-	uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
-			    MCDI_CTL_SDU_LEN_MAX)];
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_POLL_BIST_IN_LEN,
+		MCDI_CTL_SDU_LEN_MAX);
 	uint32_t value_mask = 0;
 	efx_mcdi_req_t req;
 	uint32_t result;
 	efx_rc_t rc;
 
-	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_POLL_BIST;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 24/37] net/sfc/base: add routine to check for hardware presence
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (22 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 23/37] net/sfc/base: fix out of bounds read when dereferencing sdup Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 25/37] net/sfc/base: add API to inform libefx of hardware removal Andrew Rybchenko
                   ` (13 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andy Moreton

From: Andy Moreton <amoreton@solarflare.com>

Add efx_nic_hw_unavailable() routine to check for hardware presence
before continuing with NIC operations.

Signed-off-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_ev.c   | 10 ++++++----
 drivers/net/sfc/base/ef10_impl.h |  4 ++++
 drivers/net/sfc/base/ef10_nic.c  | 22 ++++++++++++++++++++++
 drivers/net/sfc/base/efx.h       |  4 ++++
 drivers/net/sfc/base/efx_impl.h  |  2 ++
 drivers/net/sfc/base/efx_mcdi.c  |  6 ++++++
 drivers/net/sfc/base/efx_nic.c   | 27 +++++++++++++++++++++++++++
 7 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_ev.c b/drivers/net/sfc/base/ef10_ev.c
index 287550605..cdf835f03 100644
--- a/drivers/net/sfc/base/ef10_ev.c
+++ b/drivers/net/sfc/base/ef10_ev.c
@@ -863,8 +863,9 @@ 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 */
@@ -1064,8 +1065,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) {
diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 503f02362..0214a75ef 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -190,6 +190,10 @@ extern	__checkReturn	efx_rc_t
 ef10_nic_init(
 	__in		efx_nic_t *enp);
 
+extern	__checkReturn	boolean_t
+ef10_nic_hw_unavailable(
+	__in		efx_nic_t *enp);
+
 #if EFSYS_OPT_DIAG
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index 332f6ef81..ff96a7ff2 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -2304,6 +2304,28 @@ ef10_nic_get_bar_region(
 	return (rc);
 }
 
+	__checkReturn	boolean_t
+ef10_nic_hw_unavailable(
+	__in		efx_nic_t *enp)
+{
+	efx_dword_t dword;
+
+	if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
+		return (B_TRUE);
+
+	EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE);
+	if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
+		goto unavail;
+
+	return (B_FALSE);
+
+unavail:
+	EFSYS_PROBE(hw_unavail);
+	enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
+
+	return (B_TRUE);
+}
+
 			void
 ef10_nic_fini(
 	__in		efx_nic_t *enp)
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 2356a9294..fce519037 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -155,6 +155,10 @@ extern	__checkReturn	efx_rc_t
 efx_nic_reset(
 	__in		efx_nic_t *enp);
 
+extern	__checkReturn	boolean_t
+efx_nic_hw_unavailable(
+	__in		efx_nic_t *enp);
+
 #if EFSYS_OPT_DIAG
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 78df43018..8a7dc8cf6 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -59,6 +59,7 @@ extern "C" {
 #define	EFX_RESET_PHY		0x00000001
 #define	EFX_RESET_RXQ_ERR	0x00000002
 #define	EFX_RESET_TXQ_ERR	0x00000004
+#define	EFX_RESET_HW_UNAVAIL	0x00000008
 
 typedef enum efx_mac_type_e {
 	EFX_MAC_INVALID = 0,
@@ -356,6 +357,7 @@ typedef struct efx_nic_ops_s {
 	efx_rc_t	(*eno_get_vi_pool)(efx_nic_t *, uint32_t *);
 	efx_rc_t	(*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
 					uint32_t *, size_t *);
+	boolean_t	(*eno_hw_unavailable)(efx_nic_t *);
 #if EFSYS_OPT_DIAG
 	efx_rc_t	(*eno_register_test)(efx_nic_t *);
 #endif	/* EFSYS_OPT_DIAG */
diff --git a/drivers/net/sfc/base/efx_mcdi.c b/drivers/net/sfc/base/efx_mcdi.c
index 84d8452e4..c8d670c23 100644
--- a/drivers/net/sfc/base/efx_mcdi.c
+++ b/drivers/net/sfc/base/efx_mcdi.c
@@ -496,6 +496,12 @@ efx_mcdi_request_poll(
 	EFSYS_ASSERT(!emip->emi_ev_cpl);
 	emrp = emip->emi_pending_req;
 
+	/* Check if hardware is unavailable */
+	if (efx_nic_hw_unavailable(enp)) {
+		EFSYS_UNLOCK(enp->en_eslp, state);
+		return (B_FALSE);
+	}
+
 	/* Check for reboot atomically w.r.t efx_mcdi_request_start */
 	if (emip->emi_poll_cnt++ == 0) {
 		if ((rc = efx_mcdi_poll_reboot(enp)) != 0) {
diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index c364bffba..22e464a4e 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -100,6 +100,7 @@ static const efx_nic_ops_t	__efx_nic_siena_ops = {
 	siena_nic_init,			/* eno_init */
 	NULL,				/* eno_get_vi_pool */
 	NULL,				/* eno_get_bar_region */
+	NULL,				/* eno_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	siena_nic_register_test,	/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -119,6 +120,7 @@ static const efx_nic_ops_t	__efx_nic_hunt_ops = {
 	ef10_nic_init,			/* eno_init */
 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
+	ef10_nic_hw_unavailable,	/* eno_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	ef10_nic_register_test,		/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -138,6 +140,7 @@ static const efx_nic_ops_t	__efx_nic_medford_ops = {
 	ef10_nic_init,			/* eno_init */
 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
+	ef10_nic_hw_unavailable,	/* eno_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	ef10_nic_register_test,		/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -157,6 +160,7 @@ static const efx_nic_ops_t	__efx_nic_medford2_ops = {
 	ef10_nic_init,			/* eno_init */
 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
+	ef10_nic_hw_unavailable,	/* eno_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	ef10_nic_register_test,		/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -652,6 +656,29 @@ efx_nic_get_fw_version(
 	return (rc);
 }
 
+	__checkReturn	boolean_t
+efx_nic_hw_unavailable(
+	__in		efx_nic_t *enp)
+{
+	const efx_nic_ops_t *enop = enp->en_enop;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	/* NOTE: can be used by MCDI before NIC probe */
+
+	if (enop->eno_hw_unavailable != NULL) {
+		if ((enop->eno_hw_unavailable)(enp) != B_FALSE)
+			goto unavail;
+	}
+
+	return (B_FALSE);
+
+unavail:
+	EFSYS_PROBE(hw_unavail);
+
+	return (B_TRUE);
+}
+
+
 #if EFSYS_OPT_DIAG
 
 	__checkReturn	efx_rc_t
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 25/37] net/sfc/base: add API to inform libefx of hardware removal
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (23 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 24/37] net/sfc/base: add routine to check for hardware presence Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 26/37] net/sfc/base: fix ID retrival in v3 licensing Andrew Rybchenko
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andy Moreton

From: Andy Moreton <amoreton@solarflare.com>

The efx_nic_hw_unavailable() checks ensure that if the NIC hardware
has failed or has been physically removed then libefx will stop
further attempts to access the hardware.

Add an interface for libefx clients to force unavailability, so the
hardware is treated as dead or removed even if still physically present.

Signed-off-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h |  4 ++++
 drivers/net/sfc/base/ef10_nic.c  | 12 ++++++++++--
 drivers/net/sfc/base/efx.h       |  4 ++++
 drivers/net/sfc/base/efx_impl.h  |  1 +
 drivers/net/sfc/base/efx_nic.c   | 18 ++++++++++++++++--
 5 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 0214a75ef..2819ae6ed 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -194,6 +194,10 @@ extern	__checkReturn	boolean_t
 ef10_nic_hw_unavailable(
 	__in		efx_nic_t *enp);
 
+extern			void
+ef10_nic_set_hw_unavailable(
+	__in		efx_nic_t *enp);
+
 #if EFSYS_OPT_DIAG
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index ff96a7ff2..0a2474f3e 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -2320,12 +2320,20 @@ ef10_nic_hw_unavailable(
 	return (B_FALSE);
 
 unavail:
-	EFSYS_PROBE(hw_unavail);
-	enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
+	ef10_nic_set_hw_unavailable(enp);
 
 	return (B_TRUE);
 }
 
+			void
+ef10_nic_set_hw_unavailable(
+	__in		efx_nic_t *enp)
+{
+	EFSYS_PROBE(hw_unavail);
+	enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
+}
+
+
 			void
 ef10_nic_fini(
 	__in		efx_nic_t *enp)
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index fce519037..0982a34d6 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -159,6 +159,10 @@ extern	__checkReturn	boolean_t
 efx_nic_hw_unavailable(
 	__in		efx_nic_t *enp);
 
+extern			void
+efx_nic_set_hw_unavailable(
+	__in		efx_nic_t *enp);
+
 #if EFSYS_OPT_DIAG
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 8a7dc8cf6..2c95571b1 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -358,6 +358,7 @@ typedef struct efx_nic_ops_s {
 	efx_rc_t	(*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
 					uint32_t *, size_t *);
 	boolean_t	(*eno_hw_unavailable)(efx_nic_t *);
+	void		(*eno_set_hw_unavailable)(efx_nic_t *);
 #if EFSYS_OPT_DIAG
 	efx_rc_t	(*eno_register_test)(efx_nic_t *);
 #endif	/* EFSYS_OPT_DIAG */
diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index 22e464a4e..e5cb0105f 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -101,6 +101,7 @@ static const efx_nic_ops_t	__efx_nic_siena_ops = {
 	NULL,				/* eno_get_vi_pool */
 	NULL,				/* eno_get_bar_region */
 	NULL,				/* eno_hw_unavailable */
+	NULL,				/* eno_set_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	siena_nic_register_test,	/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -121,6 +122,7 @@ static const efx_nic_ops_t	__efx_nic_hunt_ops = {
 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
 	ef10_nic_hw_unavailable,	/* eno_hw_unavailable */
+	ef10_nic_set_hw_unavailable,	/* eno_set_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	ef10_nic_register_test,		/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -141,6 +143,7 @@ static const efx_nic_ops_t	__efx_nic_medford_ops = {
 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
 	ef10_nic_hw_unavailable,	/* eno_hw_unavailable */
+	ef10_nic_set_hw_unavailable,	/* eno_set_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	ef10_nic_register_test,		/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -161,6 +164,7 @@ static const efx_nic_ops_t	__efx_nic_medford2_ops = {
 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
 	ef10_nic_hw_unavailable,	/* eno_hw_unavailable */
+	ef10_nic_set_hw_unavailable,	/* eno_set_hw_unavailable */
 #if EFSYS_OPT_DIAG
 	ef10_nic_register_test,		/* eno_register_test */
 #endif	/* EFSYS_OPT_DIAG */
@@ -673,11 +677,21 @@ efx_nic_hw_unavailable(
 	return (B_FALSE);
 
 unavail:
-	EFSYS_PROBE(hw_unavail);
-
 	return (B_TRUE);
 }
 
+			void
+efx_nic_set_hw_unavailable(
+	__in		efx_nic_t *enp)
+{
+	const efx_nic_ops_t *enop = enp->en_enop;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	if (enop->eno_set_hw_unavailable != NULL)
+		enop->eno_set_hw_unavailable(enp);
+}
+
 
 #if EFSYS_OPT_DIAG
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 26/37] net/sfc/base: fix ID retrival in v3 licensing
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (24 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 25/37] net/sfc/base: add API to inform libefx of hardware removal Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 27/37] net/sfc/base: prevent access to the NIC config before probe Andrew Rybchenko
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andy Moreton, stable

From: Andy Moreton <amoreton@solarflare.com>

Fixes: 05fce2ce8451 ("net/sfc/base: import libefx licensing")
Fixes: f67e4719147d ("net/sfc/base: fix coding style")
Cc: stable@dpdk.org

Signed-off-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx_lic.c | 39 ++++++++--------------------------
 1 file changed, 9 insertions(+), 30 deletions(-)

diff --git a/drivers/net/sfc/base/efx_lic.c b/drivers/net/sfc/base/efx_lic.c
index 2a6da2647..4081aef1b 100644
--- a/drivers/net/sfc/base/efx_lic.c
+++ b/drivers/net/sfc/base/efx_lic.c
@@ -983,26 +983,14 @@ efx_mcdi_licensing_v3_get_id(
 {
 	efx_mcdi_req_t req;
 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
-		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
+		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
 	efx_rc_t rc;
 
 	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
-
-	if (bufferp == NULL) {
-		/* Request id type and length only */
-		req.emr_in_buf = bufferp;
-		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
-		req.emr_out_buf = bufferp;
-		req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
-	} else {
-		/* Request full buffer */
-		req.emr_in_buf = bufferp;
-		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
-		req.emr_out_buf = bufferp;
-		req.emr_out_length =
-		    MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
-		(void) memset(bufferp, 0, req.emr_out_length);
-	}
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX;
 
 	efx_mcdi_execute_quiet(enp, &req);
 
@@ -1020,19 +1008,10 @@ efx_mcdi_licensing_v3_get_id(
 	*lengthp =
 	    MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
 
-	if (bufferp == NULL) {
-		/*
-		 * Modify length requirements to indicate to caller the extra
-		 * buffering needed to read the complete output.
-		 */
-		*lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
-	} else {
-		/* Shift ID down to start of buffer */
-		memmove(bufferp,
-		    bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
-		    *lengthp);
-		memset(bufferp + (*lengthp), 0,
-		    MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
+	if (bufferp != NULL) {
+		memcpy(bufferp,
+		    payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
+		    MIN(buffer_size, *lengthp));
 	}
 
 	return (0);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 27/37] net/sfc/base: prevent access to the NIC config before probe
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (25 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 26/37] net/sfc/base: fix ID retrival in v3 licensing Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 28/37] net/sfc/base: fix name of the argument to store RSS flags Andrew Rybchenko
                   ` (10 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Mark Spender, stable

From: Mark Spender <mspender@solarflare.com>

NIC config is initialized during NIC probe.

Fixes: 19b64c6ac35f ("net/sfc/base: import libefx base")
Cc: stable@dpdk.org

Signed-off-by: Mark Spender <mspender@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx_nic.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index e5cb0105f..cea32b792 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -595,6 +595,7 @@ efx_nic_cfg_get(
 	__in		efx_nic_t *enp)
 {
 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
 
 	return (&(enp->en_nic_cfg));
 }
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 28/37] net/sfc/base: fix name of the argument to store RSS flags
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (26 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 27/37] net/sfc/base: prevent access to the NIC config before probe Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 29/37] net/sfc/base: fix a typo in unicast filter insertion comment Andrew Rybchenko
                   ` (9 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov, stable

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

The function used to retrieve supported RSS flags has an
argument which should be named properly to indicate
that it's a pointer.

Fixes: 613cbe75ae99 ("net/sfc/base: add a new means to control RSS hash")
Cc: stable@dpdk.org

Signed-off-by: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h    | 2 +-
 drivers/net/sfc/base/efx_rx.c | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 0982a34d6..15b3882dd 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2368,7 +2368,7 @@ extern	__checkReturn				efx_rc_t
 efx_rx_scale_hash_flags_get(
 	__in					efx_nic_t *enp,
 	__in					efx_rx_hash_alg_t hash_alg,
-	__inout_ecount(EFX_RX_HASH_NFLAGS)	unsigned int *flags,
+	__inout_ecount(EFX_RX_HASH_NFLAGS)	unsigned int *flagsp,
 	__out					unsigned int *nflagsp);
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index 09933b41a..7b9f28664 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -298,16 +298,16 @@ efx_rx_scatter_enable(
 efx_rx_scale_hash_flags_get(
 	__in					efx_nic_t *enp,
 	__in					efx_rx_hash_alg_t hash_alg,
-	__inout_ecount(EFX_RX_HASH_NFLAGS)	unsigned int *flags,
+	__inout_ecount(EFX_RX_HASH_NFLAGS)	unsigned int *flagsp,
 	__out					unsigned int *nflagsp)
 {
 	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
 	boolean_t l4;
 	boolean_t additional_modes;
-	unsigned int *entryp = flags;
+	unsigned int *entryp = flagsp;
 	efx_rc_t rc;
 
-	if (flags == NULL || nflagsp == NULL) {
+	if (flagsp == NULL || nflagsp == NULL) {
 		rc = EINVAL;
 		goto fail1;
 	}
@@ -368,7 +368,7 @@ efx_rx_scale_hash_flags_get(
 
 #undef LIST_FLAGS
 
-	*nflagsp = (unsigned int)(entryp - flags);
+	*nflagsp = (unsigned int)(entryp - flagsp);
 	EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS);
 
 	return (0);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 29/37] net/sfc/base: fix a typo in unicast filter insertion comment
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (27 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 28/37] net/sfc/base: fix name of the argument to store RSS flags Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 30/37] net/sfc/base: add support to get active FEC type Andrew Rybchenko
                   ` (8 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov, stable

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

Fixes: e7cd430c864f ("net/sfc/base: import SFN7xxx family support")
Cc: stable@dpdk.org

Signed-off-by: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_filter.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/ef10_filter.c b/drivers/net/sfc/base/ef10_filter.c
index 30a4892df..afe4064d9 100644
--- a/drivers/net/sfc/base/ef10_filter.c
+++ b/drivers/net/sfc/base/ef10_filter.c
@@ -1578,7 +1578,7 @@ ef10_filter_reconfigure(
 	/*
 	 * Insert or renew unicast filters.
 	 *
-	 * Frimware does not perform chaining on unicast filters. As traffic is
+	 * Firmware does not perform chaining on unicast filters. As traffic is
 	 * therefore only delivered to the first matching filter, we should
 	 * always insert the specific filter for our MAC address, to try and
 	 * ensure we get that traffic.
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 30/37] net/sfc/base: add support to get active FEC type
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (28 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 29/37] net/sfc/base: fix a typo in unicast filter insertion comment Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 31/37] net/sfc/base: use simpler code to check hash algorithm type Andrew Rybchenko
                   ` (7 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Vijay Srivastava

From: Vijay Srivastava <vijays@solarflare.com>

Signed-off-by: Vijay Srivastava <vijays@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h |  6 ++++
 drivers/net/sfc/base/ef10_phy.c  | 60 +++++++++++++++++++++++++++++---
 drivers/net/sfc/base/efx.h       | 11 ++++++
 drivers/net/sfc/base/efx_impl.h  |  1 +
 drivers/net/sfc/base/efx_phy.c   | 39 ++++++++++++++++++++-
 5 files changed, 111 insertions(+), 6 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 2819ae6ed..b72e7d256 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -596,6 +596,7 @@ typedef struct ef10_link_state_s {
 	uint32_t		els_adv_cap_mask;
 	uint32_t		els_lp_cap_mask;
 	unsigned int		els_fcntl;
+	efx_phy_fec_type_t	els_fec;
 	efx_link_mode_t		els_link_mode;
 #if EFSYS_OPT_LOOPBACK
 	efx_loopback_type_t	els_loopback;
@@ -632,6 +633,11 @@ ef10_phy_oui_get(
 	__in		efx_nic_t *enp,
 	__out		uint32_t *ouip);
 
+extern	__checkReturn	efx_rc_t
+ef10_phy_fec_type_get(
+	__in		efx_nic_t *enp,
+	__out		efx_phy_fec_type_t *fecp);
+
 #if EFSYS_OPT_PHY_STATS
 
 extern	__checkReturn			efx_rc_t
diff --git a/drivers/net/sfc/base/ef10_phy.c b/drivers/net/sfc/base/ef10_phy.c
index a1f59ff1c..ec3600e96 100644
--- a/drivers/net/sfc/base/ef10_phy.c
+++ b/drivers/net/sfc/base/ef10_phy.c
@@ -98,8 +98,10 @@ mcdi_phy_decode_link_mode(
 	__in		uint32_t link_flags,
 	__in		unsigned int speed,
 	__in		unsigned int fcntl,
+	__in		uint32_t fec,
 	__out		efx_link_mode_t *link_modep,
-	__out		unsigned int *fcntlp)
+	__out		unsigned int *fcntlp,
+	__out		efx_phy_fec_type_t *fecp)
 {
 	boolean_t fd = !!(link_flags &
 		    (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
@@ -141,6 +143,22 @@ mcdi_phy_decode_link_mode(
 		EFSYS_PROBE1(mc_pcol_error, int, fcntl);
 		*fcntlp = 0;
 	}
+
+	switch (fec) {
+	case MC_CMD_FEC_NONE:
+		*fecp = EFX_PHY_FEC_NONE;
+		break;
+	case MC_CMD_FEC_BASER:
+		*fecp = EFX_PHY_FEC_BASER;
+		break;
+	case MC_CMD_FEC_RS:
+		*fecp = EFX_PHY_FEC_RS;
+		break;
+	default:
+		EFSYS_PROBE1(mc_pcol_error, int, fec);
+		*fecp = EFX_PHY_FEC_NONE;
+		break;
+	}
 }
 
 
@@ -154,6 +172,7 @@ ef10_phy_link_ev(
 	unsigned int link_flags;
 	unsigned int speed;
 	unsigned int fcntl;
+	efx_phy_fec_type_t fec = MC_CMD_FEC_NONE;
 	efx_link_mode_t link_mode;
 	uint32_t lp_cap_mask;
 
@@ -191,7 +210,8 @@ ef10_phy_link_ev(
 	link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
 	mcdi_phy_decode_link_mode(enp, link_flags, speed,
 				    MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),
-				    &link_mode, &fcntl);
+				    MC_CMD_FEC_NONE, &link_mode,
+				    &fcntl, &fec);
 	mcdi_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
 			    &lp_cap_mask);
 
@@ -242,15 +262,16 @@ ef10_phy_get_link(
 	__out		ef10_link_state_t *elsp)
 {
 	efx_mcdi_req_t req;
+	uint32_t fec;
 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LINK_IN_LEN,
-		MC_CMD_GET_LINK_OUT_LEN);
+		MC_CMD_GET_LINK_OUT_V2_LEN);
 	efx_rc_t rc;
 
 	req.emr_cmd = MC_CMD_GET_LINK;
 	req.emr_in_buf = payload;
 	req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
 	req.emr_out_buf = payload;
-	req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
+	req.emr_out_length = MC_CMD_GET_LINK_OUT_V2_LEN;
 
 	efx_mcdi_execute(enp, &req);
 
@@ -269,10 +290,16 @@ ef10_phy_get_link(
 	mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
 			    &elsp->els_lp_cap_mask);
 
+	if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_V2_LEN)
+		fec = MC_CMD_FEC_NONE;
+	else
+		fec = MCDI_OUT_DWORD(req, GET_LINK_OUT_V2_FEC_TYPE);
+
 	mcdi_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),
 			    MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED),
 			    MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL),
-			    &elsp->els_link_mode, &elsp->els_fcntl);
+			    fec, &elsp->els_link_mode,
+			    &elsp->els_fcntl, &elsp->els_fec);
 
 #if EFSYS_OPT_LOOPBACK
 	/*
@@ -515,6 +542,29 @@ ef10_phy_oui_get(
 	return (ENOTSUP);
 }
 
+	__checkReturn	efx_rc_t
+ef10_phy_fec_type_get(
+	__in		efx_nic_t *enp,
+	__out		efx_phy_fec_type_t  *fecp)
+{
+	efx_rc_t rc;
+	ef10_link_state_t els;
+
+	/* Obtain the active FEC type */
+	if ((rc = ef10_phy_get_link(enp, &els)) != 0)
+		goto fail1;
+
+	*fecp = els.els_fec;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+
 #if EFSYS_OPT_PHY_STATS
 
 	__checkReturn				efx_rc_t
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 15b3882dd..cc68f744e 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -3202,6 +3202,17 @@ efx_nic_set_fw_subvariant(
 
 #endif	/* EFSYS_OPT_FW_SUBVARIANT_AWARE */
 
+typedef enum efx_phy_fec_type_e {
+	EFX_PHY_FEC_NONE = 0,
+	EFX_PHY_FEC_BASER,
+	EFX_PHY_FEC_RS
+} efx_phy_fec_type_t;
+
+extern	__checkReturn	efx_rc_t
+efx_phy_fec_type_get(
+	__in		efx_nic_t *enp,
+	__out		efx_phy_fec_type_t *typep);
+
 #ifdef	__cplusplus
 }
 #endif
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 2c95571b1..9f44d2f64 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -224,6 +224,7 @@ typedef struct efx_phy_ops_s {
 	efx_rc_t	(*epo_reconfigure)(efx_nic_t *);
 	efx_rc_t	(*epo_verify)(efx_nic_t *);
 	efx_rc_t	(*epo_oui_get)(efx_nic_t *, uint32_t *);
+	efx_rc_t	(*epo_fec_type_get)(efx_nic_t *, efx_phy_fec_type_t *);
 #if EFSYS_OPT_PHY_STATS
 	efx_rc_t	(*epo_stats_update)(efx_nic_t *, efsys_mem_t *,
 					    uint32_t *);
diff --git a/drivers/net/sfc/base/efx_phy.c b/drivers/net/sfc/base/efx_phy.c
index ba2f51c17..7c341e429 100644
--- a/drivers/net/sfc/base/efx_phy.c
+++ b/drivers/net/sfc/base/efx_phy.c
@@ -15,6 +15,7 @@ static const efx_phy_ops_t	__efx_phy_siena_ops = {
 	siena_phy_reconfigure,		/* epo_reconfigure */
 	siena_phy_verify,		/* epo_verify */
 	siena_phy_oui_get,		/* epo_oui_get */
+	NULL,				/* epo_fec_type_get */
 #if EFSYS_OPT_PHY_STATS
 	siena_phy_stats_update,		/* epo_stats_update */
 #endif	/* EFSYS_OPT_PHY_STATS */
@@ -34,6 +35,7 @@ static const efx_phy_ops_t	__efx_phy_ef10_ops = {
 	ef10_phy_reconfigure,		/* epo_reconfigure */
 	ef10_phy_verify,		/* epo_verify */
 	ef10_phy_oui_get,		/* epo_oui_get */
+	ef10_phy_fec_type_get,		/* epo_fec_type_get */
 #if EFSYS_OPT_PHY_STATS
 	ef10_phy_stats_update,		/* epo_stats_update */
 #endif	/* EFSYS_OPT_PHY_STATS */
@@ -190,6 +192,11 @@ efx_phy_adv_cap_get(
 	}
 }
 
+#define	EFX_PHY_CAP_FEC_REQ_MASK			\
+	(1U << EFX_PHY_CAP_BASER_FEC_REQUESTED)	|	\
+	(1U << EFX_PHY_CAP_RS_FEC_REQUESTED)	|	\
+	(1U << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED)
+
 	__checkReturn	efx_rc_t
 efx_phy_adv_cap_set(
 	__in		efx_nic_t *enp,
@@ -203,7 +210,8 @@ efx_phy_adv_cap_set(
 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 
-	if ((mask & ~epp->ep_phy_cap_mask) != 0) {
+	/* Ignore don't care bits of FEC (FEC EFX_PHY_CAP_*_REQUESTED) */
+	if ((mask & ~(epp->ep_phy_cap_mask | EFX_PHY_CAP_FEC_REQ_MASK)) != 0) {
 		rc = ENOTSUP;
 		goto fail1;
 	}
@@ -306,6 +314,35 @@ efx_phy_module_get_info(
 
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn		efx_rc_t
+efx_phy_fec_type_get(
+	__in		efx_nic_t *enp,
+	__out		efx_phy_fec_type_t *typep)
+{
+	efx_port_t *epp = &(enp->en_port);
+	const efx_phy_ops_t *epop = epp->ep_epop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+	if (epop->epo_fec_type_get == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = epop->epo_fec_type_get(enp, typep)) != 0)
+		goto fail2;
+
+	return (0);
+
 fail2:
 	EFSYS_PROBE(fail2);
 fail1:
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 31/37] net/sfc/base: use simpler code to check hash algorithm type
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (29 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 30/37] net/sfc/base: add support to get active FEC type Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 32/37] net/sfc/base: check buffer size for hash flags Andrew Rybchenko
                   ` (6 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

The API which is used to list supported hash flags verifies
hash algorithm choice before writing the output. This check
is based on a switch() statement which has only two options
and no distinctive actions to be conducted for each of them.
Use simpler code instead of switch() to improve readability.

Signed-off-by: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx_rx.c | 39 ++++++++++++-----------------------
 1 file changed, 13 insertions(+), 26 deletions(-)

diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index 7b9f28664..dfd3974da 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -312,6 +312,11 @@ efx_rx_scale_hash_flags_get(
 		goto fail1;
 	}
 
+	if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) {
+		*nflagsp = 0;
+		return 0;
+	}
+
 	l4 = encp->enc_rx_scale_l4_hash_supported;
 	additional_modes = encp->enc_rx_scale_additional_modes_supported;
 
@@ -340,32 +345,17 @@ efx_rx_scale_hash_flags_get(
 		_NOTE(CONSTANTCONDITION)				\
 	} while (B_FALSE)
 
-	switch (hash_alg) {
-	case EFX_RX_HASHALG_PACKED_STREAM:
-		if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0)
-			break;
-		/* FALLTHRU */
-	case EFX_RX_HASHALG_TOEPLITZ:
-		if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0)
-			break;
+	LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes);
+	LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes);
 
-		LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes);
-		LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes);
-
-		if (additional_modes) {
-			LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes);
-			LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes);
-		}
-
-		LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes);
-		LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes);
-		break;
-
-	default:
-		rc = EINVAL;
-		goto fail2;
+	if (additional_modes) {
+		LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes);
+		LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes);
 	}
 
+	LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes);
+	LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes);
+
 #undef LIST_FLAGS
 
 	*nflagsp = (unsigned int)(entryp - flagsp);
@@ -373,9 +363,6 @@ efx_rx_scale_hash_flags_get(
 
 	return (0);
 
-fail2:
-	EFSYS_PROBE(fail2);
-
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 32/37] net/sfc/base: check buffer size for hash flags
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (30 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 31/37] net/sfc/base: use simpler code to check hash algorithm type Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 33/37] net/sfc/base: simplify the code to parse RSS hash type Andrew Rybchenko
                   ` (5 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

The efx_rx_scale_hash_flags_get interface is unsafe, as it does not
have an argument for the size of the output buffer used to return
the flags. While the only caller currently supplies a sufficiently
large buffer, this should be checked at runtime to avoid writing
past the end of the buffer.

Signed-off-by: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h        |   3 +-
 drivers/net/sfc/base/efx_annote.h |   1 +
 drivers/net/sfc/base/efx_rx.c     | 120 +++++++++++++++++++-----------
 drivers/net/sfc/sfc_rx.c          |   2 +-
 4 files changed, 81 insertions(+), 45 deletions(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index cc68f744e..de62b7d50 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2368,7 +2368,8 @@ extern	__checkReturn				efx_rc_t
 efx_rx_scale_hash_flags_get(
 	__in					efx_nic_t *enp,
 	__in					efx_rx_hash_alg_t hash_alg,
-	__inout_ecount(EFX_RX_HASH_NFLAGS)	unsigned int *flagsp,
+	__out_ecount_part(max_nflags, *nflagsp)	unsigned int *flagsp,
+	__in					unsigned int max_nflags,
 	__out					unsigned int *nflagsp);
 
 extern	__checkReturn	efx_rc_t
diff --git a/drivers/net/sfc/base/efx_annote.h b/drivers/net/sfc/base/efx_annote.h
index 671aaed3b..607b43c77 100644
--- a/drivers/net/sfc/base/efx_annote.h
+++ b/drivers/net/sfc/base/efx_annote.h
@@ -33,6 +33,7 @@
 #define	__out_opt
 #define	__out_ecount(_n)
 #define	__out_ecount_opt(_n)
+#define	__out_ecount_part(_n, _l)
 #define	__out_bcount(_n)
 #define	__out_bcount_opt(_n)
 #define	__out_bcount_part(_n, _l)
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index dfd3974da..bb0c144d7 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -298,13 +298,12 @@ efx_rx_scatter_enable(
 efx_rx_scale_hash_flags_get(
 	__in					efx_nic_t *enp,
 	__in					efx_rx_hash_alg_t hash_alg,
-	__inout_ecount(EFX_RX_HASH_NFLAGS)	unsigned int *flagsp,
+	__out_ecount_part(max_nflags, *nflagsp)	unsigned int *flagsp,
+	__in					unsigned int max_nflags,
 	__out					unsigned int *nflagsp)
 {
 	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
-	boolean_t l4;
-	boolean_t additional_modes;
-	unsigned int *entryp = flagsp;
+	unsigned int nflags = 0;
 	efx_rc_t rc;
 
 	if (flagsp == NULL || nflagsp == NULL) {
@@ -313,56 +312,90 @@ efx_rx_scale_hash_flags_get(
 	}
 
 	if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) {
-		*nflagsp = 0;
-		return 0;
+		nflags = 0;
+		goto done;
 	}
 
-	l4 = encp->enc_rx_scale_l4_hash_supported;
-	additional_modes = encp->enc_rx_scale_additional_modes_supported;
-
-#define	LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes)	\
-	do {								\
-		if (_l4_hashing) {					\
-			*(_entryp++) = EFX_RX_HASH(_class, 4TUPLE);	\
-									\
-			if (_additional_modes) {			\
-				*(_entryp++) =				\
-				    EFX_RX_HASH(_class, 2TUPLE_DST);	\
-				*(_entryp++) =				\
-				    EFX_RX_HASH(_class, 2TUPLE_SRC);	\
-			}						\
-		}							\
-									\
-		*(_entryp++) = EFX_RX_HASH(_class, 2TUPLE);		\
-									\
-		if (_additional_modes) {				\
-			*(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST);	\
-			*(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC);	\
-		}							\
-									\
-		*(_entryp++) = EFX_RX_HASH(_class, DISABLE);		\
-									\
-		_NOTE(CONSTANTCONDITION)				\
+	/* Helper to add flags word to flags array without buffer overflow */
+#define	INSERT_FLAGS(_flags)			\
+	do {					\
+		if (nflags >= max_nflags) {	\
+			rc = E2BIG;		\
+			goto fail2;		\
+		}				\
+		*(flagsp + nflags) = (_flags);	\
+		nflags++;			\
+						\
+		_NOTE(CONSTANTCONDITION)	\
 	} while (B_FALSE)
 
-	LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes);
-	LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes);
+	if (encp->enc_rx_scale_l4_hash_supported != B_FALSE) {
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 4TUPLE));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 4TUPLE));
+	}
+
+	if ((encp->enc_rx_scale_l4_hash_supported != B_FALSE) &&
+	    (encp->enc_rx_scale_additional_modes_supported != B_FALSE)) {
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE_SRC));
 
-	if (additional_modes) {
-		LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes);
-		LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes);
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 4TUPLE));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 4TUPLE));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE_SRC));
+	}
+
+	INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE));
+	INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE));
+
+	INSERT_FLAGS(EFX_RX_HASH(IPV4, 2TUPLE));
+	INSERT_FLAGS(EFX_RX_HASH(IPV6, 2TUPLE));
+
+	if (encp->enc_rx_scale_additional_modes_supported != B_FALSE) {
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 1TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 1TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 1TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 1TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 1TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 1TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 1TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 1TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV4, 1TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV4, 1TUPLE_SRC));
+
+		INSERT_FLAGS(EFX_RX_HASH(IPV6, 1TUPLE_DST));
+		INSERT_FLAGS(EFX_RX_HASH(IPV6, 1TUPLE_SRC));
 	}
 
-	LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes);
-	LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes);
+	INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, DISABLE));
+	INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, DISABLE));
+
+	INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, DISABLE));
+	INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, DISABLE));
 
-#undef LIST_FLAGS
+	INSERT_FLAGS(EFX_RX_HASH(IPV4, DISABLE));
+	INSERT_FLAGS(EFX_RX_HASH(IPV6, DISABLE));
 
-	*nflagsp = (unsigned int)(entryp - flagsp);
-	EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS);
+#undef INSERT_FLAGS
 
+done:
+	*nflagsp = nflags;
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
@@ -548,7 +581,8 @@ efx_rx_scale_mode_set(
 	/*
 	 * Get the list of supported hash flags and sanitise the input.
 	 */
-	rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags);
+	rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags,
+				    EFX_ARRAY_SIZE(type_flags), &type_nflags);
 	if (rc != 0)
 		goto fail2;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index d8503e201..68d5594ba 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -1200,7 +1200,7 @@ sfc_rx_hash_init(struct sfc_adapter *sa)
 		return EINVAL;
 
 	rc = efx_rx_scale_hash_flags_get(sa->nic, alg, flags_supp,
-					 &nb_flags_supp);
+					 RTE_DIM(flags_supp), &nb_flags_supp);
 	if (rc != 0)
 		return rc;
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 33/37] net/sfc/base: simplify the code to parse RSS hash type
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (31 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 32/37] net/sfc/base: check buffer size for hash flags Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags Andrew Rybchenko
                   ` (4 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

RSS mode bits can be accessed a lot easier in the hash
type value provided that the variable type is uint32_t.
The macro helper can be removed to enhance readability.

Signed-off-by: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_rx.c | 24 ++++++++++--------------
 drivers/net/sfc/base/efx.h     |  2 +-
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 17678b517..1444eca81 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -377,12 +377,6 @@ efx_mcdi_rss_context_set_flags(
 	if (encp->enc_rx_scale_additional_modes_supported == B_FALSE)
 		modes = 0;
 
-#define	EXTRACT_RSS_MODE(_type, _class)		\
-	(EFX_EXTRACT_NATIVE(_type, 0, 31,	\
-	EFX_LOW_BIT(EFX_RX_CLASS_##_class),	\
-	EFX_HIGH_BIT(EFX_RX_CLASS_##_class)) &	\
-	EFX_MASK32(EFX_RX_CLASS_##_class))
-
 	MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
 	    RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
 	    ((type & type_ipv4) == type_ipv4) ? 1 : 0,
@@ -393,19 +387,21 @@ efx_mcdi_rss_context_set_flags(
 	    RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
 	    ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0,
 	    RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE,
-	    EXTRACT_RSS_MODE(modes, IPV4_TCP),
+	    (modes >> EFX_RX_CLASS_IPV4_TCP_LBN) &
+	    EFX_MASK32(EFX_RX_CLASS_IPV4_TCP),
 	    RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE,
-	    EXTRACT_RSS_MODE(modes, IPV4_UDP),
+	    (modes >> EFX_RX_CLASS_IPV4_UDP_LBN) &
+	    EFX_MASK32(EFX_RX_CLASS_IPV4_UDP),
 	    RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE,
-	    EXTRACT_RSS_MODE(modes, IPV4),
+	    (modes >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4),
 	    RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE,
-	    EXTRACT_RSS_MODE(modes, IPV6_TCP),
+	    (modes >> EFX_RX_CLASS_IPV6_TCP_LBN) &
+	    EFX_MASK32(EFX_RX_CLASS_IPV6_TCP),
 	    RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE,
-	    EXTRACT_RSS_MODE(modes, IPV6_UDP),
+	    (modes >> EFX_RX_CLASS_IPV6_UDP_LBN) &
+	    EFX_MASK32(EFX_RX_CLASS_IPV6_UDP),
 	    RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE,
-	    EXTRACT_RSS_MODE(modes, IPV6));
-
-#undef EXTRACT_RSS_MODE
+	    (modes >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6));
 
 	efx_mcdi_execute(enp, &req);
 
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index de62b7d50..62c56e6e1 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2267,7 +2267,7 @@ typedef enum efx_rx_hash_alg_e {
  *  - a combination of legacy flags
  *  - a combination of EFX_RX_HASH() flags
  */
-typedef unsigned int efx_rx_hash_type_t;
+typedef uint32_t efx_rx_hash_type_t;
 
 typedef enum efx_rx_hash_support_e {
 	EFX_RX_HASH_UNAVAILABLE = 0,	/* Hardware hash not inserted */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (32 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 33/37] net/sfc/base: simplify the code to parse RSS hash type Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 35/37] net/sfc/base: modify phy caps to indicate FEC request Andrew Rybchenko
                   ` (3 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

Client drivers may use either legacy flags, for example,
EFX_RX_HASH_TCPIPV4, or generalised flags, for example,
EFX_RX_HASH(IPV4_TCP, 4TUPLE), to configure RSS hash.
The libefx is able to recognise what scheme is used.

Legacy flags may be consumed directly by a chip-specific handler to
configure the NIC, that is, on EF10, these flags can be used to fill
in legacy RSS mode field in MCDI request. Generalised flags can also
be directly used in EF10-specific handler as they are fully compatible
with additional fields of the same MCDI request.

Legacy flags undergo conversion to generalised flags before they
are consumed by a chip-specific handler. This conversion is used to
make sure that chip-specific handlers expect only generalised flags
in the input for the sake of clarity of the code.

Depending on firmware capabilities, a chip-specififc handler either
supplies the input to the NIC directly, for example,
EFX_RX_HASH(IPV4_TCP, 4TUPLE) flag will enable 4 bits in
RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE field on EF10, or takes
the opportunity to translate the input to enable bits which don't map
to the generic flag, like setting
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN on EF10 when the firmware
claims no support for additional modes.

However, this approach has introduced a severe problem which can be
reproduced with ultra-low-latency firmware variant. In order to enable
IP hash, EF10-specific handler requires the user to request 2-tuple
hash for IP-other, TCP and UDP traffic classes, unconditionally.
In example, IPv4 hash can be enabled using the following input:
EFX_RX_HASH(IPV4_TCP, 2TUPLE) | EFX_RX_HASH(IPV4_UDP, 2TUPLE) |
EFX_RX_HASH(IPV4, 2TUPLE).
At the same time, on ultra-low-latency firmware, the common code will
never report support for any UDP tuple to the client driver. That is,
in the same example, the driver will use EFX_RX_HASH(IPV4_TCP, 2TUPLE) |
EFX_RX_HASH(IPV4, 2TUPLE). This input will not be recognised by
EF10-specific handler, and RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN
bit will not be set in the MCDI request.

In order to solve the problem, the patch removes conversion code
from chip-specific handlers and adds appropriate code to convert
EFX_RX_HASH() flags to their legacy counterparts to the common scale
mode set function. If the firmware does not support additional modes,
the function will convert generalised flags to legacy flags correctly
without any demand for UDP flags and pass the result to a chip-specific
handler.

Signed-off-by: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_rx.c | 42 ++++-----------
 drivers/net/sfc/base/efx_rx.c  | 94 ++++++++++++++++++----------------
 2 files changed, 62 insertions(+), 74 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 1444eca81..3c8f4f3b9 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -314,11 +314,6 @@ efx_mcdi_rss_context_set_flags(
 	__in		efx_rx_hash_type_t type)
 {
 	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
-	efx_rx_hash_type_t type_ipv4;
-	efx_rx_hash_type_t type_ipv4_tcp;
-	efx_rx_hash_type_t type_ipv6;
-	efx_rx_hash_type_t type_ipv6_tcp;
-	efx_rx_hash_type_t modes;
 	efx_mcdi_req_t req;
 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
 		MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN);
@@ -355,53 +350,38 @@ efx_mcdi_rss_context_set_flags(
 	MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
 	    rss_context);
 
-	type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE) |
-		    EFX_RX_HASH(IPV4_UDP, 2TUPLE);
-	type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
-	type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE) |
-		    EFX_RX_HASH(IPV6_UDP, 2TUPLE);
-	type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
-
-	/*
-	 * Create a copy of the original hash type.
-	 * The copy will be used to fill in RSS_MODE bits and
-	 * may be cleared beforehand. The original variable
-	 * and, thus, EN bits will remain unaffected.
-	 */
-	modes = type;
-
 	/*
 	 * If the firmware lacks support for additional modes, RSS_MODE
 	 * fields must contain zeros, otherwise the operation will fail.
 	 */
 	if (encp->enc_rx_scale_additional_modes_supported == B_FALSE)
-		modes = 0;
+		type &= EFX_RX_HASH_LEGACY_MASK;
 
 	MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
 	    RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
-	    ((type & type_ipv4) == type_ipv4) ? 1 : 0,
+	    (type & EFX_RX_HASH_IPV4) ? 1 : 0,
 	    RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
-	    ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0,
+	    (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0,
 	    RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
-	    ((type & type_ipv6) == type_ipv6) ? 1 : 0,
+	    (type & EFX_RX_HASH_IPV6) ? 1 : 0,
 	    RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
-	    ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0,
+	    (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0,
 	    RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE,
-	    (modes >> EFX_RX_CLASS_IPV4_TCP_LBN) &
+	    (type >> EFX_RX_CLASS_IPV4_TCP_LBN) &
 	    EFX_MASK32(EFX_RX_CLASS_IPV4_TCP),
 	    RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE,
-	    (modes >> EFX_RX_CLASS_IPV4_UDP_LBN) &
+	    (type >> EFX_RX_CLASS_IPV4_UDP_LBN) &
 	    EFX_MASK32(EFX_RX_CLASS_IPV4_UDP),
 	    RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE,
-	    (modes >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4),
+	    (type >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4),
 	    RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE,
-	    (modes >> EFX_RX_CLASS_IPV6_TCP_LBN) &
+	    (type >> EFX_RX_CLASS_IPV6_TCP_LBN) &
 	    EFX_MASK32(EFX_RX_CLASS_IPV6_TCP),
 	    RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE,
-	    (modes >> EFX_RX_CLASS_IPV6_UDP_LBN) &
+	    (type >> EFX_RX_CLASS_IPV6_UDP_LBN) &
 	    EFX_MASK32(EFX_RX_CLASS_IPV6_UDP),
 	    RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE,
-	    (modes >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6));
+	    (type >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6));
 
 	efx_mcdi_execute(enp, &req);
 
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index bb0c144d7..04bc7aed8 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -532,9 +532,8 @@ efx_rx_scale_mode_set(
 	__in		efx_rx_hash_type_t type,
 	__in		boolean_t insert)
 {
+	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
 	const efx_rx_ops_t *erxop = enp->en_erxop;
-	unsigned int type_flags[EFX_RX_HASH_NFLAGS];
-	unsigned int type_nflags;
 	efx_rx_hash_type_t type_check;
 	unsigned int i;
 	efx_rc_t rc;
@@ -553,47 +552,60 @@ efx_rx_scale_mode_set(
 	}
 
 	/*
-	 * Translate legacy flags to the new representation
-	 * so that chip-specific handlers will consider the
-	 * new flags only.
+	 * If RSS hash type is represented by additional bits
+	 * in the value, the latter need to be verified since
+	 * not all bit combinations are valid RSS modes. Also,
+	 * depending on the firmware, some valid combinations
+	 * may be unsupported. Discern additional bits in the
+	 * type value and try to recognise valid combinations.
+	 * If some bits remain unrecognised, report the error.
 	 */
-	if (type & EFX_RX_HASH_IPV4) {
-		type |= EFX_RX_HASH(IPV4, 2TUPLE);
-		type |= EFX_RX_HASH(IPV4_TCP, 2TUPLE);
-		type |= EFX_RX_HASH(IPV4_UDP, 2TUPLE);
-	}
-
-	if (type & EFX_RX_HASH_TCPIPV4)
-		type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE);
+	type_check = type & ~EFX_RX_HASH_LEGACY_MASK;
+	if (type_check != 0) {
+		unsigned int type_flags[EFX_RX_HASH_NFLAGS];
+		unsigned int type_nflags;
 
-	if (type & EFX_RX_HASH_IPV6) {
-		type |= EFX_RX_HASH(IPV6, 2TUPLE);
-		type |= EFX_RX_HASH(IPV6_TCP, 2TUPLE);
-		type |= EFX_RX_HASH(IPV6_UDP, 2TUPLE);
-	}
+		rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags,
+				    EFX_ARRAY_SIZE(type_flags), &type_nflags);
+		if (rc != 0)
+			goto fail2;
 
-	if (type & EFX_RX_HASH_TCPIPV6)
-		type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE);
+		for (i = 0; i < type_nflags; ++i) {
+			if ((type_check & type_flags[i]) == type_flags[i])
+				type_check &= ~(type_flags[i]);
+		}
 
-	type &= ~EFX_RX_HASH_LEGACY_MASK;
-	type_check = type;
+		if (type_check != 0) {
+			rc = EINVAL;
+			goto fail3;
+		}
+	}
 
 	/*
-	 * Get the list of supported hash flags and sanitise the input.
+	 * Translate EFX_RX_HASH() flags to their legacy counterparts
+	 * provided that the FW claims no support for additional modes.
 	 */
-	rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags,
-				    EFX_ARRAY_SIZE(type_flags), &type_nflags);
-	if (rc != 0)
-		goto fail2;
-
-	for (i = 0; i < type_nflags; ++i) {
-		if ((type_check & type_flags[i]) == type_flags[i])
-			type_check &= ~(type_flags[i]);
-	}
+	if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) {
+		efx_rx_hash_type_t t_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) |
+					    EFX_RX_HASH(IPV4_TCP, 2TUPLE);
+		efx_rx_hash_type_t t_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) |
+					    EFX_RX_HASH(IPV6_TCP, 2TUPLE);
+		efx_rx_hash_type_t t_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
+		efx_rx_hash_type_t t_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
+
+		if ((type & t_ipv4) == t_ipv4)
+			type |= EFX_RX_HASH_IPV4;
+		if ((type & t_ipv6) == t_ipv6)
+			type |= EFX_RX_HASH_IPV6;
+
+		if (encp->enc_rx_scale_l4_hash_supported == B_TRUE) {
+			if ((type & t_ipv4_tcp) == t_ipv4_tcp)
+				type |= EFX_RX_HASH_TCPIPV4;
+			if ((type & t_ipv6_tcp) == t_ipv6_tcp)
+				type |= EFX_RX_HASH_TCPIPV6;
+		}
 
-	if (type_check != 0) {
-		rc = EINVAL;
-		goto fail3;
+		type &= EFX_RX_HASH_LEGACY_MASK;
 	}
 
 	if (erxop->erxo_scale_mode_set != NULL) {
@@ -1111,10 +1123,6 @@ siena_rx_scale_mode_set(
 	__in		efx_rx_hash_type_t type,
 	__in		boolean_t insert)
 {
-	efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE);
-	efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
-	efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE);
-	efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
 	efx_rc_t rc;
 
 	if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
@@ -1129,12 +1137,12 @@ siena_rx_scale_mode_set(
 
 	case EFX_RX_HASHALG_TOEPLITZ:
 		EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
-		    (type & type_ipv4) == type_ipv4,
-		    (type & type_ipv4_tcp) == type_ipv4_tcp);
+		    (type & EFX_RX_HASH_IPV4) ? B_TRUE : B_FALSE,
+		    (type & EFX_RX_HASH_TCPIPV4) ? B_TRUE : B_FALSE);
 
 		EFX_RX_TOEPLITZ_IPV6_HASH(enp,
-		    (type & type_ipv6) == type_ipv6,
-		    (type & type_ipv6_tcp) == type_ipv6_tcp,
+		    (type & EFX_RX_HASH_IPV6) ? B_TRUE : B_FALSE,
+		    (type & EFX_RX_HASH_TCPIPV6) ? B_TRUE : B_FALSE,
 		    rc);
 		if (rc != 0)
 			goto fail2;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 35/37] net/sfc/base: modify phy caps to indicate FEC request
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (33 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 36/37] net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes Andrew Rybchenko
                   ` (2 subsequent siblings)
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Richard Houldsworth

From: Richard Houldsworth <rhouldsworth@solarflare.com>

The capability bits to request FEC modes are implicitly valid
when the corresponding FEC mode is a supported capability.
Drivers expect that it is only valid to advertise those
capabilities explicitly marked as supported. The capabilities
reported by firmware is modified with the implicit capabilities
to present the explicit model to drivers.

Signed-off-by: Richard Houldsworth <rhouldsworth@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_nic.c | 15 +++++++++++++++
 drivers/net/sfc/base/efx_phy.c  |  8 +-------
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index 0a2474f3e..b54cd3940 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -1772,6 +1772,21 @@ ef10_nic_board_cfg(
 	if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
 		goto fail6;
 
+	/*
+	 * Firmware with support for *_FEC capability bits does not
+	 * report that the corresponding *_FEC_REQUESTED bits are supported.
+	 * Add them here so that drivers understand that they are supported.
+	 */
+	if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_BASER_FEC))
+		epp->ep_phy_cap_mask |=
+		    (1u << EFX_PHY_CAP_BASER_FEC_REQUESTED);
+	if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_RS_FEC))
+		epp->ep_phy_cap_mask |=
+		    (1u << EFX_PHY_CAP_RS_FEC_REQUESTED);
+	if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_25G_BASER_FEC))
+		epp->ep_phy_cap_mask |=
+		    (1u << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED);
+
 	/* Obtain the default PHY advertised capabilities */
 	if ((rc = ef10_phy_get_link(enp, &els)) != 0)
 		goto fail7;
diff --git a/drivers/net/sfc/base/efx_phy.c b/drivers/net/sfc/base/efx_phy.c
index 7c341e429..25059dfe1 100644
--- a/drivers/net/sfc/base/efx_phy.c
+++ b/drivers/net/sfc/base/efx_phy.c
@@ -192,11 +192,6 @@ efx_phy_adv_cap_get(
 	}
 }
 
-#define	EFX_PHY_CAP_FEC_REQ_MASK			\
-	(1U << EFX_PHY_CAP_BASER_FEC_REQUESTED)	|	\
-	(1U << EFX_PHY_CAP_RS_FEC_REQUESTED)	|	\
-	(1U << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED)
-
 	__checkReturn	efx_rc_t
 efx_phy_adv_cap_set(
 	__in		efx_nic_t *enp,
@@ -210,8 +205,7 @@ efx_phy_adv_cap_set(
 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 
-	/* Ignore don't care bits of FEC (FEC EFX_PHY_CAP_*_REQUESTED) */
-	if ((mask & ~(epp->ep_phy_cap_mask | EFX_PHY_CAP_FEC_REQ_MASK)) != 0) {
+	if ((mask & ~epp->ep_phy_cap_mask) != 0) {
 		rc = ENOTSUP;
 		goto fail1;
 	}
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 36/37] net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (34 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 35/37] net/sfc/base: modify phy caps to indicate FEC request Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-10  9:33 ` [PATCH 37/37] net/sfc/base: add helper API to make Geneve filter spec Andrew Rybchenko
  2018-09-21 10:28 ` [PATCH 00/37] net/sfc: update base driver Ferruh Yigit
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Andy Moreton, stable

From: Andy Moreton <amoreton@solarflare.com>

This statistic should include 64byte and smaller frames.
Fix EF10 calculation to match Siena code.

Fixes: 8c7c723dfe7c ("net/sfc/base: import MAC statistics")
Cc: stable@dpdk.org

Signed-off-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/ef10_mac.c b/drivers/net/sfc/base/ef10_mac.c
index a4a6d9ec8..ab73828f1 100644
--- a/drivers/net/sfc/base/ef10_mac.c
+++ b/drivers/net/sfc/base/ef10_mac.c
@@ -650,7 +650,7 @@ ef10_mac_stats_update(
 	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
 	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
-	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+	EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
 
 	EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
 	EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 37/37] net/sfc/base: add helper API to make Geneve filter spec
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (35 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 36/37] net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes Andrew Rybchenko
@ 2018-09-10  9:33 ` Andrew Rybchenko
  2018-09-21 10:28 ` [PATCH 00/37] net/sfc: update base driver Ferruh Yigit
  37 siblings, 0 replies; 39+ messages in thread
From: Andrew Rybchenko @ 2018-09-10  9:33 UTC (permalink / raw)
  To: dev; +Cc: Vijay Srivastava

From: Vijay Srivastava <vijays@solarflare.com>

Signed-off-by: Vijay Srivastava <vijays@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h        | 18 ++++++-
 drivers/net/sfc/base/efx_filter.c | 90 +++++++++++++++++++++++++++----
 2 files changed, 95 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 62c56e6e1..fd68d69c7 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2959,9 +2959,23 @@ efx_filter_spec_set_encap_type(
 	__in		efx_filter_inner_frame_match_t inner_frame_match);
 
 extern	__checkReturn	efx_rc_t
-efx_filter_spec_set_vxlan_full(
+efx_filter_spec_set_vxlan(
 	__inout		efx_filter_spec_t *spec,
-	__in		const uint8_t *vxlan_id,
+	__in		const uint8_t *vni,
+	__in		const uint8_t *inner_addr,
+	__in		const uint8_t *outer_addr);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_geneve(
+	__inout		efx_filter_spec_t *spec,
+	__in		const uint8_t *vni,
+	__in		const uint8_t *inner_addr,
+	__in		const uint8_t *outer_addr);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_nvgre(
+	__inout		efx_filter_spec_t *spec,
+	__in		const uint8_t *vsid,
 	__in		const uint8_t *inner_addr,
 	__in		const uint8_t *outer_addr);
 
diff --git a/drivers/net/sfc/base/efx_filter.c b/drivers/net/sfc/base/efx_filter.c
index 412298acf..a7523b38b 100644
--- a/drivers/net/sfc/base/efx_filter.c
+++ b/drivers/net/sfc/base/efx_filter.c
@@ -490,27 +490,42 @@ efx_filter_spec_set_encap_type(
 }
 
 /*
- * Specify inner and outer Ethernet address and VXLAN ID in filter
+ * Specify inner and outer Ethernet address and VNI or VSID in tunnel filter
  * specification.
  */
-	__checkReturn	efx_rc_t
-efx_filter_spec_set_vxlan_full(
-	__inout		efx_filter_spec_t *spec,
-	__in		const uint8_t *vxlan_id,
+static	__checkReturn	efx_rc_t
+efx_filter_spec_set_tunnel(
+	__inout	efx_filter_spec_t *spec,
+	__in		efx_tunnel_protocol_t encap_type,
+	__in		const uint8_t *vni_or_vsid,
 	__in		const uint8_t *inner_addr,
 	__in		const uint8_t *outer_addr)
 {
+	efx_rc_t rc;
+
 	EFSYS_ASSERT3P(spec, !=, NULL);
-	EFSYS_ASSERT3P(vxlan_id, !=, NULL);
+	EFSYS_ASSERT3P(vni_or_vsid, !=, NULL);
 	EFSYS_ASSERT3P(inner_addr, !=, NULL);
 	EFSYS_ASSERT3P(outer_addr, !=, NULL);
 
-	if ((inner_addr == NULL) && (outer_addr == NULL))
-		return (EINVAL);
+	switch (encap_type) {
+	case EFX_TUNNEL_PROTOCOL_VXLAN:
+	case EFX_TUNNEL_PROTOCOL_GENEVE:
+	case EFX_TUNNEL_PROTOCOL_NVGRE:
+		break;
+	default:
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if ((inner_addr == NULL) && (outer_addr == NULL)) {
+		rc = EINVAL;
+		goto fail2;
+	}
 
-	if (vxlan_id != NULL) {
+	if (vni_or_vsid != NULL) {
 		spec->efs_match_flags |= EFX_FILTER_MATCH_VNI_OR_VSID;
-		memcpy(spec->efs_vni_or_vsid, vxlan_id, EFX_VNI_OR_VSID_LEN);
+		memcpy(spec->efs_vni_or_vsid, vni_or_vsid, EFX_VNI_OR_VSID_LEN);
 	}
 	if (outer_addr != NULL) {
 		spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
@@ -520,10 +535,63 @@ efx_filter_spec_set_vxlan_full(
 		spec->efs_match_flags |= EFX_FILTER_MATCH_IFRM_LOC_MAC;
 		memcpy(spec->efs_ifrm_loc_mac, inner_addr, EFX_MAC_ADDR_LEN);
 	}
+
 	spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
-	spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_VXLAN;
+	spec->efs_encap_type = encap_type;
 
 	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+/*
+ * Specify inner and outer Ethernet address and VNI in VXLAN filter
+ * specification.
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_vxlan(
+	__inout		efx_filter_spec_t *spec,
+	__in		const uint8_t *vni,
+	__in		const uint8_t *inner_addr,
+	__in		const uint8_t *outer_addr)
+{
+	return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_VXLAN,
+	    vni, inner_addr, outer_addr);
+}
+
+/*
+ * Specify inner and outer Ethernet address and VNI in Geneve filter
+ * specification.
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_geneve(
+	__inout		efx_filter_spec_t *spec,
+	__in		const uint8_t *vni,
+	__in		const uint8_t *inner_addr,
+	__in		const uint8_t *outer_addr)
+{
+	return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_GENEVE,
+	    vni, inner_addr, outer_addr);
+}
+
+/*
+ * Specify inner and outer Ethernet address and vsid in NVGRE filter
+ * specification.
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_nvgre(
+	__inout		efx_filter_spec_t *spec,
+	__in		const uint8_t *vsid,
+	__in		const uint8_t *inner_addr,
+	__in		const uint8_t *outer_addr)
+{
+	return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_NVGRE,
+	    vsid, inner_addr, outer_addr);
 }
 
 #if EFSYS_OPT_RX_SCALE
-- 
2.17.1

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 00/37] net/sfc: update base driver
  2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
                   ` (36 preceding siblings ...)
  2018-09-10  9:33 ` [PATCH 37/37] net/sfc/base: add helper API to make Geneve filter spec Andrew Rybchenko
@ 2018-09-21 10:28 ` Ferruh Yigit
  37 siblings, 0 replies; 39+ messages in thread
From: Ferruh Yigit @ 2018-09-21 10:28 UTC (permalink / raw)
  To: Andrew Rybchenko, dev

On 9/10/2018 10:32 AM, Andrew Rybchenko wrote:
> Update net/sfc base driver (aka libefx).
> 
> There are a number of checkpatches.sh warnings/errors
> because of coding style difference.
> 
> Andrew Jackson (1):
>   net/sfc/base: highlight that image layout header generated
> 
> Andrew Rybchenko (1):
>   net/sfc/base: fix build failure because of no declaration
> 
> Andy Moreton (6):
>   net/sfc/base: properly align on line continuation
>   net/sfc/base: add space after sizeof
>   net/sfc/base: add routine to check for hardware presence
>   net/sfc/base: add API to inform libefx of hardware removal
>   net/sfc/base: fix ID retrival in v3 licensing
>   net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes
> 
> Gautam Dawar (1):
>   net/sfc/base: fix out of bounds read when dereferencing sdup
> 
> Ivan Malov (6):
>   net/sfc/base: fix name of the argument to store RSS flags
>   net/sfc/base: fix a typo in unicast filter insertion comment
>   net/sfc/base: use simpler code to check hash algorithm type
>   net/sfc/base: check buffer size for hash flags
>   net/sfc/base: simplify the code to parse RSS hash type
>   net/sfc/base: improve handling of legacy RSS hash flags
> 
> Mark Spender (3):
>   net/sfc/base: remove probes when a Tx queue is too full
>   net/sfc/base: add information if TSO workaround is required
>   net/sfc/base: prevent access to the NIC config before probe
> 
> Martin Harvey (10):
>   net/sfc/base: fix PreFAST warnings because of unused return
>   net/sfc/base: fix invalid order of memset arguments
>   net/sfc/base: fix output buffer SAL annotation
>   net/sfc/base: fix erroneous SAL annotation for input buffers
>   net/sfc/base: move empty efsys definitions to EFX headers
>   net/sfc/base: refactor monitors support
>   net/sfc/base: add generated description of sensors
>   net/sfc/base: check size of memory to read sensors data to
>   net/sfc/base: add API to retrieve sensor limits
>   net/sfc/base: avoid usage of too big arrays on stack
> 
> Paul Fox (1):
>   net/sfc/base: add more definitions of partitions
> 
> Richard Houldsworth (4):
>   net/sfc/base: add buffer editing functions to boot config
>   net/sfc/base: add accessor for default port mode
>   net/sfc/base: generalise EF10 NVRAM buffer interface
>   net/sfc/base: modify phy caps to indicate FEC request
> 
> Vijay Srivastava (4):
>   net/sfc/base: fix outer IPID field in TSO option descriptors
>   net/sfc/base: add check for TUNNEL module in NIC reset API
>   net/sfc/base: add support to get active FEC type
>   net/sfc/base: add helper API to make Geneve filter spec

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2018-09-21 10:29 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-10  9:32 [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 02/37] net/sfc/base: fix invalid order of memset arguments Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 03/37] net/sfc/base: fix output buffer SAL annotation Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 04/37] net/sfc/base: highlight that image layout header generated Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 05/37] net/sfc/base: fix erroneous SAL annotation for input buffers Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 06/37] net/sfc/base: properly align on line continuation Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 07/37] net/sfc/base: add space after sizeof Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 08/37] net/sfc/base: fix build failure because of no declaration Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 09/37] net/sfc/base: add more definitions of partitions Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 10/37] net/sfc/base: fix outer IPID field in TSO option descriptors Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 11/37] net/sfc/base: move empty efsys definitions to EFX headers Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 12/37] net/sfc/base: add check for TUNNEL module in NIC reset API Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 13/37] net/sfc/base: refactor monitors support Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 14/37] net/sfc/base: remove probes when a Tx queue is too full Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 15/37] net/sfc/base: add generated description of sensors Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 16/37] net/sfc/base: check size of memory to read sensors data to Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 18/37] net/sfc/base: add buffer editing functions to boot config Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 19/37] net/sfc/base: add accessor for default port mode Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 20/37] net/sfc/base: generalise EF10 NVRAM buffer interface Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 21/37] net/sfc/base: avoid usage of too big arrays on stack Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 22/37] net/sfc/base: add information if TSO workaround is required Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 23/37] net/sfc/base: fix out of bounds read when dereferencing sdup Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 24/37] net/sfc/base: add routine to check for hardware presence Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 25/37] net/sfc/base: add API to inform libefx of hardware removal Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 26/37] net/sfc/base: fix ID retrival in v3 licensing Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 27/37] net/sfc/base: prevent access to the NIC config before probe Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 28/37] net/sfc/base: fix name of the argument to store RSS flags Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 29/37] net/sfc/base: fix a typo in unicast filter insertion comment Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 30/37] net/sfc/base: add support to get active FEC type Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 31/37] net/sfc/base: use simpler code to check hash algorithm type Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 32/37] net/sfc/base: check buffer size for hash flags Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 33/37] net/sfc/base: simplify the code to parse RSS hash type Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 35/37] net/sfc/base: modify phy caps to indicate FEC request Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 36/37] net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes Andrew Rybchenko
2018-09-10  9:33 ` [PATCH 37/37] net/sfc/base: add helper API to make Geneve filter spec Andrew Rybchenko
2018-09-21 10:28 ` [PATCH 00/37] net/sfc: update base driver Ferruh Yigit

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.