FreeBSD kernel CXGBE device code
t4vf_hw.c
Go to the documentation of this file.
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$");
29
30#include "common.h"
31#include "t4_regs.h"
32#include "t4_regs_values.h"
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 */
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
75{
76 struct fw_reset_cmd cmd;
77
78 memset(&cmd, 0, sizeof(cmd));
82 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
83}
84
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
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]);
130
131 sp->fl_starve_threshold = G_EGRTHRESHOLD(vals[5]) * 2 + 1;
132 if (is_t4(adapter))
134 else if (is_t5(adapter))
135 sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1;
136 else
137 sp->fl_starve_threshold2 = G_T6_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1;
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 */
144 pf = G_SOURCEPF(whoami);
145
146 s_hps = (S_HOSTPAGESIZEPF0 +
148 sp->page_shift = ((vals[1] >> s_hps) & M_HOSTPAGESIZEPF0) + 10;
149
150 for (i = 0; i < SGE_FLBUF_SIZES; 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;
173 if (chip_id(adapter) <= CHELSIO_T5) {
174 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) +
176 } else {
177 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) +
179 }
180 if (is_t4(adapter))
181 sp->pack_boundary = sp->pad_boundary;
182 else {
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
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 +
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
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));
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 */
260 switch (rss->mode) {
262 u32 word = be32_to_cpu(
264
265 rss->u.basicvirtual.synmapen =
266 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 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);
282 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
283
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
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));
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
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
355{
356 int err;
357
358 /*
359 * Wait for the device to become ready before proceeding ...
360 */
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;
377 adapter->params.vpd.cclk = 50000;
378
380 if (adapter->chip_params == NULL)
381 return -EINVAL;
382
383 return 0;
384}
385
386/*
387 * t4vf_get_vf_mac - Get the MAC address to be set to the VI of this VF.
388 * @adapter: The adapter
389 * @port: The port associated with vf
390 * @naddr: the number of ACL MAC addresses returned in addr
391 * @addr: Placeholder for MAC addresses
392 *
393 * Find the MAC address to be set to the VF's VI. The requested MAC address
394 * is from the host OS via callback in the PF driver.
395 */
396int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port,
397 unsigned int *naddr, u8 *addr)
398{
399 struct fw_acl_mac_cmd cmd;
400 int ret;
401
402 memset(&cmd, 0, sizeof(cmd));
406 cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
407 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
408 if (ret)
409 return ret;
410
411 if (cmd.nmac < *naddr)
412 *naddr = cmd.nmac;
413
414 switch (port) {
415 case 3:
416 memcpy(addr, cmd.macaddr3, sizeof(cmd.macaddr3));
417 break;
418 case 2:
419 memcpy(addr, cmd.macaddr2, sizeof(cmd.macaddr2));
420 break;
421 case 1:
422 memcpy(addr, cmd.macaddr1, sizeof(cmd.macaddr1));
423 break;
424 case 0:
425 memcpy(addr, cmd.macaddr0, sizeof(cmd.macaddr0));
426 break;
427 }
428
429 return ret;
430}
static uint32_t t4_read_reg(struct adapter *sc, uint32_t reg)
Definition: adapter.h:1104
#define CHELSIO_T5
Definition: common.h:415
const struct chip_params * t4_get_chip_params(int chipid)
Definition: t4_hw.c:9271
static int t4vf_wr_mbox(struct adapter *adap, const void *cmd, int size, void *rpl)
Definition: common.h:934
static int t4vf_query_params(struct adapter *adapter, unsigned int nparams, const u32 *params, u32 *vals)
Definition: common.h:920
static unsigned int core_ticks_to_us(const struct adapter *adapter, unsigned int ticks)
Definition: common.h:553
static int chip_id(struct adapter *adap)
Definition: common.h:512
static int is_t4(struct adapter *adap)
Definition: common.h:522
static int is_t5(struct adapter *adap)
Definition: common.h:527
#define be32_to_cpu(x)
Definition: osdep.h:107
uint8_t u8
Definition: osdep.h:59
#define CH_WARN(adap, fmt,...)
Definition: osdep.h:47
#define CH_ERR(adap, fmt,...)
Definition: osdep.h:45
uint32_t u32
Definition: osdep.h:61
#define cpu_to_be32(x)
Definition: osdep.h:110
unsigned int fpga
Definition: common.h:388
struct rss_params rss
Definition: common.h:364
struct sge_params sge
Definition: common.h:359
struct vf_resources vfres
Definition: common.h:365
unsigned int chipid
Definition: common.h:386
struct vpd_params vpd
Definition: common.h:361
uint8_t nports
Definition: common.h:384
const struct chip_params * chip_params
Definition: adapter.h:959
struct adapter_params params
Definition: adapter.h:958
device_t dev
Definition: adapter.h:866
__be32 r_caps_to_nethctrl
__be32 niqflint_niq
__be32 tc_to_nexactf
__be32 retval_len16
__be32 type_to_neq
union fw_rss_glb_config_cmd::fw_rss_glb_config u
unsigned int mode
Definition: common.h:326
u_int syn4tupenipv4
Definition: common.h:332
u_int ofdmapen
Definition: common.h:334
u_int syn2tupenipv4
Definition: common.h:333
u_int tnlalllookup
Definition: common.h:336
u_int synmapen
Definition: common.h:329
u_int tnlmapen
Definition: common.h:335
struct rss_params::@17::@18 basicvirtual
union rss_params::@17 u
u_int syn2tupenipv6
Definition: common.h:331
u_int syn4tupenipv6
Definition: common.h:330
u_int hashtoeplitz
Definition: common.h:337
int counter_val[SGE_NCOUNTERS]
Definition: common.h:239
int pad_boundary
Definition: common.h:246
int fl_starve_threshold2
Definition: common.h:241
u32 sge_control
Definition: common.h:249
int fl_starve_threshold
Definition: common.h:240
int page_shift
Definition: common.h:242
int timer_val[SGE_NTIMERS]
Definition: common.h:238
int pack_boundary
Definition: common.h:247
int spg_len
Definition: common.h:245
int fl_pktshift
Definition: common.h:248
u32 sge_fl_buffer_size[SGE_FLBUF_SIZES]
Definition: common.h:250
unsigned int niq
Definition: common.h:350
unsigned int niqflint
Definition: common.h:349
unsigned int wx_caps
Definition: common.h:355
unsigned int nexactf
Definition: common.h:353
unsigned int pmask
Definition: common.h:352
unsigned int r_caps
Definition: common.h:354
unsigned int neq
Definition: common.h:347
unsigned int nvi
Definition: common.h:346
unsigned int tc
Definition: common.h:351
unsigned int nethctrl
Definition: common.h:348
unsigned int cclk
Definition: common.h:279
@ SGE_FLBUF_SIZES
Definition: t4_hw.h:99
int port
Definition: t4_if.m:63
#define G_INGPACKBOUNDARY(x)
Definition: t4_regs.h:2313
#define S_QUEUESPERPAGEPF1
Definition: t4_regs.h:716
#define G_TIMERVALUE4(x)
Definition: t4_regs.h:1730
#define A_SGE_CONM_CTRL
Definition: t4_regs.h:1431
#define G_PKTSHIFT(x)
Definition: t4_regs.h:621
#define G_THRESHOLD_1(x)
Definition: t4_regs.h:1489
#define A_SGE_CONTROL2
Definition: t4_regs.h:2296
#define S_QUEUESPERPAGEPF0
Definition: t4_regs.h:721
#define G_THRESHOLD_2(x)
Definition: t4_regs.h:1494
#define S_HOSTPAGESIZEPF0
Definition: t4_regs.h:679
#define G_TIMERVALUE1(x)
Definition: t4_regs.h:1711
#define G_TIMERVALUE3(x)
Definition: t4_regs.h:1723
#define A_PL_VF_WHOAMI
Definition: t4_regs.h:37823
#define A_SGE_INGRESS_RX_THRESHOLD
Definition: t4_regs.h:1479
#define A_SGE_TIMER_VALUE_4_AND_5
Definition: t4_regs.h:1725
#define G_SOURCEPF(x)
Definition: t4_regs.h:37838
#define A_SGE_FL_BUFFER_SIZE0
Definition: t4_regs.h:1251
#define VF_PL_REG(reg_addr)
Definition: t4_regs.h:76
#define G_EGRTHRESHOLD(x)
Definition: t4_regs.h:1436
#define A_SGE_TIMER_VALUE_0_AND_1
Definition: t4_regs.h:1701
#define A_SGE_INGRESS_QUEUES_PER_PAGE_VF
Definition: t4_regs.h:2054
#define G_INGPADBOUNDARY(x)
Definition: t4_regs.h:631
#define G_THRESHOLD_3(x)
Definition: t4_regs.h:1499
#define A_SGE_HOST_PAGE_SIZE
Definition: t4_regs.h:642
#define M_QUEUESPERPAGEPF0
Definition: t4_regs.h:722
#define F_EGRSTATUSPAGESIZE
Definition: t4_regs.h:604
#define A_SGE_EGRESS_QUEUES_PER_PAGE_VF
Definition: t4_regs.h:726
#define G_TIMERVALUE2(x)
Definition: t4_regs.h:1718
#define G_EGRTHRESHOLDPACKING(x)
Definition: t4_regs.h:1454
#define M_HOSTPAGESIZEPF0
Definition: t4_regs.h:680
#define S_HOSTPAGESIZEPF1
Definition: t4_regs.h:674
#define G_TIMERVALUE0(x)
Definition: t4_regs.h:1706
#define G_THRESHOLD_0(x)
Definition: t4_regs.h:1484
#define G_TIMERVALUE5(x)
Definition: t4_regs.h:1735
#define A_SGE_CONTROL
Definition: t4_regs.h:578
#define A_SGE_TIMER_VALUE_2_AND_3
Definition: t4_regs.h:1713
#define G_T6_EGRTHRESHOLDPACKING(x)
Definition: t4_regs.h:1459
#define X_INGPADBOUNDARY_SHIFT
#define X_T6_INGPADBOUNDARY_SHIFT
#define G_FW_PFVF_CMD_NEXACTF(x)
@ FW_SUCCESS
#define F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6
#define F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4
#define V_FW_CMD_LEN16(x)
#define F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP
#define G_FW_PFVF_CMD_TC(x)
#define G_FW_PFVF_CMD_NIQ(x)
#define G_FW_PFVF_CMD_PMASK(x)
@ FW_ACL_MAC_CMD
@ FW_RSS_GLB_CONFIG_CMD
@ FW_RESET_CMD
@ FW_PFVF_CMD
#define F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN
#define F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4
#define G_FW_PFVF_CMD_NVI(x)
#define F_FW_CMD_WRITE
#define F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN
#define G_FW_PFVF_CMD_R_CAPS(x)
#define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL
#define F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ
#define V_FW_PARAMS_PARAM_XYZ(x)
#define V_FW_PARAMS_MNEM(x)
#define V_FW_CMD_OP(x)
#define G_FW_PFVF_CMD_WX_CAPS(x)
#define G_FW_RSS_GLB_CONFIG_CMD_MODE(x)
#define F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN
#define F_FW_CMD_READ
#define F_FW_CMD_REQUEST
@ FW_PARAMS_MNEM_REG
#define G_FW_PFVF_CMD_NETHCTRL(x)
#define G_FW_PFVF_CMD_NEQ(x)
#define G_FW_PFVF_CMD_NIQFLINT(x)
#define F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6
#define FW_LEN16(fw_struct)
int t4vf_wait_dev_ready(struct adapter *adapter)
Definition: t4vf_hw.c:47
int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port, unsigned int *naddr, u8 *addr)
Definition: t4vf_hw.c:396
int t4vf_get_sge_params(struct adapter *adapter)
Definition: t4vf_hw.c:93
int t4vf_get_rss_glb_config(struct adapter *adapter)
Definition: t4vf_hw.c:233
int t4vf_get_vfres(struct adapter *adapter)
Definition: t4vf_hw.c:308
__FBSDID("$FreeBSD$")
int t4vf_prep_adapter(struct adapter *adapter)
Definition: t4vf_hw.c:354
int t4vf_fw_reset(struct adapter *adapter)
Definition: t4vf_hw.c:74
#define msleep(x)
Definition: t4vf_hw.c:35
struct fw_rss_glb_config_cmd::fw_rss_glb_config::fw_rss_glb_config_basicvirtual basicvirtual
struct fw_rss_glb_config_cmd::fw_rss_glb_config::fw_rss_glb_config_manual manual