1 /******************************************************************************
2
3 Copyright (c) 2013-2020, Intel Corporation
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31
32 ******************************************************************************/
33
34 #include "ixl_pf.h"
35
36 void
ixl_configure_tx_itr(struct ixl_pf * pf)37 ixl_configure_tx_itr(struct ixl_pf *pf)
38 {
39 struct i40e_hw *hw = &pf->hw;
40 struct ixl_vsi *vsi = &pf->vsi;
41 struct ixl_tx_queue *que = vsi->tx_queues;
42
43 vsi->tx_itr_setting = pf->tx_itr;
44
45 for (int i = 0; i < vsi->num_tx_queues; i++, que++) {
46 struct tx_ring *txr = &que->txr;
47
48 wr32(hw, I40E_PFINT_ITRN(IXL_TX_ITR, i),
49 vsi->tx_itr_setting);
50 txr->itr = vsi->tx_itr_setting;
51 txr->latency = IXL_AVE_LATENCY;
52 }
53 }
54
55 void
ixl_configure_rx_itr(struct ixl_pf * pf)56 ixl_configure_rx_itr(struct ixl_pf *pf)
57 {
58 struct i40e_hw *hw = &pf->hw;
59 struct ixl_vsi *vsi = &pf->vsi;
60 struct ixl_rx_queue *que = vsi->rx_queues;
61
62 vsi->rx_itr_setting = pf->rx_itr;
63
64 for (int i = 0; i < vsi->num_rx_queues; i++, que++) {
65 struct rx_ring *rxr = &que->rxr;
66
67 wr32(hw, I40E_PFINT_ITRN(IXL_RX_ITR, i),
68 vsi->rx_itr_setting);
69 rxr->itr = vsi->rx_itr_setting;
70 rxr->latency = IXL_AVE_LATENCY;
71 }
72 }
73
74 int
ixl_intr(void * arg)75 ixl_intr(void *arg)
76 {
77 struct ixl_pf *pf = arg;
78 struct i40e_hw *hw = &pf->hw;
79 struct ixl_vsi *vsi = &pf->vsi;
80 struct ixl_rx_queue *que = vsi->rx_queues;
81 u32 icr0;
82
83 ++que->irqs;
84
85 /* Clear PBA at start of ISR if using legacy interrupts */
86 if (vsi->shared->isc_intr == IFLIB_INTR_LEGACY)
87 wr32(hw, I40E_PFINT_DYN_CTL0,
88 I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
89 (IXL_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT));
90
91 icr0 = rd32(hw, I40E_PFINT_ICR0);
92
93
94 #ifdef PCI_IOV
95 if (icr0 & I40E_PFINT_ICR0_VFLR_MASK)
96 iflib_iov_intr_deferred(vsi->ctx);
97 #endif
98
99 if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK)
100 iflib_admin_intr_deferred(vsi->ctx);
101
102 ixl_enable_intr0(hw);
103
104 if (icr0 & I40E_PFINT_ICR0_QUEUE_0_MASK)
105 return (FILTER_SCHEDULE_THREAD);
106 else
107 return (FILTER_HANDLED);
108 }
109
110 /*********************************************************************
111 *
112 * MSI-X VSI Interrupt Service routine
113 *
114 **********************************************************************/
115 int
ixl_msix_que(void * arg)116 ixl_msix_que(void *arg)
117 {
118 struct ixl_rx_queue *rx_que = arg;
119
120 ++rx_que->irqs;
121
122 ixl_set_queue_rx_itr(rx_que);
123
124 return (FILTER_SCHEDULE_THREAD);
125 }
126
127 /*********************************************************************
128 *
129 * MSI-X Admin Queue Interrupt Service routine
130 *
131 **********************************************************************/
132 int
ixl_msix_adminq(void * arg)133 ixl_msix_adminq(void *arg)
134 {
135 struct ixl_pf *pf = arg;
136 struct i40e_hw *hw = &pf->hw;
137 device_t dev = pf->dev;
138 u32 reg, mask, rstat_reg;
139 bool do_task = FALSE;
140
141 DDPRINTF(dev, "begin");
142
143 ++pf->admin_irq;
144
145 reg = rd32(hw, I40E_PFINT_ICR0);
146 /*
147 * For masking off interrupt causes that need to be handled before
148 * they can be re-enabled
149 */
150 mask = rd32(hw, I40E_PFINT_ICR0_ENA);
151
152 /* Check on the cause */
153 if (reg & I40E_PFINT_ICR0_ADMINQ_MASK) {
154 mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK;
155 do_task = TRUE;
156 }
157
158 if (reg & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
159 mask &= ~I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK;
160 ixl_set_state(&pf->state, IXL_STATE_MDD_PENDING);
161 do_task = TRUE;
162 }
163
164 if (reg & I40E_PFINT_ICR0_GRST_MASK) {
165 const char *reset_type;
166 mask &= ~I40E_PFINT_ICR0_ENA_GRST_MASK;
167 rstat_reg = rd32(hw, I40E_GLGEN_RSTAT);
168 rstat_reg = (rstat_reg & I40E_GLGEN_RSTAT_RESET_TYPE_MASK)
169 >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
170 switch (rstat_reg) {
171 /* These others might be handled similarly to an EMPR reset */
172 case I40E_RESET_CORER:
173 reset_type = "CORER";
174 break;
175 case I40E_RESET_GLOBR:
176 reset_type = "GLOBR";
177 break;
178 case I40E_RESET_EMPR:
179 reset_type = "EMPR";
180 break;
181 default:
182 reset_type = "POR";
183 break;
184 }
185 device_printf(dev, "Reset Requested! (%s)\n", reset_type);
186 /* overload admin queue task to check reset progress */
187 ixl_set_state(&pf->state, IXL_STATE_RESETTING);
188 do_task = TRUE;
189 }
190
191 /*
192 * PE / PCI / ECC exceptions are all handled in the same way:
193 * mask out these three causes, then request a PF reset
194 */
195 if (reg & I40E_PFINT_ICR0_ECC_ERR_MASK)
196 device_printf(dev, "ECC Error detected!\n");
197 if (reg & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK)
198 device_printf(dev, "PCI Exception detected!\n");
199 if (reg & I40E_PFINT_ICR0_PE_CRITERR_MASK)
200 device_printf(dev, "Critical Protocol Engine Error detected!\n");
201 /* Checks against the conditions above */
202 if (reg & IXL_ICR0_CRIT_ERR_MASK) {
203 mask &= ~IXL_ICR0_CRIT_ERR_MASK;
204 ixl_set_state(&pf->state, IXL_STATE_PF_RESET_REQ);
205 ixl_set_state(&pf->state, IXL_STATE_PF_CRIT_ERR);
206 do_task = TRUE;
207 }
208
209 if (reg & I40E_PFINT_ICR0_HMC_ERR_MASK) {
210 reg = rd32(hw, I40E_PFHMC_ERRORINFO);
211 if (reg & I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK) {
212 device_printf(dev, "HMC Error detected!\n");
213 device_printf(dev, "INFO 0x%08x\n", reg);
214 reg = rd32(hw, I40E_PFHMC_ERRORDATA);
215 device_printf(dev, "DATA 0x%08x\n", reg);
216 wr32(hw, I40E_PFHMC_ERRORINFO, 0);
217 }
218 }
219
220 #ifdef PCI_IOV
221 if (reg & I40E_PFINT_ICR0_VFLR_MASK) {
222 mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK;
223 iflib_iov_intr_deferred(pf->vsi.ctx);
224 }
225 #endif
226
227 wr32(hw, I40E_PFINT_ICR0_ENA, mask);
228 ixl_enable_intr0(hw);
229
230 if (do_task)
231 return (FILTER_SCHEDULE_THREAD);
232 else
233 return (FILTER_HANDLED);
234 }
235
236 /*
237 * Configure queue interrupt cause registers in hardware.
238 *
239 * Linked list for each vector LNKLSTN(i) -> RQCTL(i) -> TQCTL(i) -> EOL
240 */
241 void
ixl_configure_queue_intr_msix(struct ixl_pf * pf)242 ixl_configure_queue_intr_msix(struct ixl_pf *pf)
243 {
244 struct i40e_hw *hw = &pf->hw;
245 struct ixl_vsi *vsi = &pf->vsi;
246 u32 reg;
247 u16 vector = 1;
248
249 for (int i = 0; i < max(vsi->num_rx_queues, vsi->num_tx_queues); i++, vector++) {
250 /* Make sure interrupt is disabled */
251 wr32(hw, I40E_PFINT_DYN_CTLN(i), 0);
252 /* Set linked list head to point to corresponding RX queue
253 * e.g. vector 1 (LNKLSTN register 0) points to queue pair 0's RX queue */
254 reg = ((i << I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
255 & I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) |
256 ((I40E_QUEUE_TYPE_RX << I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
257 & I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_MASK);
258 wr32(hw, I40E_PFINT_LNKLSTN(i), reg);
259
260 reg = I40E_QINT_RQCTL_CAUSE_ENA_MASK |
261 (IXL_RX_ITR << I40E_QINT_RQCTL_ITR_INDX_SHIFT) |
262 (vector << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) |
263 (i << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) |
264 (I40E_QUEUE_TYPE_TX << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT);
265 wr32(hw, I40E_QINT_RQCTL(i), reg);
266
267 reg = I40E_QINT_TQCTL_CAUSE_ENA_MASK |
268 (IXL_TX_ITR << I40E_QINT_TQCTL_ITR_INDX_SHIFT) |
269 (vector << I40E_QINT_TQCTL_MSIX_INDX_SHIFT) |
270 (IXL_QUEUE_EOL << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT) |
271 (I40E_QUEUE_TYPE_RX << I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT);
272 wr32(hw, I40E_QINT_TQCTL(i), reg);
273 }
274 }
275
276 /*
277 * Configure for single interrupt vector operation
278 */
279 void
ixl_configure_legacy(struct ixl_pf * pf)280 ixl_configure_legacy(struct ixl_pf *pf)
281 {
282 struct i40e_hw *hw = &pf->hw;
283 struct ixl_vsi *vsi = &pf->vsi;
284 u32 reg;
285
286 vsi->rx_queues[0].rxr.itr = vsi->rx_itr_setting;
287
288 /* Setup "other" causes */
289 reg = I40E_PFINT_ICR0_ENA_ECC_ERR_MASK
290 | I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK
291 | I40E_PFINT_ICR0_ENA_GRST_MASK
292 | I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK
293 | I40E_PFINT_ICR0_ENA_HMC_ERR_MASK
294 | I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK
295 | I40E_PFINT_ICR0_ENA_VFLR_MASK
296 | I40E_PFINT_ICR0_ENA_ADMINQ_MASK
297 ;
298 wr32(hw, I40E_PFINT_ICR0_ENA, reg);
299
300 /* No ITR for non-queue interrupts */
301 wr32(hw, I40E_PFINT_STAT_CTL0,
302 IXL_ITR_NONE << I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT);
303
304 /* FIRSTQ_INDX = 0, FIRSTQ_TYPE = 0 (rx) */
305 wr32(hw, I40E_PFINT_LNKLST0, 0);
306
307 /* Associate the queue pair to the vector and enable the q int */
308 reg = I40E_QINT_RQCTL_CAUSE_ENA_MASK
309 | (IXL_RX_ITR << I40E_QINT_RQCTL_ITR_INDX_SHIFT)
310 | (I40E_QUEUE_TYPE_TX << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT);
311 wr32(hw, I40E_QINT_RQCTL(0), reg);
312
313 reg = I40E_QINT_TQCTL_CAUSE_ENA_MASK
314 | (IXL_TX_ITR << I40E_QINT_TQCTL_ITR_INDX_SHIFT)
315 | (IXL_QUEUE_EOL << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT);
316 wr32(hw, I40E_QINT_TQCTL(0), reg);
317 }
318
319 void
ixl_free_pci_resources(struct ixl_pf * pf)320 ixl_free_pci_resources(struct ixl_pf *pf)
321 {
322 struct ixl_vsi *vsi = &pf->vsi;
323 device_t dev = iflib_get_dev(vsi->ctx);
324 struct ixl_rx_queue *rx_que = vsi->rx_queues;
325
326 /* We may get here before stations are set up */
327 if (rx_que == NULL)
328 goto early;
329
330 /*
331 ** Release all MSI-X VSI resources:
332 */
333 iflib_irq_free(vsi->ctx, &vsi->irq);
334
335 for (int i = 0; i < vsi->num_rx_queues; i++, rx_que++)
336 iflib_irq_free(vsi->ctx, &rx_que->que_irq);
337 early:
338 if (pf->pci_mem != NULL)
339 bus_release_resource(dev, SYS_RES_MEMORY,
340 rman_get_rid(pf->pci_mem), pf->pci_mem);
341 }
342
343 /*********************************************************************
344 *
345 * Setup networking device structure and register an interface.
346 *
347 **********************************************************************/
348 int
ixl_setup_interface(device_t dev,struct ixl_pf * pf)349 ixl_setup_interface(device_t dev, struct ixl_pf *pf)
350 {
351 struct ixl_vsi *vsi = &pf->vsi;
352 if_ctx_t ctx = vsi->ctx;
353 struct i40e_hw *hw = &pf->hw;
354 if_t ifp = iflib_get_ifp(ctx);
355 struct i40e_aq_get_phy_abilities_resp abilities;
356 enum i40e_status_code aq_error = 0;
357
358 INIT_DBG_DEV(dev, "begin");
359
360 vsi->shared->isc_max_frame_size =
361 if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN
362 + ETHER_VLAN_ENCAP_LEN;
363
364 if (IXL_PF_IN_RECOVERY_MODE(pf))
365 goto only_auto;
366
367 aq_error = i40e_aq_get_phy_capabilities(hw,
368 FALSE, TRUE, &abilities, NULL);
369 /* May need delay to detect fiber correctly */
370 if (aq_error == I40E_ERR_UNKNOWN_PHY) {
371 i40e_msec_delay(200);
372 aq_error = i40e_aq_get_phy_capabilities(hw, FALSE,
373 TRUE, &abilities, NULL);
374 }
375 if (aq_error) {
376 if (aq_error == I40E_ERR_UNKNOWN_PHY)
377 device_printf(dev, "Unknown PHY type detected!\n");
378 else
379 device_printf(dev,
380 "Error getting supported media types, err %d,"
381 " AQ error %d\n", aq_error, hw->aq.asq_last_status);
382 } else {
383 pf->supported_speeds = abilities.link_speed;
384 if_setbaudrate(ifp, ixl_max_aq_speed_to_value(pf->supported_speeds));
385
386 ixl_add_ifmedia(vsi->media, hw->phy.phy_types);
387 }
388
389 only_auto:
390 /* Use autoselect media by default */
391 ifmedia_add(vsi->media, IFM_ETHER | IFM_AUTO, 0, NULL);
392 ifmedia_set(vsi->media, IFM_ETHER | IFM_AUTO);
393
394 return (0);
395 }
396
397 /*
398 ** Run when the Admin Queue gets a link state change interrupt.
399 */
400 void
ixl_link_event(struct ixl_pf * pf,struct i40e_arq_event_info * e)401 ixl_link_event(struct ixl_pf *pf, struct i40e_arq_event_info *e)
402 {
403 struct i40e_hw *hw = &pf->hw;
404 device_t dev = iflib_get_dev(pf->vsi.ctx);
405 struct i40e_link_status *link_info = &hw->phy.link_info;
406
407 /* Driver needs to re-enable delivering of link status events
408 * by FW after each event reception. Call i40e_get_link_status
409 * to do that. To not lose information about link state changes,
410 * which happened between receiving an event and the call,
411 * do not rely on status from event but use most recent
412 * status information retrieved by the call. */
413 hw->phy.get_link_info = TRUE;
414 i40e_get_link_status(hw, &pf->link_up);
415
416 /* Print out message if an unqualified module is found */
417 if ((link_info->link_info & I40E_AQ_MEDIA_AVAILABLE) &&
418 (pf->advertised_speed) &&
419 (if_getflags(pf->vsi.ifp) & IFF_UP) &&
420 (!(link_info->an_info & I40E_AQ_QUALIFIED_MODULE)) &&
421 (!(link_info->link_info & I40E_AQ_LINK_UP)))
422 device_printf(dev, "Link failed because "
423 "an unqualified module was detected!\n");
424
425 /* OS link info is updated elsewhere */
426 }
427
428 /*********************************************************************
429 *
430 * Initialize the VSI: this handles contexts, which means things
431 * like the number of descriptors, buffer size,
432 * plus we init the rings thru this function.
433 *
434 **********************************************************************/
435 int
ixl_initialize_vsi(struct ixl_vsi * vsi)436 ixl_initialize_vsi(struct ixl_vsi *vsi)
437 {
438 struct ixl_pf *pf = vsi->back;
439 if_softc_ctx_t scctx = iflib_get_softc_ctx(vsi->ctx);
440 struct ixl_tx_queue *tx_que = vsi->tx_queues;
441 struct ixl_rx_queue *rx_que = vsi->rx_queues;
442 device_t dev = iflib_get_dev(vsi->ctx);
443 struct i40e_hw *hw = vsi->hw;
444 struct i40e_vsi_context ctxt;
445 int tc_queues;
446 int err = 0;
447
448 memset(&ctxt, 0, sizeof(ctxt));
449 ctxt.seid = vsi->seid;
450 if (pf->veb_seid != 0)
451 ctxt.uplink_seid = pf->veb_seid;
452 ctxt.pf_num = hw->pf_id;
453 err = i40e_aq_get_vsi_params(hw, &ctxt, NULL);
454 if (err) {
455 device_printf(dev, "i40e_aq_get_vsi_params() failed, error %d"
456 " aq_error %d\n", err, hw->aq.asq_last_status);
457 return (err);
458 }
459 ixl_dbg(pf, IXL_DBG_SWITCH_INFO,
460 "get_vsi_params: seid: %d, uplinkseid: %d, vsi_number: %d, "
461 "vsis_allocated: %d, vsis_unallocated: %d, flags: 0x%x, "
462 "pfnum: %d, vfnum: %d, stat idx: %d, enabled: %d\n", ctxt.seid,
463 ctxt.uplink_seid, ctxt.vsi_number,
464 ctxt.vsis_allocated, ctxt.vsis_unallocated,
465 ctxt.flags, ctxt.pf_num, ctxt.vf_num,
466 ctxt.info.stat_counter_idx, ctxt.info.up_enable_bits);
467 /*
468 ** Set the queue and traffic class bits
469 ** - when multiple traffic classes are supported
470 ** this will need to be more robust.
471 */
472 ctxt.info.valid_sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID;
473 ctxt.info.mapping_flags |= I40E_AQ_VSI_QUE_MAP_CONTIG;
474 /* In contig mode, que_mapping[0] is first queue index used by this VSI */
475 ctxt.info.queue_mapping[0] = 0;
476 /*
477 * This VSI will only use traffic class 0; start traffic class 0's
478 * queue allocation at queue 0, and assign it 2^tc_queues queues (though
479 * the driver may not use all of them).
480 */
481 tc_queues = fls(pf->qtag.num_allocated) - 1;
482 ctxt.info.tc_mapping[0] = ((pf->qtag.first_qidx << I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT)
483 & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) |
484 ((tc_queues << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT)
485 & I40E_AQ_VSI_TC_QUE_NUMBER_MASK);
486
487 /* Set VLAN receive stripping mode */
488 ctxt.info.valid_sections |= I40E_AQ_VSI_PROP_VLAN_VALID;
489 ctxt.info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_ALL;
490 if (if_getcapenable(vsi->ifp) & IFCAP_VLAN_HWTAGGING)
491 ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH;
492 else
493 ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_EMOD_NOTHING;
494
495 #ifdef IXL_IW
496 /* Set TCP Enable for iWARP capable VSI */
497 if (ixl_enable_iwarp && pf->iw_enabled) {
498 ctxt.info.valid_sections |=
499 htole16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
500 ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA;
501 }
502 #endif
503 /*
504 * Save the VSI number and info for later. A changed counter index
505 * begins a new statistics epoch.
506 */
507 if (vsi->stat_offsets_loaded &&
508 vsi->info.stat_counter_idx != ctxt.info.stat_counter_idx)
509 ixl_vsi_reset_stats(vsi);
510 vsi->vsi_num = ctxt.vsi_number;
511 bcopy(&ctxt.info, &vsi->info, sizeof(vsi->info));
512
513 ctxt.flags = htole16(I40E_AQ_VSI_TYPE_PF);
514
515 err = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
516 if (err) {
517 device_printf(dev, "i40e_aq_update_vsi_params() failed, error %d,"
518 " aq_error %d\n", err, hw->aq.asq_last_status);
519 return (err);
520 }
521
522 for (int i = 0; i < vsi->num_tx_queues; i++, tx_que++) {
523 struct tx_ring *txr = &tx_que->txr;
524 struct i40e_hmc_obj_txq tctx;
525 u32 txctl;
526
527 /* Setup the HMC TX Context */
528 bzero(&tctx, sizeof(tctx));
529 tctx.new_context = 1;
530 tctx.base = (txr->tx_paddr/IXL_TX_CTX_BASE_UNITS);
531 tctx.qlen = scctx->isc_ntxd[0];
532 tctx.fc_ena = 0; /* Disable FCoE */
533 /*
534 * This value needs to pulled from the VSI that this queue
535 * is assigned to. Index into array is traffic class.
536 */
537 tctx.rdylist = vsi->info.qs_handle[0];
538 /*
539 * Set these to enable Head Writeback
540 * - Address is last entry in TX ring (reserved for HWB index)
541 * Leave these as 0 for Descriptor Writeback
542 */
543 if (vsi->enable_head_writeback) {
544 tctx.head_wb_ena = 1;
545 tctx.head_wb_addr = txr->tx_paddr +
546 (scctx->isc_ntxd[0] * sizeof(struct i40e_tx_desc));
547 } else {
548 tctx.head_wb_ena = 0;
549 tctx.head_wb_addr = 0;
550 }
551 tctx.rdylist_act = 0;
552 err = i40e_clear_lan_tx_queue_context(hw, i);
553 if (err) {
554 device_printf(dev, "Unable to clear TX context\n");
555 break;
556 }
557 err = i40e_set_lan_tx_queue_context(hw, i, &tctx);
558 if (err) {
559 device_printf(dev, "Unable to set TX context\n");
560 break;
561 }
562 /* Associate the ring with this PF */
563 txctl = I40E_QTX_CTL_PF_QUEUE;
564 txctl |= ((hw->pf_id << I40E_QTX_CTL_PF_INDX_SHIFT) &
565 I40E_QTX_CTL_PF_INDX_MASK);
566 wr32(hw, I40E_QTX_CTL(i), txctl);
567 ixl_flush(hw);
568
569 /* Do ring (re)init */
570 ixl_init_tx_ring(vsi, tx_que);
571 }
572 for (int i = 0; i < vsi->num_rx_queues; i++, rx_que++) {
573 struct rx_ring *rxr = &rx_que->rxr;
574 struct i40e_hmc_obj_rxq rctx;
575
576 /* Next setup the HMC RX Context */
577 rxr->mbuf_sz = iflib_get_rx_mbuf_sz(vsi->ctx);
578
579 u16 max_rxmax = rxr->mbuf_sz * hw->func_caps.rx_buf_chain_len;
580
581 /* Set up an RX context for the HMC */
582 memset(&rctx, 0, sizeof(struct i40e_hmc_obj_rxq));
583 rctx.dbuff = rxr->mbuf_sz >> I40E_RXQ_CTX_DBUFF_SHIFT;
584 /* ignore header split for now */
585 rctx.hbuff = 0 >> I40E_RXQ_CTX_HBUFF_SHIFT;
586 rctx.rxmax = (scctx->isc_max_frame_size < max_rxmax) ?
587 scctx->isc_max_frame_size : max_rxmax;
588 rctx.dtype = 0;
589 rctx.dsize = 1; /* do 32byte descriptors */
590 rctx.hsplit_0 = 0; /* no header split */
591 rctx.base = (rxr->rx_paddr/IXL_RX_CTX_BASE_UNITS);
592 rctx.qlen = scctx->isc_nrxd[0];
593 rctx.tphrdesc_ena = 1;
594 rctx.tphwdesc_ena = 1;
595 rctx.tphdata_ena = 0; /* Header Split related */
596 rctx.tphhead_ena = 0; /* Header Split related */
597 rctx.lrxqthresh = 1; /* Interrupt at <64 desc avail */
598 rctx.crcstrip = 1;
599 rctx.l2tsel = 1;
600 rctx.showiv = 1; /* Strip inner VLAN header */
601 rctx.fc_ena = 0; /* Disable FCoE */
602 rctx.prefena = 1; /* Prefetch descriptors */
603
604 err = i40e_clear_lan_rx_queue_context(hw, i);
605 if (err) {
606 device_printf(dev,
607 "Unable to clear RX context %d\n", i);
608 break;
609 }
610 err = i40e_set_lan_rx_queue_context(hw, i, &rctx);
611 if (err) {
612 device_printf(dev, "Unable to set RX context %d\n", i);
613 break;
614 }
615 wr32(vsi->hw, I40E_QRX_TAIL(i), 0);
616 }
617 return (err);
618 }
619
620
621 /*
622 ** Provide a update to the queue RX
623 ** interrupt moderation value.
624 */
625 void
ixl_set_queue_rx_itr(struct ixl_rx_queue * que)626 ixl_set_queue_rx_itr(struct ixl_rx_queue *que)
627 {
628 struct ixl_vsi *vsi = que->vsi;
629 struct ixl_pf *pf = (struct ixl_pf *)vsi->back;
630 struct i40e_hw *hw = vsi->hw;
631 struct rx_ring *rxr = &que->rxr;
632 u16 rx_itr;
633 u16 rx_latency = 0;
634 int rx_bytes;
635
636 /* Idle, do nothing */
637 if (rxr->bytes == 0)
638 return;
639
640 if (pf->dynamic_rx_itr) {
641 rx_bytes = rxr->bytes/rxr->itr;
642 rx_itr = rxr->itr;
643
644 /* Adjust latency range */
645 switch (rxr->latency) {
646 case IXL_LOW_LATENCY:
647 if (rx_bytes > 10) {
648 rx_latency = IXL_AVE_LATENCY;
649 rx_itr = IXL_ITR_20K;
650 }
651 break;
652 case IXL_AVE_LATENCY:
653 if (rx_bytes > 20) {
654 rx_latency = IXL_BULK_LATENCY;
655 rx_itr = IXL_ITR_8K;
656 } else if (rx_bytes <= 10) {
657 rx_latency = IXL_LOW_LATENCY;
658 rx_itr = IXL_ITR_100K;
659 }
660 break;
661 case IXL_BULK_LATENCY:
662 if (rx_bytes <= 20) {
663 rx_latency = IXL_AVE_LATENCY;
664 rx_itr = IXL_ITR_20K;
665 }
666 break;
667 }
668
669 rxr->latency = rx_latency;
670
671 if (rx_itr != rxr->itr) {
672 /* do an exponential smoothing */
673 rx_itr = (10 * rx_itr * rxr->itr) /
674 ((9 * rx_itr) + rxr->itr);
675 rxr->itr = min(rx_itr, IXL_MAX_ITR);
676 wr32(hw, I40E_PFINT_ITRN(IXL_RX_ITR,
677 rxr->me), rxr->itr);
678 }
679 } else { /* We may have have toggled to non-dynamic */
680 if (vsi->rx_itr_setting & IXL_ITR_DYNAMIC)
681 vsi->rx_itr_setting = pf->rx_itr;
682 /* Update the hardware if needed */
683 if (rxr->itr != vsi->rx_itr_setting) {
684 rxr->itr = vsi->rx_itr_setting;
685 wr32(hw, I40E_PFINT_ITRN(IXL_RX_ITR,
686 rxr->me), rxr->itr);
687 }
688 }
689 rxr->bytes = 0;
690 rxr->packets = 0;
691 }
692
693
694 /*
695 ** Provide a update to the queue TX
696 ** interrupt moderation value.
697 */
698 void
ixl_set_queue_tx_itr(struct ixl_tx_queue * que)699 ixl_set_queue_tx_itr(struct ixl_tx_queue *que)
700 {
701 struct ixl_vsi *vsi = que->vsi;
702 struct ixl_pf *pf = (struct ixl_pf *)vsi->back;
703 struct i40e_hw *hw = vsi->hw;
704 struct tx_ring *txr = &que->txr;
705 u16 tx_itr;
706 u16 tx_latency = 0;
707 int tx_bytes;
708
709
710 /* Idle, do nothing */
711 if (txr->bytes == 0)
712 return;
713
714 if (pf->dynamic_tx_itr) {
715 tx_bytes = txr->bytes/txr->itr;
716 tx_itr = txr->itr;
717
718 switch (txr->latency) {
719 case IXL_LOW_LATENCY:
720 if (tx_bytes > 10) {
721 tx_latency = IXL_AVE_LATENCY;
722 tx_itr = IXL_ITR_20K;
723 }
724 break;
725 case IXL_AVE_LATENCY:
726 if (tx_bytes > 20) {
727 tx_latency = IXL_BULK_LATENCY;
728 tx_itr = IXL_ITR_8K;
729 } else if (tx_bytes <= 10) {
730 tx_latency = IXL_LOW_LATENCY;
731 tx_itr = IXL_ITR_100K;
732 }
733 break;
734 case IXL_BULK_LATENCY:
735 if (tx_bytes <= 20) {
736 tx_latency = IXL_AVE_LATENCY;
737 tx_itr = IXL_ITR_20K;
738 }
739 break;
740 }
741
742 txr->latency = tx_latency;
743
744 if (tx_itr != txr->itr) {
745 /* do an exponential smoothing */
746 tx_itr = (10 * tx_itr * txr->itr) /
747 ((9 * tx_itr) + txr->itr);
748 txr->itr = min(tx_itr, IXL_MAX_ITR);
749 wr32(hw, I40E_PFINT_ITRN(IXL_TX_ITR,
750 txr->me), txr->itr);
751 }
752
753 } else { /* We may have have toggled to non-dynamic */
754 if (vsi->tx_itr_setting & IXL_ITR_DYNAMIC)
755 vsi->tx_itr_setting = pf->tx_itr;
756 /* Update the hardware if needed */
757 if (txr->itr != vsi->tx_itr_setting) {
758 txr->itr = vsi->tx_itr_setting;
759 wr32(hw, I40E_PFINT_ITRN(IXL_TX_ITR,
760 txr->me), txr->itr);
761 }
762 }
763 txr->bytes = 0;
764 txr->packets = 0;
765 return;
766 }
767
768 #ifdef IXL_DEBUG
769 /**
770 * ixl_sysctl_qtx_tail_handler
771 * Retrieves I40E_QTX_TAIL value from hardware
772 * for a sysctl.
773 */
774 int
ixl_sysctl_qtx_tail_handler(SYSCTL_HANDLER_ARGS)775 ixl_sysctl_qtx_tail_handler(SYSCTL_HANDLER_ARGS)
776 {
777 struct ixl_tx_queue *tx_que;
778 int error;
779 u32 val;
780
781 tx_que = ((struct ixl_tx_queue *)oidp->oid_arg1);
782 if (!tx_que) return 0;
783
784 val = rd32(tx_que->vsi->hw, tx_que->txr.tail);
785 error = sysctl_handle_int(oidp, &val, 0, req);
786 if (error || !req->newptr)
787 return error;
788 return (0);
789 }
790
791 /**
792 * ixl_sysctl_qrx_tail_handler
793 * Retrieves I40E_QRX_TAIL value from hardware
794 * for a sysctl.
795 */
796 int
ixl_sysctl_qrx_tail_handler(SYSCTL_HANDLER_ARGS)797 ixl_sysctl_qrx_tail_handler(SYSCTL_HANDLER_ARGS)
798 {
799 struct ixl_rx_queue *rx_que;
800 int error;
801 u32 val;
802
803 rx_que = ((struct ixl_rx_queue *)oidp->oid_arg1);
804 if (!rx_que) return 0;
805
806 val = rd32(rx_que->vsi->hw, rx_que->rxr.tail);
807 error = sysctl_handle_int(oidp, &val, 0, req);
808 if (error || !req->newptr)
809 return error;
810 return (0);
811 }
812 #endif
813
814 void
ixl_add_hw_stats(struct ixl_pf * pf)815 ixl_add_hw_stats(struct ixl_pf *pf)
816 {
817 struct ixl_vsi *vsi = &pf->vsi;
818 device_t dev = iflib_get_dev(vsi->ctx);
819 struct i40e_hw_port_stats *pf_stats = &pf->stats;
820
821 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
822 struct sysctl_oid *tree = device_get_sysctl_tree(dev);
823 struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
824
825 /* Driver statistics */
826 SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "admin_irq",
827 CTLFLAG_RD, &pf->admin_irq,
828 "Admin Queue IRQs received");
829
830 sysctl_ctx_init(&vsi->sysctl_ctx);
831 ixl_vsi_add_sysctls(vsi, "pf", true);
832
833 ixl_add_sysctls_mac_stats(ctx, child, pf_stats);
834 }
835
836 void
ixl_set_rss_hlut(struct ixl_pf * pf)837 ixl_set_rss_hlut(struct ixl_pf *pf)
838 {
839 struct i40e_hw *hw = &pf->hw;
840 struct ixl_vsi *vsi = &pf->vsi;
841 device_t dev = iflib_get_dev(vsi->ctx);
842 int i, que_id;
843 int lut_entry_width;
844 u32 lut = 0;
845 enum i40e_status_code status;
846
847 lut_entry_width = pf->hw.func_caps.rss_table_entry_width;
848
849 /* Populate the LUT with max no. of queues in round robin fashion */
850 u8 hlut_buf[512];
851 for (i = 0; i < pf->hw.func_caps.rss_table_size; i++) {
852 #ifdef RSS
853 /*
854 * Fetch the RSS bucket id for the given indirection entry.
855 * Cap it at the number of configured buckets (which is
856 * num_queues.)
857 */
858 que_id = rss_get_indirection_to_bucket(i);
859 que_id = que_id % vsi->num_rx_queues;
860 #else
861 que_id = i % vsi->num_rx_queues;
862 #endif
863 lut = (que_id & ((0x1 << lut_entry_width) - 1));
864 hlut_buf[i] = lut;
865 }
866
867 if (hw->mac.type == I40E_MAC_X722) {
868 status = i40e_aq_set_rss_lut(hw, vsi->vsi_num, TRUE, hlut_buf, sizeof(hlut_buf));
869 if (status)
870 device_printf(dev, "i40e_aq_set_rss_lut status %s, error %s\n",
871 i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
872 } else {
873 for (i = 0; i < pf->hw.func_caps.rss_table_size >> 2; i++)
874 wr32(hw, I40E_PFQF_HLUT(i), ((u32 *)hlut_buf)[i]);
875 ixl_flush(hw);
876 }
877 }
878
879 /* For PF VSI only */
880 int
ixl_enable_rings(struct ixl_vsi * vsi)881 ixl_enable_rings(struct ixl_vsi *vsi)
882 {
883 struct ixl_pf *pf = vsi->back;
884 int error;
885
886 for (int i = 0; i < vsi->num_tx_queues; i++) {
887 error = ixl_enable_tx_ring(pf, &pf->qtag, i);
888 if (error != 0)
889 return (error);
890 }
891
892 for (int i = 0; i < vsi->num_rx_queues; i++) {
893 error = ixl_enable_rx_ring(pf, &pf->qtag, i);
894 if (error != 0)
895 return (error);
896 }
897
898 return (0);
899 }
900
901 int
ixl_disable_rings(struct ixl_pf * pf,struct ixl_vsi * vsi,struct ixl_pf_qtag * qtag)902 ixl_disable_rings(struct ixl_pf *pf, struct ixl_vsi *vsi, struct ixl_pf_qtag *qtag)
903 {
904 int error, first_error;
905
906 first_error = 0;
907 for (int i = 0; i < vsi->num_tx_queues; i++) {
908 error = ixl_disable_tx_ring(pf, qtag, i);
909 if (error != 0 && first_error == 0)
910 first_error = error;
911 }
912
913 for (int i = 0; i < vsi->num_rx_queues; i++) {
914 error = ixl_disable_rx_ring(pf, qtag, i);
915 if (error != 0 && first_error == 0)
916 first_error = error;
917 }
918
919 return (first_error);
920 }
921
922 void
ixl_enable_intr(struct ixl_vsi * vsi)923 ixl_enable_intr(struct ixl_vsi *vsi)
924 {
925 struct i40e_hw *hw = vsi->hw;
926 struct ixl_rx_queue *que = vsi->rx_queues;
927
928 if (vsi->shared->isc_intr == IFLIB_INTR_MSIX) {
929 for (int i = 0; i < vsi->num_rx_queues; i++, que++)
930 ixl_enable_queue(hw, que->rxr.me);
931 } else
932 ixl_enable_intr0(hw);
933 }
934
935 void
ixl_disable_rings_intr(struct ixl_vsi * vsi)936 ixl_disable_rings_intr(struct ixl_vsi *vsi)
937 {
938 struct i40e_hw *hw = vsi->hw;
939 struct ixl_rx_queue *que = vsi->rx_queues;
940
941 for (int i = 0; i < vsi->num_rx_queues; i++, que++)
942 ixl_disable_queue(hw, que->rxr.me);
943 }
944
945 int
ixl_prepare_for_reset(struct ixl_pf * pf,bool is_up)946 ixl_prepare_for_reset(struct ixl_pf *pf, bool is_up)
947 {
948 struct i40e_hw *hw = &pf->hw;
949 device_t dev = pf->dev;
950 int error, first_error;
951
952 first_error = 0;
953 /* Restore identification before the reset tears down AdminQ access. */
954 ixl_led_restore(pf);
955 #ifdef PCI_IOV
956 ixl_notify_vfs_reset(pf);
957 error = ixl_quiesce_vfs_for_reset(pf);
958 if (error != 0) {
959 device_printf(dev, "Failed to quiesce one or more VFs: %d\n",
960 error);
961 first_error = error;
962 }
963 #endif
964 if (is_up)
965 ixl_if_stop(pf->vsi.ctx);
966
967 ixl_shutdown_hmc(pf);
968
969 ixl_disable_intr0(hw);
970
971 error = i40e_shutdown_adminq(hw);
972 if (error) {
973 device_printf(dev,
974 "Shutdown Admin queue failed with code %d\n", error);
975 if (first_error == 0)
976 first_error = error;
977 }
978
979 ixl_pf_qmgr_release(&pf->qmgr, &pf->qtag);
980 return (first_error);
981 }
982
983 int
ixl_rebuild_hw_structs_after_reset(struct ixl_pf * pf,bool is_up)984 ixl_rebuild_hw_structs_after_reset(struct ixl_pf *pf, bool is_up)
985 {
986 struct i40e_hw *hw = &pf->hw;
987 struct ixl_vsi *vsi = &pf->vsi;
988 device_t dev = pf->dev;
989 enum i40e_get_fw_lldp_status_resp lldp_status;
990 int error = 0;
991
992 device_printf(dev, "Rebuilding driver state...\n");
993
994 /* Setup */
995 error = i40e_init_adminq(hw);
996 if (error != 0 && error != I40E_ERR_FIRMWARE_API_VERSION) {
997 device_printf(dev, "Unable to initialize Admin Queue, error %d\n",
998 error);
999 goto ixl_rebuild_hw_structs_after_reset_err;
1000 }
1001
1002 if (IXL_PF_IN_RECOVERY_MODE(pf)) {
1003 /* Keep admin queue interrupts active while driver is loaded */
1004 if (vsi->shared->isc_intr == IFLIB_INTR_MSIX) {
1005 ixl_configure_intr0_msix(pf);
1006 ixl_enable_intr0(hw);
1007 }
1008
1009 return (0);
1010 }
1011
1012 i40e_clear_pxe_mode(hw);
1013
1014 error = ixl_get_hw_capabilities(pf);
1015 if (error) {
1016 device_printf(dev, "ixl_get_hw_capabilities failed: %d\n", error);
1017 goto ixl_rebuild_hw_structs_after_reset_err;
1018 }
1019
1020 error = ixl_setup_hmc(pf);
1021 if (error)
1022 goto ixl_rebuild_hw_structs_after_reset_err;
1023
1024 /* reserve a contiguous allocation for the PF's VSI */
1025 error = ixl_pf_qmgr_alloc_contiguous(&pf->qmgr, vsi->num_tx_queues, &pf->qtag);
1026 if (error) {
1027 device_printf(dev, "Failed to reserve queues for PF LAN VSI, error %d\n",
1028 error);
1029 goto ixl_rebuild_hw_structs_after_reset_err;
1030 }
1031
1032 error = ixl_switch_config(pf);
1033 if (error) {
1034 device_printf(dev, "ixl_rebuild_hw_structs_after_reset: ixl_switch_config() failed: %d\n",
1035 error);
1036 error = EIO;
1037 goto ixl_rebuild_hw_structs_after_reset_err;
1038 }
1039 /* Firmware has rebuilt the port and VSI counter resources. */
1040 ixl_pf_reset_stats(pf);
1041 ixl_vsi_reset_stats(vsi);
1042
1043 error = i40e_aq_set_phy_int_mask(hw, IXL_DEFAULT_PHY_INT_MASK,
1044 NULL);
1045 if (error) {
1046 device_printf(dev, "init: i40e_aq_set_phy_mask() failed: err %d,"
1047 " aq_err %d\n", error, hw->aq.asq_last_status);
1048 error = EIO;
1049 goto ixl_rebuild_hw_structs_after_reset_err;
1050 }
1051
1052 u8 set_fc_err_mask;
1053 error = i40e_set_fc(hw, &set_fc_err_mask, true);
1054 if (error) {
1055 device_printf(dev, "init: setting link flow control failed; retcode %d,"
1056 " fc_err_mask 0x%02x\n", error, set_fc_err_mask);
1057 error = EIO;
1058 goto ixl_rebuild_hw_structs_after_reset_err;
1059 }
1060
1061 /* Remove default filters reinstalled by FW on reset */
1062 ixl_del_default_hw_filters(vsi);
1063
1064 /* Receive broadcast Ethernet frames */
1065 i40e_aq_set_vsi_broadcast(&pf->hw, vsi->seid, TRUE, NULL);
1066
1067 #ifdef PCI_IOV
1068 if (pf->num_vfs != 0) {
1069 error = ixl_rebuild_vfs_after_reset(pf);
1070 if (error != 0)
1071 device_printf(dev,
1072 "Failed to rebuild one or more VFs: %d\n", error);
1073 }
1074 #endif
1075
1076 /* Determine link state */
1077 ixl_attach_get_link_status(pf);
1078
1079 i40e_aq_set_dcb_parameters(hw, TRUE, NULL);
1080
1081 /* Query device FW LLDP status */
1082 if (i40e_get_fw_lldp_status(hw, &lldp_status) == I40E_SUCCESS) {
1083 if (lldp_status == I40E_GET_FW_LLDP_STATUS_DISABLED) {
1084 ixl_set_state(&pf->state,
1085 IXL_STATE_FW_LLDP_DISABLED);
1086 } else {
1087 ixl_clear_state(&pf->state,
1088 IXL_STATE_FW_LLDP_DISABLED);
1089 }
1090 }
1091
1092 /* Keep admin queue interrupts active while driver is loaded */
1093 if (vsi->shared->isc_intr == IFLIB_INTR_MSIX) {
1094 ixl_configure_intr0_msix(pf);
1095 ixl_enable_intr0(hw);
1096 }
1097
1098 if (is_up) {
1099 iflib_request_reset(vsi->ctx);
1100 iflib_admin_intr_deferred(vsi->ctx);
1101 }
1102
1103 device_printf(dev, "Rebuilding driver state done.\n");
1104 return (0);
1105
1106 ixl_rebuild_hw_structs_after_reset_err:
1107 device_printf(dev, "Reload the driver to recover\n");
1108 return (error);
1109 }
1110
1111 /*
1112 ** Set flow control using sysctl:
1113 ** 0 - off
1114 ** 1 - rx pause
1115 ** 2 - tx pause
1116 ** 3 - full
1117 */
1118 int
ixl_sysctl_set_flowcntl(SYSCTL_HANDLER_ARGS)1119 ixl_sysctl_set_flowcntl(SYSCTL_HANDLER_ARGS)
1120 {
1121 struct ixl_pf *pf = (struct ixl_pf *)arg1;
1122 struct i40e_hw *hw = &pf->hw;
1123 device_t dev = pf->dev;
1124 int requested_fc, error = 0;
1125 enum i40e_status_code aq_error = 0;
1126 u8 fc_aq_err = 0;
1127
1128 /* Get request */
1129 requested_fc = pf->fc;
1130 error = sysctl_handle_int(oidp, &requested_fc, 0, req);
1131 if ((error) || (req->newptr == NULL))
1132 return (error);
1133 if (requested_fc < 0 || requested_fc > 3) {
1134 device_printf(dev,
1135 "Invalid fc mode; valid modes are 0 through 3\n");
1136 return (EINVAL);
1137 }
1138
1139 /* Set fc ability for port */
1140 hw->fc.requested_mode = requested_fc;
1141 aq_error = i40e_set_fc(hw, &fc_aq_err, TRUE);
1142 if (aq_error) {
1143 device_printf(dev,
1144 "%s: Error setting Flow Control mode %d; fc_err %#x\n",
1145 __func__, aq_error, fc_aq_err);
1146 return (EIO);
1147 }
1148 pf->fc = requested_fc;
1149
1150 return (0);
1151 }
1152