Deleted Added
full compact
t4vf_hw.c (306664) t4vf_hw.c (309560)
1/*-
2 * Copyright (c) 2016 Chelsio Communications, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2016 Chelsio Communications, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/11/sys/dev/cxgbe/common/t4vf_hw.c 306664 2016-10-03 23:49:05Z jhb $");
28__FBSDID("$FreeBSD: stable/11/sys/dev/cxgbe/common/t4vf_hw.c 309560 2016-12-05 20:43:25Z jhb $");
29
30#include "common.h"
31#include "t4_regs.h"
29
30#include "common.h"
31#include "t4_regs.h"
32#include "t4_regs_values.h"
32
33#undef msleep
34#define msleep(x) do { \
35 if (cold) \
36 DELAY((x) * 1000); \
37 else \
38 pause("t4hw", (x) * hz / 1000); \
39} while (0)
40
41/*
42 * Wait for the device to become ready (signified by our "who am I" register
43 * returning a value other than all 1's). Return an error if it doesn't
44 * become ready ...
45 */
46int t4vf_wait_dev_ready(struct adapter *adapter)
47{
48 const u32 whoami = VF_PL_REG(A_PL_VF_WHOAMI);
49 const u32 notready1 = 0xffffffff;
50 const u32 notready2 = 0xeeeeeeee;
51 u32 val;
52
53 val = t4_read_reg(adapter, whoami);
54 if (val != notready1 && val != notready2)
55 return 0;
56 msleep(500);
57 val = t4_read_reg(adapter, whoami);
58 if (val != notready1 && val != notready2)
59 return 0;
60 else
61 return -EIO;
62}
63
64
65/**
66 * t4vf_fw_reset - issue a reset to FW
67 * @adapter: the adapter
68 *
69 * Issues a reset command to FW. For a Physical Function this would
70 * result in the Firmware reseting all of its state. For a Virtual
71 * Function this just resets the state associated with the VF.
72 */
73int t4vf_fw_reset(struct adapter *adapter)
74{
75 struct fw_reset_cmd cmd;
76
77 memset(&cmd, 0, sizeof(cmd));
78 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) |
79 F_FW_CMD_WRITE);
80 cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd)));
81 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
82}
83
84/**
85 * t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters
86 * @adapter: the adapter
87 *
88 * Retrieves various core SGE parameters in the form of hardware SGE
89 * register values. The caller is responsible for decoding these as
90 * needed. The SGE parameters are stored in @adapter->params.sge.
91 */
92int t4vf_get_sge_params(struct adapter *adapter)
93{
94 struct sge_params *sp = &adapter->params.sge;
95 u32 params[7], vals[7];
96 u32 whoami;
97 unsigned int pf, s_hps;
98 int i, v;
99
100 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
101 V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL));
102 params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
103 V_FW_PARAMS_PARAM_XYZ(A_SGE_HOST_PAGE_SIZE));
104 params[2] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
105 V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_0_AND_1));
106 params[3] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
107 V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_2_AND_3));
108 params[4] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
109 V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_4_AND_5));
110 params[5] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
111 V_FW_PARAMS_PARAM_XYZ(A_SGE_CONM_CTRL));
112 params[6] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
113 V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_RX_THRESHOLD));
114 v = t4vf_query_params(adapter, 7, params, vals);
115 if (v != FW_SUCCESS)
116 return v;
117
118 sp->sge_control = vals[0];
119 sp->counter_val[0] = G_THRESHOLD_0(vals[6]);
120 sp->counter_val[1] = G_THRESHOLD_1(vals[6]);
121 sp->counter_val[2] = G_THRESHOLD_2(vals[6]);
122 sp->counter_val[3] = G_THRESHOLD_3(vals[6]);
123 sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(vals[2]));
124 sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(vals[2]));
125 sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(vals[3]));
126 sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(vals[3]));
127 sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(vals[4]));
128 sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(vals[4]));
129
130 sp->fl_starve_threshold = G_EGRTHRESHOLD(vals[5]) * 2 + 1;
131 if (is_t4(adapter))
132 sp->fl_starve_threshold2 = sp->fl_starve_threshold;
33
34#undef msleep
35#define msleep(x) do { \
36 if (cold) \
37 DELAY((x) * 1000); \
38 else \
39 pause("t4hw", (x) * hz / 1000); \
40} while (0)
41
42/*
43 * Wait for the device to become ready (signified by our "who am I" register
44 * returning a value other than all 1's). Return an error if it doesn't
45 * become ready ...
46 */
47int t4vf_wait_dev_ready(struct adapter *adapter)
48{
49 const u32 whoami = VF_PL_REG(A_PL_VF_WHOAMI);
50 const u32 notready1 = 0xffffffff;
51 const u32 notready2 = 0xeeeeeeee;
52 u32 val;
53
54 val = t4_read_reg(adapter, whoami);
55 if (val != notready1 && val != notready2)
56 return 0;
57 msleep(500);
58 val = t4_read_reg(adapter, whoami);
59 if (val != notready1 && val != notready2)
60 return 0;
61 else
62 return -EIO;
63}
64
65
66/**
67 * t4vf_fw_reset - issue a reset to FW
68 * @adapter: the adapter
69 *
70 * Issues a reset command to FW. For a Physical Function this would
71 * result in the Firmware reseting all of its state. For a Virtual
72 * Function this just resets the state associated with the VF.
73 */
74int t4vf_fw_reset(struct adapter *adapter)
75{
76 struct fw_reset_cmd cmd;
77
78 memset(&cmd, 0, sizeof(cmd));
79 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) |
80 F_FW_CMD_WRITE);
81 cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd)));
82 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
83}
84
85/**
86 * t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters
87 * @adapter: the adapter
88 *
89 * Retrieves various core SGE parameters in the form of hardware SGE
90 * register values. The caller is responsible for decoding these as
91 * needed. The SGE parameters are stored in @adapter->params.sge.
92 */
93int t4vf_get_sge_params(struct adapter *adapter)
94{
95 struct sge_params *sp = &adapter->params.sge;
96 u32 params[7], vals[7];
97 u32 whoami;
98 unsigned int pf, s_hps;
99 int i, v;
100
101 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
102 V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL));
103 params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
104 V_FW_PARAMS_PARAM_XYZ(A_SGE_HOST_PAGE_SIZE));
105 params[2] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
106 V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_0_AND_1));
107 params[3] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
108 V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_2_AND_3));
109 params[4] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
110 V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_4_AND_5));
111 params[5] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
112 V_FW_PARAMS_PARAM_XYZ(A_SGE_CONM_CTRL));
113 params[6] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
114 V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_RX_THRESHOLD));
115 v = t4vf_query_params(adapter, 7, params, vals);
116 if (v != FW_SUCCESS)
117 return v;
118
119 sp->sge_control = vals[0];
120 sp->counter_val[0] = G_THRESHOLD_0(vals[6]);
121 sp->counter_val[1] = G_THRESHOLD_1(vals[6]);
122 sp->counter_val[2] = G_THRESHOLD_2(vals[6]);
123 sp->counter_val[3] = G_THRESHOLD_3(vals[6]);
124 sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(vals[2]));
125 sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(vals[2]));
126 sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(vals[3]));
127 sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(vals[3]));
128 sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(vals[4]));
129 sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(vals[4]));
130
131 sp->fl_starve_threshold = G_EGRTHRESHOLD(vals[5]) * 2 + 1;
132 if (is_t4(adapter))
133 sp->fl_starve_threshold2 = sp->fl_starve_threshold;
134 else if (is_t5(adapter))
135 sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1;
133 else
136 else
134 sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 +
135 1;
137 sp->fl_starve_threshold2 = G_T6_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1;
136
137 /*
138 * We need the Queues/Page and Host Page Size for our VF.
139 * This is based on the PF from which we're instantiated.
140 */
141 whoami = t4_read_reg(adapter, VF_PL_REG(A_PL_VF_WHOAMI));
142 pf = G_SOURCEPF(whoami);
143
144 s_hps = (S_HOSTPAGESIZEPF0 +
145 (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * pf);
146 sp->page_shift = ((vals[1] >> s_hps) & M_HOSTPAGESIZEPF0) + 10;
147
148 for (i = 0; i < SGE_FLBUF_SIZES; i++) {
149 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
150 V_FW_PARAMS_PARAM_XYZ(A_SGE_FL_BUFFER_SIZE0 + (4 * i)));
151 v = t4vf_query_params(adapter, 1, params, vals);
152 if (v != FW_SUCCESS)
153 return v;
154
155 sp->sge_fl_buffer_size[i] = vals[0];
156 }
157
158 /*
159 * T4 uses a single control field to specify both the PCIe Padding and
160 * Packing Boundary. T5 introduced the ability to specify these
161 * separately with the Padding Boundary in SGE_CONTROL and and Packing
162 * Boundary in SGE_CONTROL2. So for T5 and later we need to grab
163 * SGE_CONTROL in order to determine how ingress packet data will be
164 * laid out in Packed Buffer Mode. Unfortunately, older versions of
165 * the firmware won't let us retrieve SGE_CONTROL2 so if we get a
166 * failure grabbing it we throw an error since we can't figure out the
167 * right value.
168 */
169 sp->spg_len = sp->sge_control & F_EGRSTATUSPAGESIZE ? 128 : 64;
170 sp->fl_pktshift = G_PKTSHIFT(sp->sge_control);
138
139 /*
140 * We need the Queues/Page and Host Page Size for our VF.
141 * This is based on the PF from which we're instantiated.
142 */
143 whoami = t4_read_reg(adapter, VF_PL_REG(A_PL_VF_WHOAMI));
144 pf = G_SOURCEPF(whoami);
145
146 s_hps = (S_HOSTPAGESIZEPF0 +
147 (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * pf);
148 sp->page_shift = ((vals[1] >> s_hps) & M_HOSTPAGESIZEPF0) + 10;
149
150 for (i = 0; i < SGE_FLBUF_SIZES; i++) {
151 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
152 V_FW_PARAMS_PARAM_XYZ(A_SGE_FL_BUFFER_SIZE0 + (4 * i)));
153 v = t4vf_query_params(adapter, 1, params, vals);
154 if (v != FW_SUCCESS)
155 return v;
156
157 sp->sge_fl_buffer_size[i] = vals[0];
158 }
159
160 /*
161 * T4 uses a single control field to specify both the PCIe Padding and
162 * Packing Boundary. T5 introduced the ability to specify these
163 * separately with the Padding Boundary in SGE_CONTROL and and Packing
164 * Boundary in SGE_CONTROL2. So for T5 and later we need to grab
165 * SGE_CONTROL in order to determine how ingress packet data will be
166 * laid out in Packed Buffer Mode. Unfortunately, older versions of
167 * the firmware won't let us retrieve SGE_CONTROL2 so if we get a
168 * failure grabbing it we throw an error since we can't figure out the
169 * right value.
170 */
171 sp->spg_len = sp->sge_control & F_EGRSTATUSPAGESIZE ? 128 : 64;
172 sp->fl_pktshift = G_PKTSHIFT(sp->sge_control);
171 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) + 5);
173 if (chip_id(adapter) <= CHELSIO_T5) {
174 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) +
175 X_INGPADBOUNDARY_SHIFT);
176 } else {
177 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) +
178 X_T6_INGPADBOUNDARY_SHIFT);
179 }
172 if (is_t4(adapter))
173 sp->pack_boundary = sp->pad_boundary;
174 else {
175 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
176 V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL2));
177 v = t4vf_query_params(adapter, 1, params, vals);
178 if (v != FW_SUCCESS) {
179 CH_ERR(adapter, "Unable to get SGE Control2; "
180 "probably old firmware.\n");
181 return v;
182 }
183 if (G_INGPACKBOUNDARY(vals[0]) == 0)
184 sp->pack_boundary = 16;
185 else
186 sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(vals[0]) +
187 5);
188 }
189
190 /*
191 * For T5 and later we want to use the new BAR2 Doorbells.
192 * Unfortunately, older firmware didn't allow the this register to be
193 * read.
194 */
195 if (!is_t4(adapter)) {
196 unsigned int s_qpp;
197
198 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
199 V_FW_PARAMS_PARAM_XYZ(A_SGE_EGRESS_QUEUES_PER_PAGE_VF));
200 params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
201 V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_QUEUES_PER_PAGE_VF));
202 v = t4vf_query_params(adapter, 2, params, vals);
203 if (v != FW_SUCCESS) {
204 CH_WARN(adapter, "Unable to get VF SGE Queues/Page; "
205 "probably old firmware.\n");
206 return v;
207 }
208
209 s_qpp = (S_QUEUESPERPAGEPF0 +
210 (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * pf);
211 sp->eq_s_qpp = ((vals[0] >> s_qpp) & M_QUEUESPERPAGEPF0);
212 sp->iq_s_qpp = ((vals[1] >> s_qpp) & M_QUEUESPERPAGEPF0);
213 }
214
215 return 0;
216}
217
218/**
219 * t4vf_get_rss_glb_config - retrieve adapter RSS Global Configuration
220 * @adapter: the adapter
221 *
222 * Retrieves global RSS mode and parameters with which we have to live
223 * and stores them in the @adapter's RSS parameters.
224 */
225int t4vf_get_rss_glb_config(struct adapter *adapter)
226{
227 struct rss_params *rss = &adapter->params.rss;
228 struct fw_rss_glb_config_cmd cmd, rpl;
229 int v;
230
231 /*
232 * Execute an RSS Global Configuration read command to retrieve
233 * our RSS configuration.
234 */
235 memset(&cmd, 0, sizeof(cmd));
236 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
237 F_FW_CMD_REQUEST |
238 F_FW_CMD_READ);
239 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
240 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
241 if (v != FW_SUCCESS)
242 return v;
243
244 /*
245 * Transate the big-endian RSS Global Configuration into our
246 * cpu-endian format based on the RSS mode. We also do first level
247 * filtering at this point to weed out modes which don't support
248 * VF Drivers ...
249 */
250 rss->mode = G_FW_RSS_GLB_CONFIG_CMD_MODE(
251 be32_to_cpu(rpl.u.manual.mode_pkd));
252 switch (rss->mode) {
253 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
254 u32 word = be32_to_cpu(
255 rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
256
257 rss->u.basicvirtual.synmapen =
258 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0);
259 rss->u.basicvirtual.syn4tupenipv6 =
260 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0);
261 rss->u.basicvirtual.syn2tupenipv6 =
262 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0);
263 rss->u.basicvirtual.syn4tupenipv4 =
264 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0);
265 rss->u.basicvirtual.syn2tupenipv4 =
266 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0);
267
268 rss->u.basicvirtual.ofdmapen =
269 ((word & F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0);
270
271 rss->u.basicvirtual.tnlmapen =
272 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0);
273 rss->u.basicvirtual.tnlalllookup =
274 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
275
276 rss->u.basicvirtual.hashtoeplitz =
277 ((word & F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0);
278
279 /* we need at least Tunnel Map Enable to be set */
280 if (!rss->u.basicvirtual.tnlmapen)
281 return -EINVAL;
282 break;
283 }
284
285 default:
286 /* all unknown/unsupported RSS modes result in an error */
287 return -EINVAL;
288 }
289
290 return 0;
291}
292
293/**
294 * t4vf_get_vfres - retrieve VF resource limits
295 * @adapter: the adapter
296 *
297 * Retrieves configured resource limits and capabilities for a virtual
298 * function. The results are stored in @adapter->vfres.
299 */
300int t4vf_get_vfres(struct adapter *adapter)
301{
302 struct vf_resources *vfres = &adapter->params.vfres;
303 struct fw_pfvf_cmd cmd, rpl;
304 int v;
305 u32 word;
306
307 /*
308 * Execute PFVF Read command to get VF resource limits; bail out early
309 * with error on command failure.
310 */
311 memset(&cmd, 0, sizeof(cmd));
312 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) |
313 F_FW_CMD_REQUEST |
314 F_FW_CMD_READ);
315 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
316 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
317 if (v != FW_SUCCESS)
318 return v;
319
320 /*
321 * Extract VF resource limits and return success.
322 */
323 word = be32_to_cpu(rpl.niqflint_niq);
324 vfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word);
325 vfres->niq = G_FW_PFVF_CMD_NIQ(word);
326
327 word = be32_to_cpu(rpl.type_to_neq);
328 vfres->neq = G_FW_PFVF_CMD_NEQ(word);
329 vfres->pmask = G_FW_PFVF_CMD_PMASK(word);
330
331 word = be32_to_cpu(rpl.tc_to_nexactf);
332 vfres->tc = G_FW_PFVF_CMD_TC(word);
333 vfres->nvi = G_FW_PFVF_CMD_NVI(word);
334 vfres->nexactf = G_FW_PFVF_CMD_NEXACTF(word);
335
336 word = be32_to_cpu(rpl.r_caps_to_nethctrl);
337 vfres->r_caps = G_FW_PFVF_CMD_R_CAPS(word);
338 vfres->wx_caps = G_FW_PFVF_CMD_WX_CAPS(word);
339 vfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word);
340
341 return 0;
342}
343
344/**
345 */
346int t4vf_prep_adapter(struct adapter *adapter)
347{
348 int err;
349
350 /*
351 * Wait for the device to become ready before proceeding ...
352 */
353 err = t4vf_wait_dev_ready(adapter);
354 if (err)
355 return err;
356
357 adapter->params.chipid = pci_get_device(adapter->dev) >> 12;
358 if (adapter->params.chipid >= 0xa) {
359 adapter->params.chipid -= (0xa - 0x4);
360 adapter->params.fpga = 1;
361 }
362
363 /*
364 * Default port and clock for debugging in case we can't reach
365 * firmware.
366 */
367 adapter->params.nports = 1;
368 adapter->params.vfres.pmask = 1;
369 adapter->params.vpd.cclk = 50000;
370
371 adapter->chip_params = t4_get_chip_params(chip_id(adapter));
372 if (adapter->chip_params == NULL)
373 return -EINVAL;
374
375 return 0;
376}
180 if (is_t4(adapter))
181 sp->pack_boundary = sp->pad_boundary;
182 else {
183 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
184 V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL2));
185 v = t4vf_query_params(adapter, 1, params, vals);
186 if (v != FW_SUCCESS) {
187 CH_ERR(adapter, "Unable to get SGE Control2; "
188 "probably old firmware.\n");
189 return v;
190 }
191 if (G_INGPACKBOUNDARY(vals[0]) == 0)
192 sp->pack_boundary = 16;
193 else
194 sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(vals[0]) +
195 5);
196 }
197
198 /*
199 * For T5 and later we want to use the new BAR2 Doorbells.
200 * Unfortunately, older firmware didn't allow the this register to be
201 * read.
202 */
203 if (!is_t4(adapter)) {
204 unsigned int s_qpp;
205
206 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
207 V_FW_PARAMS_PARAM_XYZ(A_SGE_EGRESS_QUEUES_PER_PAGE_VF));
208 params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
209 V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_QUEUES_PER_PAGE_VF));
210 v = t4vf_query_params(adapter, 2, params, vals);
211 if (v != FW_SUCCESS) {
212 CH_WARN(adapter, "Unable to get VF SGE Queues/Page; "
213 "probably old firmware.\n");
214 return v;
215 }
216
217 s_qpp = (S_QUEUESPERPAGEPF0 +
218 (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * pf);
219 sp->eq_s_qpp = ((vals[0] >> s_qpp) & M_QUEUESPERPAGEPF0);
220 sp->iq_s_qpp = ((vals[1] >> s_qpp) & M_QUEUESPERPAGEPF0);
221 }
222
223 return 0;
224}
225
226/**
227 * t4vf_get_rss_glb_config - retrieve adapter RSS Global Configuration
228 * @adapter: the adapter
229 *
230 * Retrieves global RSS mode and parameters with which we have to live
231 * and stores them in the @adapter's RSS parameters.
232 */
233int t4vf_get_rss_glb_config(struct adapter *adapter)
234{
235 struct rss_params *rss = &adapter->params.rss;
236 struct fw_rss_glb_config_cmd cmd, rpl;
237 int v;
238
239 /*
240 * Execute an RSS Global Configuration read command to retrieve
241 * our RSS configuration.
242 */
243 memset(&cmd, 0, sizeof(cmd));
244 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
245 F_FW_CMD_REQUEST |
246 F_FW_CMD_READ);
247 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
248 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
249 if (v != FW_SUCCESS)
250 return v;
251
252 /*
253 * Transate the big-endian RSS Global Configuration into our
254 * cpu-endian format based on the RSS mode. We also do first level
255 * filtering at this point to weed out modes which don't support
256 * VF Drivers ...
257 */
258 rss->mode = G_FW_RSS_GLB_CONFIG_CMD_MODE(
259 be32_to_cpu(rpl.u.manual.mode_pkd));
260 switch (rss->mode) {
261 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
262 u32 word = be32_to_cpu(
263 rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
264
265 rss->u.basicvirtual.synmapen =
266 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0);
267 rss->u.basicvirtual.syn4tupenipv6 =
268 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0);
269 rss->u.basicvirtual.syn2tupenipv6 =
270 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0);
271 rss->u.basicvirtual.syn4tupenipv4 =
272 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0);
273 rss->u.basicvirtual.syn2tupenipv4 =
274 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0);
275
276 rss->u.basicvirtual.ofdmapen =
277 ((word & F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0);
278
279 rss->u.basicvirtual.tnlmapen =
280 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0);
281 rss->u.basicvirtual.tnlalllookup =
282 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
283
284 rss->u.basicvirtual.hashtoeplitz =
285 ((word & F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0);
286
287 /* we need at least Tunnel Map Enable to be set */
288 if (!rss->u.basicvirtual.tnlmapen)
289 return -EINVAL;
290 break;
291 }
292
293 default:
294 /* all unknown/unsupported RSS modes result in an error */
295 return -EINVAL;
296 }
297
298 return 0;
299}
300
301/**
302 * t4vf_get_vfres - retrieve VF resource limits
303 * @adapter: the adapter
304 *
305 * Retrieves configured resource limits and capabilities for a virtual
306 * function. The results are stored in @adapter->vfres.
307 */
308int t4vf_get_vfres(struct adapter *adapter)
309{
310 struct vf_resources *vfres = &adapter->params.vfres;
311 struct fw_pfvf_cmd cmd, rpl;
312 int v;
313 u32 word;
314
315 /*
316 * Execute PFVF Read command to get VF resource limits; bail out early
317 * with error on command failure.
318 */
319 memset(&cmd, 0, sizeof(cmd));
320 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) |
321 F_FW_CMD_REQUEST |
322 F_FW_CMD_READ);
323 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
324 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
325 if (v != FW_SUCCESS)
326 return v;
327
328 /*
329 * Extract VF resource limits and return success.
330 */
331 word = be32_to_cpu(rpl.niqflint_niq);
332 vfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word);
333 vfres->niq = G_FW_PFVF_CMD_NIQ(word);
334
335 word = be32_to_cpu(rpl.type_to_neq);
336 vfres->neq = G_FW_PFVF_CMD_NEQ(word);
337 vfres->pmask = G_FW_PFVF_CMD_PMASK(word);
338
339 word = be32_to_cpu(rpl.tc_to_nexactf);
340 vfres->tc = G_FW_PFVF_CMD_TC(word);
341 vfres->nvi = G_FW_PFVF_CMD_NVI(word);
342 vfres->nexactf = G_FW_PFVF_CMD_NEXACTF(word);
343
344 word = be32_to_cpu(rpl.r_caps_to_nethctrl);
345 vfres->r_caps = G_FW_PFVF_CMD_R_CAPS(word);
346 vfres->wx_caps = G_FW_PFVF_CMD_WX_CAPS(word);
347 vfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word);
348
349 return 0;
350}
351
352/**
353 */
354int t4vf_prep_adapter(struct adapter *adapter)
355{
356 int err;
357
358 /*
359 * Wait for the device to become ready before proceeding ...
360 */
361 err = t4vf_wait_dev_ready(adapter);
362 if (err)
363 return err;
364
365 adapter->params.chipid = pci_get_device(adapter->dev) >> 12;
366 if (adapter->params.chipid >= 0xa) {
367 adapter->params.chipid -= (0xa - 0x4);
368 adapter->params.fpga = 1;
369 }
370
371 /*
372 * Default port and clock for debugging in case we can't reach
373 * firmware.
374 */
375 adapter->params.nports = 1;
376 adapter->params.vfres.pmask = 1;
377 adapter->params.vpd.cclk = 50000;
378
379 adapter->chip_params = t4_get_chip_params(chip_id(adapter));
380 if (adapter->chip_params == NULL)
381 return -EINVAL;
382
383 return 0;
384}