diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 892aab64b..79c8fcb76 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -133,6 +133,7 @@ struct tp_params {
 	unsigned short tx_modq[NCHAN];  /* channel to modulation queue map */
 
 	u32 vlan_pri_map;               /* cached TP_VLAN_PRI_MAP */
+	u32 filter_mask;
 	u32 ingress_config;             /* cached TP_INGRESS_CONFIG */
 
 	/* cached TP_OUT_CONFIG compressed error vector
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 48b6d77b1..1e7be3ec3 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -5215,8 +5215,8 @@ int t4_init_sge_params(struct adapter *adapter)
  */
 int t4_init_tp_params(struct adapter *adap)
 {
-	int chan;
-	u32 v;
+	int chan, ret;
+	u32 param, v;
 
 	v = t4_read_reg(adap, A_TP_TIMER_RESOLUTION);
 	adap->params.tp.tre = G_TIMERRESOLUTION(v);
@@ -5227,11 +5227,47 @@ int t4_init_tp_params(struct adapter *adap)
 		adap->params.tp.tx_modq[chan] = chan;
 
 	/*
-	 * Cache the adapter's Compressed Filter Mode and global Incress
+	 * Cache the adapter's Compressed Filter Mode/Mask and global Ingress
 	 * Configuration.
 	 */
-	t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
-			 &adap->params.tp.vlan_pri_map, 1, A_TP_VLAN_PRI_MAP);
+	param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
+		 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FILTER) |
+		 V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_MODE_MASK));
+
+	/* Read current value */
+	ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+			      1, &param, &v);
+	if (!ret) {
+		dev_info(adap, "Current filter mode/mask 0x%x:0x%x\n",
+			 G_FW_PARAMS_PARAM_FILTER_MODE(v),
+			 G_FW_PARAMS_PARAM_FILTER_MASK(v));
+		adap->params.tp.vlan_pri_map =
+			G_FW_PARAMS_PARAM_FILTER_MODE(v);
+		adap->params.tp.filter_mask =
+			G_FW_PARAMS_PARAM_FILTER_MASK(v);
+	} else {
+		dev_info(adap,
+			 "Failed to read filter mode/mask via fw api, using indirect-reg-read\n");
+
+		/* Incase of older-fw (which doesn't expose the api
+		 * FW_PARAM_DEV_FILTER_MODE_MASK) and newer-driver (which uses
+		 * the fw api) combination, fall-back to older method of reading
+		 * the filter mode from indirect-register
+		 */
+		t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
+				 &adap->params.tp.vlan_pri_map, 1,
+				 A_TP_VLAN_PRI_MAP);
+
+		/* With the older-fw and newer-driver combination we might run
+		 * into an issue when user wants to use hash filter region but
+		 * the filter_mask is zero, in this case filter_mask validation
+		 * is tough. To avoid that we set the filter_mask same as filter
+		 * mode, which will behave exactly as the older way of ignoring
+		 * the filter mask validation.
+		 */
+		adap->params.tp.filter_mask = adap->params.tp.vlan_pri_map;
+	}
+
 	t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
 			 &adap->params.tp.ingress_config, 1,
 			 A_TP_INGRESS_CONFIG);
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 51ebe4f7a..46d087a09 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -671,6 +671,19 @@ enum fw_params_mnem {
 /*
  * device parameters
  */
+
+#define S_FW_PARAMS_PARAM_FILTER_MODE 16
+#define M_FW_PARAMS_PARAM_FILTER_MODE 0xffff
+#define G_FW_PARAMS_PARAM_FILTER_MODE(x)          \
+	(((x) >> S_FW_PARAMS_PARAM_FILTER_MODE) & \
+	M_FW_PARAMS_PARAM_FILTER_MODE)
+
+#define S_FW_PARAMS_PARAM_FILTER_MASK 0
+#define M_FW_PARAMS_PARAM_FILTER_MASK 0xffff
+#define G_FW_PARAMS_PARAM_FILTER_MASK(x)          \
+	(((x) >> S_FW_PARAMS_PARAM_FILTER_MASK) & \
+	M_FW_PARAMS_PARAM_FILTER_MASK)
+
 enum fw_params_param_dev {
 	FW_PARAMS_PARAM_DEV_CCLK	= 0x00, /* chip core clock in khz */
 	FW_PARAMS_PARAM_DEV_PORTVEC	= 0x01, /* the port vector */
@@ -683,6 +696,7 @@ enum fw_params_param_dev {
 	FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
 	FW_PARAMS_PARAM_DEV_FILTER2_WR	= 0x1D,
 	FW_PARAMS_PARAM_DEV_OPAQUE_VIID_SMT_EXTN = 0x27,
+	FW_PARAMS_PARAM_DEV_FILTER      = 0x2E,
 };
 
 /*
@@ -710,6 +724,10 @@ enum fw_params_param_dmaq {
 	FW_PARAMS_PARAM_DMAQ_CONM_CTXT = 0x20,
 };
 
+enum fw_params_param_dev_filter {
+	FW_PARAM_DEV_FILTER_MODE_MASK   = 0x01,
+};
+
 #define S_FW_PARAMS_MNEM	24
 #define M_FW_PARAMS_MNEM	0xff
 #define V_FW_PARAMS_MNEM(x)	((x) << S_FW_PARAMS_MNEM)
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index c5f5e41e3..27e96c73e 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -62,7 +62,8 @@ int cxgbe_validate_filter(struct adapter *adapter,
 	/*
 	 * Check for unconfigured fields being used.
 	 */
-	fconf = adapter->params.tp.vlan_pri_map;
+	fconf = fs->cap ? adapter->params.tp.filter_mask :
+			  adapter->params.tp.vlan_pri_map;
 
 	iconf = adapter->params.tp.ingress_config;
 
