xref: /freebsd/sys/dev/ixl/ixl_pf_iflib.c (revision 444168adbe5217ea9b73773e42c60bf75fb7a6fd)
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