From 9a57eee01860bfbd203d3db5d3be220ddaf1e4be Mon Sep 17 00:00:00 2001
From: Mark Spender <mspender@solarflare.com>
Date: Thu, 16 Nov 2017 08:04:17 +0000
Subject: [PATCH] net/sfc/base: request info about outer frame in Rx events

For encapsulated packets, the firmware gives info about the inner frame
fields by default. When not using encapsulation offload, ask for info
about the outer frame instead.

On SFN8xxx with firmware version before v6.4.2.1007 driver reload is
needed after switching from full-feature to low-latency firmware
variant since the driver still thinks that firmware supports
encapsulation, but firmware does not tolerate request to provide info
about outer frame in Rx events.

Signed-off-by: Mark Spender <mspender@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_rx.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 4c74d1f5cb..5ede72806f 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -46,6 +46,7 @@ efx_mcdi_init_rxq(
 	__in		boolean_t disable_scatter,
 	__in		uint32_t ps_bufsize)
 {
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
 	uint8_t payload[MAX(MC_CMD_INIT_RXQ_EXT_IN_LEN,
 			    MC_CMD_INIT_RXQ_EXT_OUT_LEN)];
@@ -55,6 +56,7 @@ efx_mcdi_init_rxq(
 	uint64_t addr;
 	efx_rc_t rc;
 	uint32_t dma_mode;
+	boolean_t want_outer_classes;
 
 	/* If this changes, then the payload size might need to change. */
 	EFSYS_ASSERT3U(MC_CMD_INIT_RXQ_OUT_LEN, ==, 0);
@@ -65,6 +67,25 @@ efx_mcdi_init_rxq(
 	else
 		dma_mode = MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET;
 
+	if (encp->enc_tunnel_encapsulations_supported != 0) {
+		/*
+		 * WANT_OUTER_CLASSES can only be specified on hardware which
+		 * supports tunnel encapsulation offloads, even though it is
+		 * effectively the behaviour the hardware gives.
+		 *
+		 * Also, on hardware which does support such offloads, older
+		 * firmware rejects the flag if the offloads are not supported
+		 * by the current firmware variant, which means this may fail if
+		 * the capabilities are not updated when the firmware variant
+		 * changes. This is not an issue on newer firmware, as it was
+		 * changed in bug 69842 (v6.4.2.1007) to permit this flag to be
+		 * specified on all firmware variants.
+		 */
+		want_outer_classes = B_TRUE;
+	} else {
+		want_outer_classes = B_FALSE;
+	}
+
 	(void) memset(payload, 0, sizeof (payload));
 	req.emr_cmd = MC_CMD_INIT_RXQ;
 	req.emr_in_buf = payload;
@@ -76,7 +97,7 @@ efx_mcdi_init_rxq(
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_TARGET_EVQ, target_evq);
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_LABEL, label);
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_INSTANCE, instance);
-	MCDI_IN_POPULATE_DWORD_8(req, INIT_RXQ_EXT_IN_FLAGS,
+	MCDI_IN_POPULATE_DWORD_9(req, INIT_RXQ_EXT_IN_FLAGS,
 	    INIT_RXQ_EXT_IN_FLAG_BUFF_MODE, 0,
 	    INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT, 0,
 	    INIT_RXQ_EXT_IN_FLAG_TIMESTAMP, 0,
@@ -85,7 +106,8 @@ efx_mcdi_init_rxq(
 	    INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER, disable_scatter,
 	    INIT_RXQ_EXT_IN_DMA_MODE,
 	    dma_mode,
-	    INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE, ps_bufsize);
+	    INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE, ps_bufsize,
+	    INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES, want_outer_classes);
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_OWNER_ID, 0);
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
 
-- 
2.39.5