diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 03ea5dc128..3814ce3dee 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -685,6 +685,7 @@ sfc_rss_attach(struct sfc_adapter *sa)
 	efx_intr_fini(sa->nic);
 
 	rte_memcpy(rss->key, default_rss_key, sizeof(rss->key));
+	rss->dummy_rss_context = EFX_RSS_CONTEXT_DEFAULT;
 
 	return 0;
 
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index fa7c79b80b..5ea29362e1 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -157,6 +157,8 @@ struct sfc_rss {
 	efx_rx_hash_type_t		hash_types;
 	unsigned int			tbl[EFX_RSS_TBL_SIZE];
 	uint8_t				key[EFX_RSS_KEY_SIZE];
+
+	uint32_t			dummy_rss_context;
 };
 
 /* Adapter private data shared by primary and secondary processes */
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6c96118007..9cc07292e1 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1526,8 +1526,15 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
 	struct sfc_rss *rss = &sfc_sa2shared(sa)->rss;
 	unsigned int efx_hash_types;
+	uint32_t contexts[] = {EFX_RSS_CONTEXT_DEFAULT, rss->dummy_rss_context};
+	unsigned int n_contexts;
+	unsigned int mode_i = 0;
+	unsigned int key_i = 0;
+	unsigned int i = 0;
 	int rc = 0;
 
+	n_contexts = rss->dummy_rss_context == EFX_RSS_CONTEXT_DEFAULT ? 1 : 2;
+
 	if (sfc_sa2shared(sa)->isolated)
 		return -ENOTSUP;
 
@@ -1554,19 +1561,24 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
 	if (rc != 0)
 		goto fail_rx_hf_rte_to_efx;
 
-	rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT,
-				   rss->hash_alg, efx_hash_types, B_TRUE);
-	if (rc != 0)
-		goto fail_scale_mode_set;
+	for (mode_i = 0; mode_i < n_contexts; mode_i++) {
+		rc = efx_rx_scale_mode_set(sa->nic, contexts[mode_i],
+					   rss->hash_alg, efx_hash_types,
+					   B_TRUE);
+		if (rc != 0)
+			goto fail_scale_mode_set;
+	}
 
 	if (rss_conf->rss_key != NULL) {
 		if (sa->state == SFC_ADAPTER_STARTED) {
-			rc = efx_rx_scale_key_set(sa->nic,
-						  EFX_RSS_CONTEXT_DEFAULT,
-						  rss_conf->rss_key,
-						  sizeof(rss->key));
-			if (rc != 0)
-				goto fail_scale_key_set;
+			for (key_i = 0; key_i < n_contexts; key_i++) {
+				rc = efx_rx_scale_key_set(sa->nic,
+							  contexts[key_i],
+							  rss_conf->rss_key,
+							  sizeof(rss->key));
+				if (rc != 0)
+					goto fail_scale_key_set;
+			}
 		}
 
 		rte_memcpy(rss->key, rss_conf->rss_key, sizeof(rss->key));
@@ -1579,12 +1591,20 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
 	return 0;
 
 fail_scale_key_set:
-	if (efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT,
-				  EFX_RX_HASHALG_TOEPLITZ,
-				  rss->hash_types, B_TRUE) != 0)
-		sfc_err(sa, "failed to restore RSS mode");
+	for (i = 0; i < key_i; i++) {
+		if (efx_rx_scale_key_set(sa->nic, contexts[i], rss->key,
+					 sizeof(rss->key)) != 0)
+			sfc_err(sa, "failed to restore RSS key");
+	}
 
 fail_scale_mode_set:
+	for (i = 0; i < mode_i; i++) {
+		if (efx_rx_scale_mode_set(sa->nic, contexts[i],
+					  EFX_RX_HASHALG_TOEPLITZ,
+					  rss->hash_types, B_TRUE) != 0)
+			sfc_err(sa, "failed to restore RSS mode");
+	}
+
 fail_rx_hf_rte_to_efx:
 	sfc_adapter_unlock(sa);
 	return -rc;
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 1a3c0d618b..cb802d7991 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1293,6 +1293,7 @@ sfc_flow_parse_queue(struct sfc_adapter *sa,
 	struct sfc_flow_spec *spec = &flow->spec;
 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
 	struct sfc_rxq *rxq;
+	struct sfc_rxq_info *rxq_info;
 
 	if (queue->index >= sfc_sa2shared(sa)->rxq_count)
 		return -EINVAL;
@@ -1300,6 +1301,10 @@ sfc_flow_parse_queue(struct sfc_adapter *sa,
 	rxq = &sa->rxq_ctrl[queue->index];
 	spec_filter->template.efs_dmaq_id = (uint16_t)rxq->hw_index;
 
+	rxq_info = &sfc_sa2shared(sa)->rxq_info[queue->index];
+	spec_filter->rss_hash_required = !!(rxq_info->rxq_flags &
+					    SFC_RXQ_FLAG_RSS_HASH);
+
 	return 0;
 }
 
@@ -1465,13 +1470,34 @@ sfc_flow_filter_insert(struct sfc_adapter *sa,
 	struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter;
 	struct sfc_flow_rss *flow_rss = &spec_filter->rss_conf;
 	uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT;
+	boolean_t create_context;
 	unsigned int i;
 	int rc = 0;
 
-	if (spec_filter->rss) {
-		unsigned int rss_spread = MIN(flow_rss->rxq_hw_index_max -
-					      flow_rss->rxq_hw_index_min + 1,
-					      EFX_MAXRSS);
+	create_context = spec_filter->rss || (spec_filter->rss_hash_required &&
+			rss->dummy_rss_context == EFX_RSS_CONTEXT_DEFAULT);
+
+	if (create_context) {
+		unsigned int rss_spread;
+		unsigned int rss_hash_types;
+		uint8_t *rss_key;
+
+		if (spec_filter->rss) {
+			rss_spread = MIN(flow_rss->rxq_hw_index_max -
+					flow_rss->rxq_hw_index_min + 1,
+					EFX_MAXRSS);
+			rss_hash_types = flow_rss->rss_hash_types;
+			rss_key = flow_rss->rss_key;
+		} else {
+			/*
+			 * Initialize dummy RSS context parameters to have
+			 * valid RSS hash. Use default RSS hash function and
+			 * key.
+			 */
+			rss_spread = 1;
+			rss_hash_types = rss->hash_types;
+			rss_key = rss->key;
+		}
 
 		rc = efx_rx_scale_context_alloc(sa->nic,
 						EFX_RX_SCALE_EXCLUSIVE,
@@ -1482,16 +1508,19 @@ sfc_flow_filter_insert(struct sfc_adapter *sa,
 
 		rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context,
 					   rss->hash_alg,
-					   flow_rss->rss_hash_types, B_TRUE);
+					   rss_hash_types, B_TRUE);
 		if (rc != 0)
 			goto fail_scale_mode_set;
 
 		rc = efx_rx_scale_key_set(sa->nic, efs_rss_context,
-					  flow_rss->rss_key,
-					  sizeof(rss->key));
+					  rss_key, sizeof(rss->key));
 		if (rc != 0)
 			goto fail_scale_key_set;
+	} else {
+		efs_rss_context = rss->dummy_rss_context;
+	}
 
+	if (spec_filter->rss || spec_filter->rss_hash_required) {
 		/*
 		 * At this point, fully elaborated filter specifications
 		 * have been produced from the template. To make sure that
@@ -1502,8 +1531,9 @@ sfc_flow_filter_insert(struct sfc_adapter *sa,
 			efx_filter_spec_t *spec = &spec_filter->filters[i];
 
 			spec->efs_rss_context = efs_rss_context;
-			spec->efs_dmaq_id = flow_rss->rxq_hw_index_min;
 			spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS;
+			if (spec_filter->rss)
+				spec->efs_dmaq_id = flow_rss->rxq_hw_index_min;
 		}
 	}
 
@@ -1511,7 +1541,12 @@ sfc_flow_filter_insert(struct sfc_adapter *sa,
 	if (rc != 0)
 		goto fail_filter_insert;
 
-	if (spec_filter->rss) {
+	if (create_context) {
+		unsigned int dummy_tbl[RTE_DIM(flow_rss->rss_tbl)] = {0};
+		unsigned int *tbl;
+
+		tbl = spec_filter->rss ? flow_rss->rss_tbl : dummy_tbl;
+
 		/*
 		 * Scale table is set after filter insertion because
 		 * the table entries are relative to the base RxQ ID
@@ -1521,10 +1556,13 @@ sfc_flow_filter_insert(struct sfc_adapter *sa,
 		 * the table entries, and the operation will succeed
 		 */
 		rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context,
-					  flow_rss->rss_tbl,
-					  RTE_DIM(flow_rss->rss_tbl));
+					  tbl, RTE_DIM(flow_rss->rss_tbl));
 		if (rc != 0)
 			goto fail_scale_tbl_set;
+
+		/* Remember created dummy RSS context */
+		if (!spec_filter->rss)
+			rss->dummy_rss_context = efs_rss_context;
 	}
 
 	return 0;
@@ -1535,7 +1573,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa,
 fail_filter_insert:
 fail_scale_key_set:
 fail_scale_mode_set:
-	if (efs_rss_context != EFX_RSS_CONTEXT_DEFAULT)
+	if (create_context)
 		efx_rx_scale_context_free(sa->nic, efs_rss_context);
 
 fail_scale_context_alloc:
@@ -2634,12 +2672,19 @@ sfc_flow_fini(struct sfc_adapter *sa)
 void
 sfc_flow_stop(struct sfc_adapter *sa)
 {
+	struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
+	struct sfc_rss *rss = &sas->rss;
 	struct rte_flow *flow;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
 	TAILQ_FOREACH(flow, &sa->flow_list, entries)
 		sfc_flow_remove(sa, flow, NULL);
+
+	if (rss->dummy_rss_context != EFX_RSS_CONTEXT_DEFAULT) {
+		efx_rx_scale_context_free(sa->nic, rss->dummy_rss_context);
+		rss->dummy_rss_context = EFX_RSS_CONTEXT_DEFAULT;
+	}
 }
 
 int
diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h
index 5a7dad8f09..433c7a31e9 100644
--- a/drivers/net/sfc/sfc_flow.h
+++ b/drivers/net/sfc/sfc_flow.h
@@ -52,6 +52,8 @@ struct sfc_flow_spec_filter {
 	unsigned int count;
 	/* RSS toggle */
 	boolean_t rss;
+	/* RSS hash toggle */
+	boolean_t rss_hash_required;
 	/* RSS configuration */
 	struct sfc_flow_rss rss_conf;
 };
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index dccafb163a..3e5c8e42da 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -1139,6 +1139,13 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rxq_info->refill_threshold =
 		RTE_MAX(rx_free_thresh, SFC_RX_REFILL_BULK);
 	rxq_info->refill_mb_pool = mb_pool;
+
+	if (rss->hash_support == EFX_RX_HASH_AVAILABLE && rss->channels > 0 &&
+	    (offloads & DEV_RX_OFFLOAD_RSS_HASH))
+		rxq_info->rxq_flags = SFC_RXQ_FLAG_RSS_HASH;
+	else
+		rxq_info->rxq_flags = 0;
+
 	rxq->buf_size = buf_size;
 
 	rc = sfc_dma_alloc(sa, "rxq", sw_index,
@@ -1154,11 +1161,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.buf_size = buf_size;
 	info.batch_max = encp->enc_rx_batch_max;
 	info.prefix_size = encp->enc_rx_prefix_size;
-
-	if (rss->hash_support == EFX_RX_HASH_AVAILABLE && rss->channels > 0 &&
-	    (offloads & DEV_RX_OFFLOAD_RSS_HASH))
-		info.flags |= SFC_RXQ_FLAG_RSS_HASH;
-
+	info.flags = rxq_info->rxq_flags;
 	info.rxq_entries = rxq_info->entries;
 	info.rxq_hw_ring = rxq->mem.esm_base;
 	info.evq_hw_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 697ea29d62..b0b5327a49 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -115,6 +115,7 @@ struct sfc_rxq_info {
 	boolean_t		deferred_started;
 	unsigned int		refill_threshold;
 	struct rte_mempool	*refill_mb_pool;
+	unsigned int		rxq_flags;
 };
 
 struct sfc_rxq_info *sfc_rxq_info_by_dp_rxq(const struct sfc_dp_rxq *dp_rxq);
