xref: /freebsd/sys/dev/cxgbe/common/t4vf_hw.c (revision 4471ff11969ec6bd2e5d3c745fc5ba90fda596ed)
16af45170SJohn Baldwin /*-
26af45170SJohn Baldwin  * Copyright (c) 2016 Chelsio Communications, Inc.
36af45170SJohn Baldwin  * All rights reserved.
46af45170SJohn Baldwin  *
56af45170SJohn Baldwin  * Redistribution and use in source and binary forms, with or without
66af45170SJohn Baldwin  * modification, are permitted provided that the following conditions
76af45170SJohn Baldwin  * are met:
86af45170SJohn Baldwin  * 1. Redistributions of source code must retain the above copyright
96af45170SJohn Baldwin  *    notice, this list of conditions and the following disclaimer.
106af45170SJohn Baldwin  * 2. Redistributions in binary form must reproduce the above copyright
116af45170SJohn Baldwin  *    notice, this list of conditions and the following disclaimer in the
126af45170SJohn Baldwin  *    documentation and/or other materials provided with the distribution.
136af45170SJohn Baldwin  *
146af45170SJohn Baldwin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
156af45170SJohn Baldwin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
166af45170SJohn Baldwin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
176af45170SJohn Baldwin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
186af45170SJohn Baldwin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
196af45170SJohn Baldwin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
206af45170SJohn Baldwin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
216af45170SJohn Baldwin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
226af45170SJohn Baldwin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
236af45170SJohn Baldwin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
246af45170SJohn Baldwin  * SUCH DAMAGE.
256af45170SJohn Baldwin  */
266af45170SJohn Baldwin 
276af45170SJohn Baldwin #include <sys/cdefs.h>
286af45170SJohn Baldwin #include "common.h"
296af45170SJohn Baldwin #include "t4_regs.h"
300dbc6cfdSNavdeep Parhar #include "t4_regs_values.h"
316af45170SJohn Baldwin 
326af45170SJohn Baldwin #undef msleep
336af45170SJohn Baldwin #define msleep(x) do { \
346af45170SJohn Baldwin 	if (cold) \
356af45170SJohn Baldwin 		DELAY((x) * 1000); \
366af45170SJohn Baldwin 	else \
376af45170SJohn Baldwin 		pause("t4hw", (x) * hz / 1000); \
386af45170SJohn Baldwin } while (0)
396af45170SJohn Baldwin 
406af45170SJohn Baldwin /*
416af45170SJohn Baldwin  * Wait for the device to become ready (signified by our "who am I" register
426af45170SJohn Baldwin  * returning a value other than all 1's).  Return an error if it doesn't
436af45170SJohn Baldwin  * become ready ...
446af45170SJohn Baldwin  */
t4vf_wait_dev_ready(struct adapter * adapter)456af45170SJohn Baldwin int t4vf_wait_dev_ready(struct adapter *adapter)
466af45170SJohn Baldwin {
476af45170SJohn Baldwin 	const u32 whoami = VF_PL_REG(A_PL_VF_WHOAMI);
486af45170SJohn Baldwin 	const u32 notready1 = 0xffffffff;
496af45170SJohn Baldwin 	const u32 notready2 = 0xeeeeeeee;
506af45170SJohn Baldwin 	u32 val;
516af45170SJohn Baldwin 
526af45170SJohn Baldwin 	val = t4_read_reg(adapter, whoami);
536af45170SJohn Baldwin 	if (val != notready1 && val != notready2)
546af45170SJohn Baldwin 		return 0;
556af45170SJohn Baldwin 	msleep(500);
566af45170SJohn Baldwin 	val = t4_read_reg(adapter, whoami);
576af45170SJohn Baldwin 	if (val != notready1 && val != notready2)
586af45170SJohn Baldwin 		return 0;
596af45170SJohn Baldwin 	else
606af45170SJohn Baldwin 		return -EIO;
616af45170SJohn Baldwin }
626af45170SJohn Baldwin 
636af45170SJohn Baldwin 
646af45170SJohn Baldwin /**
656af45170SJohn Baldwin  *      t4vf_fw_reset - issue a reset to FW
666af45170SJohn Baldwin  *      @adapter: the adapter
676af45170SJohn Baldwin  *
686af45170SJohn Baldwin  *	Issues a reset command to FW.  For a Physical Function this would
696af45170SJohn Baldwin  *	result in the Firmware reseting all of its state.  For a Virtual
706af45170SJohn Baldwin  *	Function this just resets the state associated with the VF.
716af45170SJohn Baldwin  */
t4vf_fw_reset(struct adapter * adapter)726af45170SJohn Baldwin int t4vf_fw_reset(struct adapter *adapter)
736af45170SJohn Baldwin {
746af45170SJohn Baldwin 	struct fw_reset_cmd cmd;
756af45170SJohn Baldwin 
766af45170SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
776af45170SJohn Baldwin 	cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) |
786af45170SJohn Baldwin 				      F_FW_CMD_WRITE);
796af45170SJohn Baldwin 	cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd)));
806af45170SJohn Baldwin 	return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
816af45170SJohn Baldwin }
826af45170SJohn Baldwin 
836af45170SJohn Baldwin /**
846af45170SJohn Baldwin  *	t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters
856af45170SJohn Baldwin  *	@adapter: the adapter
866af45170SJohn Baldwin  *
876af45170SJohn Baldwin  *	Retrieves various core SGE parameters in the form of hardware SGE
886af45170SJohn Baldwin  *	register values.  The caller is responsible for decoding these as
896af45170SJohn Baldwin  *	needed.  The SGE parameters are stored in @adapter->params.sge.
906af45170SJohn Baldwin  */
t4vf_get_sge_params(struct adapter * adapter)916af45170SJohn Baldwin int t4vf_get_sge_params(struct adapter *adapter)
926af45170SJohn Baldwin {
936af45170SJohn Baldwin 	struct sge_params *sp = &adapter->params.sge;
946af45170SJohn Baldwin 	u32 params[7], vals[7];
956af45170SJohn Baldwin 	u32 whoami;
966af45170SJohn Baldwin 	unsigned int pf, s_hps;
976af45170SJohn Baldwin 	int i, v;
986af45170SJohn Baldwin 
996af45170SJohn Baldwin 	params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1006af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL));
1016af45170SJohn Baldwin 	params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1026af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_HOST_PAGE_SIZE));
1036af45170SJohn Baldwin 	params[2] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1046af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_0_AND_1));
1056af45170SJohn Baldwin 	params[3] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1066af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_2_AND_3));
1076af45170SJohn Baldwin 	params[4] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1086af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_4_AND_5));
1096af45170SJohn Baldwin 	params[5] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1106af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_CONM_CTRL));
1116af45170SJohn Baldwin 	params[6] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1126af45170SJohn Baldwin 		     V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_RX_THRESHOLD));
1136af45170SJohn Baldwin 	v = t4vf_query_params(adapter, 7, params, vals);
1146af45170SJohn Baldwin 	if (v != FW_SUCCESS)
1156af45170SJohn Baldwin 		return v;
1166af45170SJohn Baldwin 
1176af45170SJohn Baldwin 	sp->sge_control = vals[0];
1186af45170SJohn Baldwin 	sp->counter_val[0] = G_THRESHOLD_0(vals[6]);
1196af45170SJohn Baldwin 	sp->counter_val[1] = G_THRESHOLD_1(vals[6]);
1206af45170SJohn Baldwin 	sp->counter_val[2] = G_THRESHOLD_2(vals[6]);
1216af45170SJohn Baldwin 	sp->counter_val[3] = G_THRESHOLD_3(vals[6]);
1226af45170SJohn Baldwin 	sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(vals[2]));
1236af45170SJohn Baldwin 	sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(vals[2]));
1246af45170SJohn Baldwin 	sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(vals[3]));
1256af45170SJohn Baldwin 	sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(vals[3]));
1266af45170SJohn Baldwin 	sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(vals[4]));
1276af45170SJohn Baldwin 	sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(vals[4]));
1286af45170SJohn Baldwin 
1296af45170SJohn Baldwin 	sp->fl_starve_threshold = G_EGRTHRESHOLD(vals[5]) * 2 + 1;
1306af45170SJohn Baldwin 	if (is_t4(adapter))
1316af45170SJohn Baldwin 		sp->fl_starve_threshold2 = sp->fl_starve_threshold;
132774168beSNavdeep Parhar 	else if (is_t5(adapter))
133774168beSNavdeep Parhar 		sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1;
1346af45170SJohn Baldwin 	else
135774168beSNavdeep Parhar 		sp->fl_starve_threshold2 = G_T6_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1;
1366af45170SJohn Baldwin 
1376af45170SJohn Baldwin 	/*
1386af45170SJohn Baldwin 	 * We need the Queues/Page and Host Page Size for our VF.
1396af45170SJohn Baldwin 	 * This is based on the PF from which we're instantiated.
1406af45170SJohn Baldwin 	 */
1416af45170SJohn Baldwin 	whoami = t4_read_reg(adapter, VF_PL_REG(A_PL_VF_WHOAMI));
142d0fdafdbSNavdeep Parhar 	if (chip_id(adapter) <= CHELSIO_T5)
1436af45170SJohn Baldwin 		pf = G_SOURCEPF(whoami);
144d0fdafdbSNavdeep Parhar 	else
145d0fdafdbSNavdeep Parhar 		pf = G_T6_SOURCEPF(whoami);
1466af45170SJohn Baldwin 
1476af45170SJohn Baldwin 	s_hps = (S_HOSTPAGESIZEPF0 +
1486af45170SJohn Baldwin 	    (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * pf);
1496af45170SJohn Baldwin 	sp->page_shift = ((vals[1] >> s_hps) & M_HOSTPAGESIZEPF0) + 10;
1506af45170SJohn Baldwin 
1516af45170SJohn Baldwin 	for (i = 0; i < SGE_FLBUF_SIZES; i++) {
1526af45170SJohn Baldwin 		params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1536af45170SJohn Baldwin 		    V_FW_PARAMS_PARAM_XYZ(A_SGE_FL_BUFFER_SIZE0 + (4 * i)));
1546af45170SJohn Baldwin 		v = t4vf_query_params(adapter, 1, params, vals);
1556af45170SJohn Baldwin 		if (v != FW_SUCCESS)
1566af45170SJohn Baldwin 			return v;
1576af45170SJohn Baldwin 
1586af45170SJohn Baldwin 		sp->sge_fl_buffer_size[i] = vals[0];
1596af45170SJohn Baldwin 	}
1606af45170SJohn Baldwin 
1616af45170SJohn Baldwin 	/*
1626af45170SJohn Baldwin 	 * T4 uses a single control field to specify both the PCIe Padding and
1636af45170SJohn Baldwin 	 * Packing Boundary.  T5 introduced the ability to specify these
1646af45170SJohn Baldwin 	 * separately with the Padding Boundary in SGE_CONTROL and and Packing
1656af45170SJohn Baldwin 	 * Boundary in SGE_CONTROL2.  So for T5 and later we need to grab
1666af45170SJohn Baldwin 	 * SGE_CONTROL in order to determine how ingress packet data will be
1676af45170SJohn Baldwin 	 * laid out in Packed Buffer Mode.  Unfortunately, older versions of
1686af45170SJohn Baldwin 	 * the firmware won't let us retrieve SGE_CONTROL2 so if we get a
1696af45170SJohn Baldwin 	 * failure grabbing it we throw an error since we can't figure out the
1706af45170SJohn Baldwin 	 * right value.
1716af45170SJohn Baldwin 	 */
1726af45170SJohn Baldwin 	sp->spg_len = sp->sge_control & F_EGRSTATUSPAGESIZE ? 128 : 64;
1736af45170SJohn Baldwin 	sp->fl_pktshift = G_PKTSHIFT(sp->sge_control);
1740dbc6cfdSNavdeep Parhar 	if (chip_id(adapter) <= CHELSIO_T5) {
1750dbc6cfdSNavdeep Parhar 		sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) +
1760dbc6cfdSNavdeep Parhar 		    X_INGPADBOUNDARY_SHIFT);
1770dbc6cfdSNavdeep Parhar 	} else {
1780dbc6cfdSNavdeep Parhar 		sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) +
1790dbc6cfdSNavdeep Parhar 		    X_T6_INGPADBOUNDARY_SHIFT);
1800dbc6cfdSNavdeep Parhar 	}
1816af45170SJohn Baldwin 	if (is_t4(adapter))
1826af45170SJohn Baldwin 		sp->pack_boundary = sp->pad_boundary;
1836af45170SJohn Baldwin 	else {
1846af45170SJohn Baldwin 		params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
1856af45170SJohn Baldwin 			     V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL2));
1866af45170SJohn Baldwin 		v = t4vf_query_params(adapter, 1, params, vals);
1876af45170SJohn Baldwin 		if (v != FW_SUCCESS) {
1886af45170SJohn Baldwin 			CH_ERR(adapter, "Unable to get SGE Control2; "
1896af45170SJohn Baldwin 			       "probably old firmware.\n");
1906af45170SJohn Baldwin 			return v;
1916af45170SJohn Baldwin 		}
1926af45170SJohn Baldwin 		if (G_INGPACKBOUNDARY(vals[0]) == 0)
1936af45170SJohn Baldwin 			sp->pack_boundary = 16;
1946af45170SJohn Baldwin 		else
1956af45170SJohn Baldwin 			sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(vals[0]) +
1966af45170SJohn Baldwin 			    5);
1976af45170SJohn Baldwin 	}
1986af45170SJohn Baldwin 
1996af45170SJohn Baldwin 	/*
2006af45170SJohn Baldwin 	 * For T5 and later we want to use the new BAR2 Doorbells.
2016af45170SJohn Baldwin 	 * Unfortunately, older firmware didn't allow the this register to be
2026af45170SJohn Baldwin 	 * read.
2036af45170SJohn Baldwin 	 */
2046af45170SJohn Baldwin 	if (!is_t4(adapter)) {
2056af45170SJohn Baldwin 		unsigned int s_qpp;
2066af45170SJohn Baldwin 
2076af45170SJohn Baldwin 		params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2086af45170SJohn Baldwin 			     V_FW_PARAMS_PARAM_XYZ(A_SGE_EGRESS_QUEUES_PER_PAGE_VF));
2096af45170SJohn Baldwin 		params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2106af45170SJohn Baldwin 			     V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_QUEUES_PER_PAGE_VF));
2116af45170SJohn Baldwin 		v = t4vf_query_params(adapter, 2, params, vals);
2126af45170SJohn Baldwin 		if (v != FW_SUCCESS) {
2136af45170SJohn Baldwin 			CH_WARN(adapter, "Unable to get VF SGE Queues/Page; "
2146af45170SJohn Baldwin 				"probably old firmware.\n");
2156af45170SJohn Baldwin 			return v;
2166af45170SJohn Baldwin 		}
2176af45170SJohn Baldwin 
2186af45170SJohn Baldwin 		s_qpp = (S_QUEUESPERPAGEPF0 +
2196af45170SJohn Baldwin 			 (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * pf);
2206af45170SJohn Baldwin 		sp->eq_s_qpp = ((vals[0] >> s_qpp) & M_QUEUESPERPAGEPF0);
2216af45170SJohn Baldwin 		sp->iq_s_qpp = ((vals[1] >> s_qpp) & M_QUEUESPERPAGEPF0);
2226af45170SJohn Baldwin 	}
2236af45170SJohn Baldwin 
2246af45170SJohn Baldwin 	return 0;
2256af45170SJohn Baldwin }
2266af45170SJohn Baldwin 
2276af45170SJohn Baldwin /**
2286af45170SJohn Baldwin  *	t4vf_get_rss_glb_config - retrieve adapter RSS Global Configuration
2296af45170SJohn Baldwin  *	@adapter: the adapter
2306af45170SJohn Baldwin  *
2316af45170SJohn Baldwin  *	Retrieves global RSS mode and parameters with which we have to live
2326af45170SJohn Baldwin  *	and stores them in the @adapter's RSS parameters.
2336af45170SJohn Baldwin  */
t4vf_get_rss_glb_config(struct adapter * adapter)2346af45170SJohn Baldwin int t4vf_get_rss_glb_config(struct adapter *adapter)
2356af45170SJohn Baldwin {
2366af45170SJohn Baldwin 	struct rss_params *rss = &adapter->params.rss;
2376af45170SJohn Baldwin 	struct fw_rss_glb_config_cmd cmd, rpl;
2386af45170SJohn Baldwin 	int v;
2396af45170SJohn Baldwin 
2406af45170SJohn Baldwin 	/*
2416af45170SJohn Baldwin 	 * Execute an RSS Global Configuration read command to retrieve
2426af45170SJohn Baldwin 	 * our RSS configuration.
2436af45170SJohn Baldwin 	 */
2446af45170SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
2456af45170SJohn Baldwin 	cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
2466af45170SJohn Baldwin 				      F_FW_CMD_REQUEST |
2476af45170SJohn Baldwin 				      F_FW_CMD_READ);
2486af45170SJohn Baldwin 	cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
2496af45170SJohn Baldwin 	v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
2506af45170SJohn Baldwin 	if (v != FW_SUCCESS)
2516af45170SJohn Baldwin 		return v;
2526af45170SJohn Baldwin 
2536af45170SJohn Baldwin 	/*
2546af45170SJohn Baldwin 	 * Transate the big-endian RSS Global Configuration into our
2556af45170SJohn Baldwin 	 * cpu-endian format based on the RSS mode.  We also do first level
2566af45170SJohn Baldwin 	 * filtering at this point to weed out modes which don't support
2576af45170SJohn Baldwin 	 * VF Drivers ...
2586af45170SJohn Baldwin 	 */
2596af45170SJohn Baldwin 	rss->mode = G_FW_RSS_GLB_CONFIG_CMD_MODE(
2606af45170SJohn Baldwin 			be32_to_cpu(rpl.u.manual.mode_pkd));
2616af45170SJohn Baldwin 	switch (rss->mode) {
2626af45170SJohn Baldwin 	case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
2636af45170SJohn Baldwin 		u32 word = be32_to_cpu(
2646af45170SJohn Baldwin 				rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
2656af45170SJohn Baldwin 
2666af45170SJohn Baldwin 		rss->u.basicvirtual.synmapen =
2676af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0);
2686af45170SJohn Baldwin 		rss->u.basicvirtual.syn4tupenipv6 =
2696af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0);
2706af45170SJohn Baldwin 		rss->u.basicvirtual.syn2tupenipv6 =
2716af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0);
2726af45170SJohn Baldwin 		rss->u.basicvirtual.syn4tupenipv4 =
2736af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0);
2746af45170SJohn Baldwin 		rss->u.basicvirtual.syn2tupenipv4 =
2756af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0);
2766af45170SJohn Baldwin 
2776af45170SJohn Baldwin 		rss->u.basicvirtual.ofdmapen =
2786af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0);
2796af45170SJohn Baldwin 
2806af45170SJohn Baldwin 		rss->u.basicvirtual.tnlmapen =
2816af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0);
2826af45170SJohn Baldwin 		rss->u.basicvirtual.tnlalllookup =
2836af45170SJohn Baldwin 			((word  & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
2846af45170SJohn Baldwin 
2856af45170SJohn Baldwin 		rss->u.basicvirtual.hashtoeplitz =
2866af45170SJohn Baldwin 			((word & F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0);
2876af45170SJohn Baldwin 
2886af45170SJohn Baldwin 		/* we need at least Tunnel Map Enable to be set */
2896af45170SJohn Baldwin 		if (!rss->u.basicvirtual.tnlmapen)
2906af45170SJohn Baldwin 			return -EINVAL;
2916af45170SJohn Baldwin 		break;
2926af45170SJohn Baldwin 	}
2936af45170SJohn Baldwin 
2946af45170SJohn Baldwin 	default:
2956af45170SJohn Baldwin 		/* all unknown/unsupported RSS modes result in an error */
2966af45170SJohn Baldwin 		return -EINVAL;
2976af45170SJohn Baldwin 	}
2986af45170SJohn Baldwin 
2996af45170SJohn Baldwin 	return 0;
3006af45170SJohn Baldwin }
3016af45170SJohn Baldwin 
3026af45170SJohn Baldwin /**
3036af45170SJohn Baldwin  *	t4vf_get_vfres - retrieve VF resource limits
3046af45170SJohn Baldwin  *	@adapter: the adapter
3056af45170SJohn Baldwin  *
3066af45170SJohn Baldwin  *	Retrieves configured resource limits and capabilities for a virtual
3076af45170SJohn Baldwin  *	function.  The results are stored in @adapter->vfres.
3086af45170SJohn Baldwin  */
t4vf_get_vfres(struct adapter * adapter)3096af45170SJohn Baldwin int t4vf_get_vfres(struct adapter *adapter)
3106af45170SJohn Baldwin {
3116af45170SJohn Baldwin 	struct vf_resources *vfres = &adapter->params.vfres;
3126af45170SJohn Baldwin 	struct fw_pfvf_cmd cmd, rpl;
3136af45170SJohn Baldwin 	int v;
3146af45170SJohn Baldwin 	u32 word;
3156af45170SJohn Baldwin 
3166af45170SJohn Baldwin 	/*
3176af45170SJohn Baldwin 	 * Execute PFVF Read command to get VF resource limits; bail out early
3186af45170SJohn Baldwin 	 * with error on command failure.
3196af45170SJohn Baldwin 	 */
3206af45170SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
3216af45170SJohn Baldwin 	cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) |
3226af45170SJohn Baldwin 				    F_FW_CMD_REQUEST |
3236af45170SJohn Baldwin 				    F_FW_CMD_READ);
3246af45170SJohn Baldwin 	cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
3256af45170SJohn Baldwin 	v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
3266af45170SJohn Baldwin 	if (v != FW_SUCCESS)
3276af45170SJohn Baldwin 		return v;
3286af45170SJohn Baldwin 
3296af45170SJohn Baldwin 	/*
3306af45170SJohn Baldwin 	 * Extract VF resource limits and return success.
3316af45170SJohn Baldwin 	 */
3326af45170SJohn Baldwin 	word = be32_to_cpu(rpl.niqflint_niq);
3336af45170SJohn Baldwin 	vfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word);
3346af45170SJohn Baldwin 	vfres->niq = G_FW_PFVF_CMD_NIQ(word);
3356af45170SJohn Baldwin 
3366af45170SJohn Baldwin 	word = be32_to_cpu(rpl.type_to_neq);
3376af45170SJohn Baldwin 	vfres->neq = G_FW_PFVF_CMD_NEQ(word);
3386af45170SJohn Baldwin 	vfres->pmask = G_FW_PFVF_CMD_PMASK(word);
3396af45170SJohn Baldwin 
3406af45170SJohn Baldwin 	word = be32_to_cpu(rpl.tc_to_nexactf);
3416af45170SJohn Baldwin 	vfres->tc = G_FW_PFVF_CMD_TC(word);
3426af45170SJohn Baldwin 	vfres->nvi = G_FW_PFVF_CMD_NVI(word);
3436af45170SJohn Baldwin 	vfres->nexactf = G_FW_PFVF_CMD_NEXACTF(word);
3446af45170SJohn Baldwin 
3456af45170SJohn Baldwin 	word = be32_to_cpu(rpl.r_caps_to_nethctrl);
3466af45170SJohn Baldwin 	vfres->r_caps = G_FW_PFVF_CMD_R_CAPS(word);
3476af45170SJohn Baldwin 	vfres->wx_caps = G_FW_PFVF_CMD_WX_CAPS(word);
3486af45170SJohn Baldwin 	vfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word);
3496af45170SJohn Baldwin 
3506af45170SJohn Baldwin 	return 0;
3516af45170SJohn Baldwin }
3526af45170SJohn Baldwin 
3536af45170SJohn Baldwin /**
3546af45170SJohn Baldwin  */
t4vf_prep_adapter(struct adapter * adapter)3556af45170SJohn Baldwin int t4vf_prep_adapter(struct adapter *adapter)
3566af45170SJohn Baldwin {
3576af45170SJohn Baldwin 	int err;
3586af45170SJohn Baldwin 
3596af45170SJohn Baldwin 	/*
3606af45170SJohn Baldwin 	 * Wait for the device to become ready before proceeding ...
3616af45170SJohn Baldwin 	 */
3626af45170SJohn Baldwin 	err = t4vf_wait_dev_ready(adapter);
3636af45170SJohn Baldwin 	if (err)
3646af45170SJohn Baldwin 		return err;
3656af45170SJohn Baldwin 
3666af45170SJohn Baldwin 	adapter->params.chipid = pci_get_device(adapter->dev) >> 12;
3676af45170SJohn Baldwin 	if (adapter->params.chipid >= 0xa) {
3686af45170SJohn Baldwin 		adapter->params.chipid -= (0xa - 0x4);
3696af45170SJohn Baldwin 		adapter->params.fpga = 1;
3706af45170SJohn Baldwin 	}
3716af45170SJohn Baldwin 
3726af45170SJohn Baldwin 	/*
3736af45170SJohn Baldwin 	 * Default port and clock for debugging in case we can't reach
3746af45170SJohn Baldwin 	 * firmware.
3756af45170SJohn Baldwin 	 */
3766af45170SJohn Baldwin 	adapter->params.nports = 1;
3776af45170SJohn Baldwin 	adapter->params.vfres.pmask = 1;
3786af45170SJohn Baldwin 	adapter->params.vpd.cclk = 50000;
3796af45170SJohn Baldwin 
3806af45170SJohn Baldwin 	adapter->chip_params = t4_get_chip_params(chip_id(adapter));
3816af45170SJohn Baldwin 	if (adapter->chip_params == NULL)
3826af45170SJohn Baldwin 		return -EINVAL;
3836af45170SJohn Baldwin 
3846af45170SJohn Baldwin 	return 0;
3856af45170SJohn Baldwin }
386dc0800a9SNavdeep Parhar 
387dc0800a9SNavdeep Parhar /*
388dc0800a9SNavdeep Parhar  *	t4vf_get_vf_mac - Get the MAC address to be set to the VI of this VF.
389dc0800a9SNavdeep Parhar  *	@adapter: The adapter
390dc0800a9SNavdeep Parhar  *	@port: The port associated with vf
391dc0800a9SNavdeep Parhar  *	@naddr: the number of ACL MAC addresses returned in addr
392dc0800a9SNavdeep Parhar  *	@addr: Placeholder for MAC addresses
393dc0800a9SNavdeep Parhar  *
394dc0800a9SNavdeep Parhar  *	Find the MAC address to be set to the VF's VI. The requested MAC address
395dc0800a9SNavdeep Parhar  *	is from the host OS via callback in the PF driver.
396dc0800a9SNavdeep Parhar  */
t4vf_get_vf_mac(struct adapter * adapter,unsigned int port,unsigned int * naddr,u8 * addr)397dc0800a9SNavdeep Parhar int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port,
398dc0800a9SNavdeep Parhar 		    unsigned int *naddr, u8 *addr)
399dc0800a9SNavdeep Parhar {
400dc0800a9SNavdeep Parhar 	struct fw_acl_mac_cmd cmd;
401dc0800a9SNavdeep Parhar 	int ret;
402dc0800a9SNavdeep Parhar 
403dc0800a9SNavdeep Parhar 	memset(&cmd, 0, sizeof(cmd));
404dc0800a9SNavdeep Parhar 	cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_ACL_MAC_CMD) |
405dc0800a9SNavdeep Parhar 			      F_FW_CMD_REQUEST |
406dc0800a9SNavdeep Parhar 			      F_FW_CMD_READ);
407dc0800a9SNavdeep Parhar 	cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
408dc0800a9SNavdeep Parhar 	ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
409dc0800a9SNavdeep Parhar 	if (ret)
410dc0800a9SNavdeep Parhar 		return ret;
411dc0800a9SNavdeep Parhar 
412dc0800a9SNavdeep Parhar 	if (cmd.nmac < *naddr)
413dc0800a9SNavdeep Parhar 		*naddr = cmd.nmac;
414dc0800a9SNavdeep Parhar 
415dc0800a9SNavdeep Parhar 	switch (port) {
416dc0800a9SNavdeep Parhar 	case 3:
417dc0800a9SNavdeep Parhar 		memcpy(addr, cmd.macaddr3, sizeof(cmd.macaddr3));
418dc0800a9SNavdeep Parhar 		break;
419dc0800a9SNavdeep Parhar 	case 2:
420dc0800a9SNavdeep Parhar 		memcpy(addr, cmd.macaddr2, sizeof(cmd.macaddr2));
421dc0800a9SNavdeep Parhar 		break;
422dc0800a9SNavdeep Parhar 	case 1:
423dc0800a9SNavdeep Parhar 		memcpy(addr, cmd.macaddr1, sizeof(cmd.macaddr1));
424dc0800a9SNavdeep Parhar 		break;
425dc0800a9SNavdeep Parhar 	case 0:
426dc0800a9SNavdeep Parhar 		memcpy(addr, cmd.macaddr0, sizeof(cmd.macaddr0));
427dc0800a9SNavdeep Parhar 		break;
428dc0800a9SNavdeep Parhar 	}
429dc0800a9SNavdeep Parhar 
430dc0800a9SNavdeep Parhar 	return ret;
431dc0800a9SNavdeep Parhar }
432*4471ff11SNavdeep Parhar 
433*4471ff11SNavdeep Parhar /*
434*4471ff11SNavdeep Parhar  *	t4vf_get_vf_vlan - Get the VLAN ID to be set to the VI of this VF.
435*4471ff11SNavdeep Parhar  *	@adapter: The adapter
436*4471ff11SNavdeep Parhar  *
437*4471ff11SNavdeep Parhar  *	Find the VLAN ID to be set to the VF's VI. The requested VLAN ID
438*4471ff11SNavdeep Parhar  *	is from the host OS via callback in the PF driver.
439*4471ff11SNavdeep Parhar  */
t4vf_get_vf_vlan(struct adapter * adapter)440*4471ff11SNavdeep Parhar int t4vf_get_vf_vlan(struct adapter *adapter)
441*4471ff11SNavdeep Parhar {
442*4471ff11SNavdeep Parhar 	struct fw_acl_vlan_cmd cmd = {0};
443*4471ff11SNavdeep Parhar 	int vlan = 0;
444*4471ff11SNavdeep Parhar 	int ret = 0;
445*4471ff11SNavdeep Parhar 
446*4471ff11SNavdeep Parhar 	cmd.op_to_vfn = htonl(V_FW_CMD_OP(FW_ACL_VLAN_CMD) |
447*4471ff11SNavdeep Parhar 			      F_FW_CMD_REQUEST | F_FW_CMD_READ);
448*4471ff11SNavdeep Parhar 
449*4471ff11SNavdeep Parhar 	/* Note: Do not enable the ACL */
450*4471ff11SNavdeep Parhar 	cmd.en_to_len16 = htonl((unsigned int)FW_LEN16(cmd));
451*4471ff11SNavdeep Parhar 
452*4471ff11SNavdeep Parhar 	ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
453*4471ff11SNavdeep Parhar 
454*4471ff11SNavdeep Parhar 	if (!ret)
455*4471ff11SNavdeep Parhar 		vlan = be16_to_cpu(cmd.vlanid[0]);
456*4471ff11SNavdeep Parhar 
457*4471ff11SNavdeep Parhar 	return vlan;
458*4471ff11SNavdeep Parhar }
459