Commit dcf10ec7 authored by Raju Rangoju's avatar Raju Rangoju Committed by David S. Miller
Browse files

cxgb4: use firmware API for validating filter spec



Adds support for validating hardware filter spec configured in firmware
before offloading exact match flows.

Use the new fw api FW_PARAM_DEV_FILTER_MODE_MASK to read the filter mode
and mask from firmware. If the api isn't supported, then fall-back to
older way of reading just the mode from indirect register.

Signed-off-by: default avatarRaju Rangoju <rajur@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 00e31a09
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -280,6 +280,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
+2 −1
Original line number Diff line number Diff line
@@ -248,8 +248,9 @@ static int validate_filter(struct net_device *dev,
	u32 fconf, iconf;

	/* Check for unconfigured fields being used. */
	fconf = adapter->params.tp.vlan_pri_map;
	iconf = adapter->params.tp.ingress_config;
	fconf = fs->hash ? adapter->params.tp.filter_mask :
			   adapter->params.tp.vlan_pri_map;

	if (unsupported(fconf, FCOE_F, fs->val.fcoe, fs->mask.fcoe) ||
	    unsupported(fconf, PORT_F, fs->val.iport, fs->mask.iport) ||
+42 −5
Original line number Diff line number Diff line
@@ -9388,8 +9388,9 @@ int t4_init_sge_params(struct adapter *adapter)
 */
int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
{
	int chan;
	u32 v;
	u32 param, val, v;
	int chan, ret;


	v = t4_read_reg(adap, TP_TIMER_RESOLUTION_A);
	adap->params.tp.tre = TIMERRESOLUTION_G(v);
@@ -9399,11 +9400,47 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
	for (chan = 0; chan < NCHAN; chan++)
		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.
	 */
	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FILTER) |
		 FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_FILTER_MODE_MASK));

	/* Read current value */
	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
			      &param, &val);
	if (ret == 0) {
		dev_info(adap->pdev_dev,
			 "Current filter mode/mask 0x%x:0x%x\n",
			 FW_PARAMS_PARAM_FILTER_MODE_G(val),
			 FW_PARAMS_PARAM_FILTER_MASK_G(val));
		adap->params.tp.vlan_pri_map =
			FW_PARAMS_PARAM_FILTER_MODE_G(val);
		adap->params.tp.filter_mask =
			FW_PARAMS_PARAM_FILTER_MASK_G(val);
	} else {
		dev_info(adap->pdev_dev,
			 "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_tp_pio_read(adap, &adap->params.tp.vlan_pri_map, 1,
			       TP_VLAN_PRI_MAP_A, sleep_ok);

		/* 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_tp_pio_read(adap, &adap->params.tp.ingress_config, 1,
		       TP_INGRESS_CONFIG_A, sleep_ok);

+23 −0
Original line number Diff line number Diff line
@@ -1221,6 +1221,23 @@ enum fw_params_mnem {
/*
 * device parameters
 */

#define FW_PARAMS_PARAM_FILTER_MODE_S 16
#define FW_PARAMS_PARAM_FILTER_MODE_M 0xffff
#define FW_PARAMS_PARAM_FILTER_MODE_V(x)          \
	((x) << FW_PARAMS_PARAM_FILTER_MODE_S)
#define FW_PARAMS_PARAM_FILTER_MODE_G(x)          \
	(((x) >> FW_PARAMS_PARAM_FILTER_MODE_S) & \
	FW_PARAMS_PARAM_FILTER_MODE_M)

#define FW_PARAMS_PARAM_FILTER_MASK_S 0
#define FW_PARAMS_PARAM_FILTER_MASK_M 0xffff
#define FW_PARAMS_PARAM_FILTER_MASK_V(x)          \
	((x) << FW_PARAMS_PARAM_FILTER_MASK_S)
#define FW_PARAMS_PARAM_FILTER_MASK_G(x)          \
	(((x) >> FW_PARAMS_PARAM_FILTER_MASK_S) & \
	FW_PARAMS_PARAM_FILTER_MASK_M)

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 */
@@ -1258,6 +1275,7 @@ enum fw_params_param_dev {
	FW_PARAMS_PARAM_DEV_HASHFILTER_WITH_OFLD = 0x28,
	FW_PARAMS_PARAM_DEV_DBQ_TIMER	= 0x29,
	FW_PARAMS_PARAM_DEV_DBQ_TIMERTICK = 0x2A,
	FW_PARAMS_PARAM_DEV_FILTER = 0x2E,
};

/*
@@ -1349,6 +1367,11 @@ enum fw_params_param_dev_diag {
	FW_PARAM_DEV_DIAG_MAXTMPTHRESH	= 0x02,
};

enum fw_params_param_dev_filter {
	FW_PARAM_DEV_FILTER_VNIC_MODE   = 0x00,
	FW_PARAM_DEV_FILTER_MODE_MASK   = 0x01,
};

enum fw_params_param_dev_fwcache {
	FW_PARAM_DEV_FWCACHE_FLUSH      = 0x00,
	FW_PARAM_DEV_FWCACHE_FLUSHINV   = 0x01,