addbf1c5d2c50fb778ec3dc5ca454c3cd58951c6
[deb_dpdk.git] / drivers / net / sfc / base / hunt_nic.c
1 /*
2  * Copyright (c) 2012-2016 Solarflare 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 are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30
31 #include "efx.h"
32 #include "efx_impl.h"
33 #if EFSYS_OPT_MON_MCDI
34 #include "mcdi_mon.h"
35 #endif
36
37 #if EFSYS_OPT_HUNTINGTON
38
39 #include "ef10_tlv_layout.h"
40
41 static  __checkReturn   efx_rc_t
42 hunt_nic_get_required_pcie_bandwidth(
43         __in            efx_nic_t *enp,
44         __out           uint32_t *bandwidth_mbpsp)
45 {
46         uint32_t port_modes;
47         uint32_t max_port_mode;
48         uint32_t bandwidth;
49         efx_rc_t rc;
50
51         /*
52          * On Huntington, the firmware may not give us the current port mode, so
53          * we need to go by the set of available port modes and assume the most
54          * capable mode is in use.
55          */
56
57         if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, NULL)) != 0) {
58                 /* No port mode info available */
59                 bandwidth = 0;
60                 goto out;
61         }
62
63         if (port_modes & (1 << TLV_PORT_MODE_40G_40G)) {
64                 /*
65                  * This needs the full PCIe bandwidth (and could use
66                  * more) - roughly 64 Gbit/s for 8 lanes of Gen3.
67                  */
68                 if ((rc = efx_nic_calculate_pcie_link_bandwidth(8,
69                             EFX_PCIE_LINK_SPEED_GEN3, &bandwidth)) != 0)
70                         goto fail1;
71         } else {
72                 if (port_modes & (1 << TLV_PORT_MODE_40G)) {
73                         max_port_mode = TLV_PORT_MODE_40G;
74                 } else if (port_modes & (1 << TLV_PORT_MODE_10G_10G_10G_10G)) {
75                         max_port_mode = TLV_PORT_MODE_10G_10G_10G_10G;
76                 } else {
77                         /* Assume two 10G ports */
78                         max_port_mode = TLV_PORT_MODE_10G_10G;
79                 }
80
81                 if ((rc = ef10_nic_get_port_mode_bandwidth(max_port_mode,
82                                                             &bandwidth)) != 0)
83                         goto fail2;
84         }
85
86 out:
87         *bandwidth_mbpsp = bandwidth;
88
89         return (0);
90
91 fail2:
92         EFSYS_PROBE(fail2);
93 fail1:
94         EFSYS_PROBE1(fail1, efx_rc_t, rc);
95
96         return (rc);
97 }
98
99         __checkReturn   efx_rc_t
100 hunt_board_cfg(
101         __in            efx_nic_t *enp)
102 {
103         efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
104         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
105         uint8_t mac_addr[6] = { 0 };
106         uint32_t board_type = 0;
107         ef10_link_state_t els;
108         efx_port_t *epp = &(enp->en_port);
109         uint32_t port;
110         uint32_t pf;
111         uint32_t vf;
112         uint32_t mask;
113         uint32_t flags;
114         uint32_t sysclk, dpcpu_clk;
115         uint32_t base, nvec;
116         uint32_t bandwidth;
117         efx_rc_t rc;
118
119         if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0)
120                 goto fail1;
121
122         /*
123          * NOTE: The MCDI protocol numbers ports from zero.
124          * The common code MCDI interface numbers ports from one.
125          */
126         emip->emi_port = port + 1;
127
128         if ((rc = ef10_external_port_mapping(enp, port,
129                     &encp->enc_external_port)) != 0)
130                 goto fail2;
131
132         /*
133          * Get PCIe function number from firmware (used for
134          * per-function privilege and dynamic config info).
135          *  - PCIe PF: pf = PF number, vf = 0xffff.
136          *  - PCIe VF: pf = parent PF, vf = VF number.
137          */
138         if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0)
139                 goto fail3;
140
141         encp->enc_pf = pf;
142         encp->enc_vf = vf;
143
144         /* MAC address for this function */
145         if (EFX_PCI_FUNCTION_IS_PF(encp)) {
146                 rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
147                 if ((rc == 0) && (mac_addr[0] & 0x02)) {
148                         /*
149                          * If the static config does not include a global MAC
150                          * address pool then the board may return a locally
151                          * administered MAC address (this should only happen on
152                          * incorrectly programmed boards).
153                          */
154                         rc = EINVAL;
155                 }
156         } else {
157                 rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
158         }
159         if (rc != 0)
160                 goto fail4;
161
162         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
163
164         /* Board configuration */
165         rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL);
166         if (rc != 0) {
167                 /* Unprivileged functions may not be able to read board cfg */
168                 if (rc == EACCES)
169                         board_type = 0;
170                 else
171                         goto fail5;
172         }
173
174         encp->enc_board_type = board_type;
175         encp->enc_clk_mult = 1; /* not used for Huntington */
176
177         /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
178         if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
179                 goto fail6;
180
181         /* Obtain the default PHY advertised capabilities */
182         if ((rc = ef10_phy_get_link(enp, &els)) != 0)
183                 goto fail7;
184         epp->ep_default_adv_cap_mask = els.els_adv_cap_mask;
185         epp->ep_adv_cap_mask = els.els_adv_cap_mask;
186
187         /*
188          * Enable firmware workarounds for hardware errata.
189          * Expected responses are:
190          *  - 0 (zero):
191          *      Success: workaround enabled or disabled as requested.
192          *  - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
193          *      Firmware does not support the MC_CMD_WORKAROUND request.
194          *      (assume that the workaround is not supported).
195          *  - MC_CMD_ERR_ENOENT (reported as ENOENT):
196          *      Firmware does not support the requested workaround.
197          *  - MC_CMD_ERR_EPERM  (reported as EACCES):
198          *      Unprivileged function cannot enable/disable workarounds.
199          *
200          * See efx_mcdi_request_errcode() for MCDI error translations.
201          */
202
203         /*
204          * If the bug35388 workaround is enabled, then use an indirect access
205          * method to avoid unsafe EVQ writes.
206          */
207         rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG35388, B_TRUE,
208             NULL);
209         if ((rc == 0) || (rc == EACCES))
210                 encp->enc_bug35388_workaround = B_TRUE;
211         else if ((rc == ENOTSUP) || (rc == ENOENT))
212                 encp->enc_bug35388_workaround = B_FALSE;
213         else
214                 goto fail8;
215
216         /*
217          * If the bug41750 workaround is enabled, then do not test interrupts,
218          * as the test will fail (seen with Greenport controllers).
219          */
220         rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG41750, B_TRUE,
221             NULL);
222         if (rc == 0) {
223                 encp->enc_bug41750_workaround = B_TRUE;
224         } else if (rc == EACCES) {
225                 /* Assume a controller with 40G ports needs the workaround. */
226                 if (epp->ep_default_adv_cap_mask & EFX_PHY_CAP_40000FDX)
227                         encp->enc_bug41750_workaround = B_TRUE;
228                 else
229                         encp->enc_bug41750_workaround = B_FALSE;
230         } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
231                 encp->enc_bug41750_workaround = B_FALSE;
232         } else {
233                 goto fail9;
234         }
235         if (EFX_PCI_FUNCTION_IS_VF(encp)) {
236                 /* Interrupt testing does not work for VFs. See bug50084. */
237                 encp->enc_bug41750_workaround = B_TRUE;
238         }
239
240         /*
241          * If the bug26807 workaround is enabled, then firmware has enabled
242          * support for chained multicast filters. Firmware will reset (FLR)
243          * functions which have filters in the hardware filter table when the
244          * workaround is enabled/disabled.
245          *
246          * We must recheck if the workaround is enabled after inserting the
247          * first hardware filter, in case it has been changed since this check.
248          */
249         rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807,
250             B_TRUE, &flags);
251         if (rc == 0) {
252                 encp->enc_bug26807_workaround = B_TRUE;
253                 if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) {
254                         /*
255                          * Other functions had installed filters before the
256                          * workaround was enabled, and they have been reset
257                          * by firmware.
258                          */
259                         EFSYS_PROBE(bug26807_workaround_flr_done);
260                         /* FIXME: bump MC warm boot count ? */
261                 }
262         } else if (rc == EACCES) {
263                 /*
264                  * Unprivileged functions cannot enable the workaround in older
265                  * firmware.
266                  */
267                 encp->enc_bug26807_workaround = B_FALSE;
268         } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
269                 encp->enc_bug26807_workaround = B_FALSE;
270         } else {
271                 goto fail10;
272         }
273
274         /* Get clock frequencies (in MHz). */
275         if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0)
276                 goto fail11;
277
278         /*
279          * The Huntington timer quantum is 1536 sysclk cycles, documented for
280          * the EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units.
281          */
282         encp->enc_evq_timer_quantum_ns = 1536000UL / sysclk; /* 1536 cycles */
283         if (encp->enc_bug35388_workaround) {
284                 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
285                 ERF_DD_EVQ_IND_TIMER_VAL_WIDTH) / 1000;
286         } else {
287                 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
288                 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
289         }
290
291         encp->enc_bug61265_workaround = B_FALSE; /* Medford only */
292
293         /* Check capabilities of running datapath firmware */
294         if ((rc = ef10_get_datapath_caps(enp)) != 0)
295                 goto fail12;
296
297         /* Alignment for receive packet DMA buffers */
298         encp->enc_rx_buf_align_start = 1;
299         encp->enc_rx_buf_align_end = 64; /* RX DMA end padding */
300
301         /* Alignment for WPTR updates */
302         encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
303
304         encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT);
305         /* No boundary crossing limits */
306         encp->enc_tx_dma_desc_boundary = 0;
307
308         /*
309          * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
310          * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
311          * resources (allocated to this PCIe function), which is zero until
312          * after we have allocated VIs.
313          */
314         encp->enc_evq_limit = 1024;
315         encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
316         encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
317
318         /*
319          * The workaround for bug35388 uses the top bit of transmit queue
320          * descriptor writes, preventing the use of 4096 descriptor TXQs.
321          */
322         encp->enc_txq_max_ndescs = encp->enc_bug35388_workaround ? 2048 : 4096;
323
324         encp->enc_buftbl_limit = 0xFFFFFFFF;
325
326         encp->enc_piobuf_limit = HUNT_PIOBUF_NBUFS;
327         encp->enc_piobuf_size = HUNT_PIOBUF_SIZE;
328         encp->enc_piobuf_min_alloc_size = HUNT_MIN_PIO_ALLOC_SIZE;
329
330         /*
331          * Get the current privilege mask. Note that this may be modified
332          * dynamically, so this value is informational only. DO NOT use
333          * the privilege mask to check for sufficient privileges, as that
334          * can result in time-of-check/time-of-use bugs.
335          */
336         if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0)
337                 goto fail13;
338         encp->enc_privilege_mask = mask;
339
340         /* Get interrupt vector limits */
341         if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
342                 if (EFX_PCI_FUNCTION_IS_PF(encp))
343                         goto fail14;
344
345                 /* Ignore error (cannot query vector limits from a VF). */
346                 base = 0;
347                 nvec = 1024;
348         }
349         encp->enc_intr_vec_base = base;
350         encp->enc_intr_limit = nvec;
351
352         /*
353          * Maximum number of bytes into the frame the TCP header can start for
354          * firmware assisted TSO to work.
355          */
356         encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
357
358         if ((rc = hunt_nic_get_required_pcie_bandwidth(enp, &bandwidth)) != 0)
359                 goto fail15;
360         encp->enc_required_pcie_bandwidth_mbps = bandwidth;
361
362         /* All Huntington devices have a PCIe Gen3, 8 lane connector */
363         encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3;
364
365         return (0);
366
367 fail15:
368         EFSYS_PROBE(fail15);
369 fail14:
370         EFSYS_PROBE(fail14);
371 fail13:
372         EFSYS_PROBE(fail13);
373 fail12:
374         EFSYS_PROBE(fail12);
375 fail11:
376         EFSYS_PROBE(fail11);
377 fail10:
378         EFSYS_PROBE(fail10);
379 fail9:
380         EFSYS_PROBE(fail9);
381 fail8:
382         EFSYS_PROBE(fail8);
383 fail7:
384         EFSYS_PROBE(fail7);
385 fail6:
386         EFSYS_PROBE(fail6);
387 fail5:
388         EFSYS_PROBE(fail5);
389 fail4:
390         EFSYS_PROBE(fail4);
391 fail3:
392         EFSYS_PROBE(fail3);
393 fail2:
394         EFSYS_PROBE(fail2);
395 fail1:
396         EFSYS_PROBE1(fail1, efx_rc_t, rc);
397
398         return (rc);
399 }
400
401
402 #endif  /* EFSYS_OPT_HUNTINGTON */