]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/cxgbe/common/t4vf_hw.c
MFC 303522,303647,303860,303880,304168-304170,304479,304482,304485,305548,
[FreeBSD/stable/10.git] / sys / dev / cxgbe / common / t4vf_hw.c
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
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  */
46 int 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  */
73 int 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  */
92 int 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;
133         else
134                 sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 +
135                     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);
171         sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) + 5);
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  */
225 int 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  */
300 int 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  */
346 int 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 }