]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/cxgbe/common/t4vf_hw.c
MFC 305695,305696,305699,305702,305703,305713,305715,305827,305852,305906,
[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 #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  */
47 int 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  */
74 int 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  */
93 int 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;
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          */
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);
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         }
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  */
233 int 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  */
308 int 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  */
354 int 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 }