xref: /freebsd/sys/dev/ice/ice_iov.c (revision 046472590365c3bf1e076efa49471d52a033da35)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*  Copyright (c) 2025, Intel Corporation
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  *
11  *   2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *
15  *   3. Neither the name of the Intel Corporation nor the names of its
16  *      contributors may be used to endorse or promote products derived from
17  *      this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *  POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @file ice_iov.c
34  * @brief Virtualization support functions
35  *
36  * Contains functions for enabling and managing PCIe virtual function devices,
37  * including enabling new VFs, and managing VFs over the virtchnl interface.
38  */
39 
40 #include "ice_iov.h"
41 
42 static struct ice_vf *ice_iov_get_vf(struct ice_softc *sc, int vf_num);
43 static void ice_iov_ready_vf(struct ice_softc *sc, struct ice_vf *vf);
44 static void ice_reset_vf(struct ice_softc *sc, struct ice_vf *vf,
45 			 bool trigger_vflr);
46 static void ice_iov_setup_intr_mapping(struct ice_softc *sc, struct ice_vf *vf);
47 
48 static void ice_vc_version_msg(struct ice_softc *sc, struct ice_vf *vf,
49 			       u8 *msg_buf);
50 static void ice_vc_get_vf_res_msg(struct ice_softc *sc, struct ice_vf *vf,
51 				  u8 *msg_buf);
52 static void ice_vc_add_eth_addr_msg(struct ice_softc *sc, struct ice_vf *vf,
53 				    u8 *msg_buf);
54 static void ice_vc_del_eth_addr_msg(struct ice_softc *sc, struct ice_vf *vf,
55 				    u8 *msg_buf);
56 static bool ice_vc_isvalid_ring_len(u16 ring_len);
57 static void ice_vc_cfg_vsi_qs_msg(struct ice_softc *sc, struct ice_vf *vf,
58 				  u8 *msg_buf);
59 static void ice_vc_cfg_rss_key_msg(struct ice_softc *sc, struct ice_vf *vf,
60 				   u8 *msg_buf);
61 static void ice_vc_set_rss_hena_msg(struct ice_softc *sc, struct ice_vf *vf,
62 				    u8 *msg_buf);
63 static void ice_vc_enable_queues_msg(struct ice_softc *sc, struct ice_vf *vf,
64 				     u8 *msg_buf);
65 static void ice_vc_notify_vf_link_state(struct ice_softc *sc, struct ice_vf *vf);
66 static void ice_vc_disable_queues_msg(struct ice_softc *sc, struct ice_vf *vf,
67 				      u8 *msg_buf);
68 static void ice_vc_cfg_irq_map_msg(struct ice_softc *sc, struct ice_vf *vf,
69 				   u8 *msg_buf);
70 static void ice_vc_get_stats_msg(struct ice_softc *sc, struct ice_vf *vf,
71 				 u8 *msg_buf);
72 static void ice_eth_stats_to_virtchnl_eth_stats(struct ice_eth_stats *istats,
73      struct virtchnl_eth_stats *vstats);
74 static void ice_vc_cfg_rss_lut_msg(struct ice_softc *sc, struct ice_vf *vf,
75 				   u8 *msg_buf);
76 static void ice_vc_cfg_promisc_mode_msg(struct ice_softc *sc, struct ice_vf *vf,
77 				        u8 *msg_buf);
78 static void ice_vc_add_vlan_msg(struct ice_softc *sc, struct ice_vf *vf,
79 				u8 *msg_buf);
80 static void ice_vc_del_vlan_msg(struct ice_softc *sc, struct ice_vf *vf,
81 				u8 *msg_buf);
82 static enum virtchnl_status_code ice_iov_err_to_virt_err(int ice_err);
83 static int ice_vf_validate_mac(struct ice_vf *vf, const uint8_t *addr);
84 
85 /**
86  * ice_iov_attach - Initialize SR-IOV PF host support
87  * @sc: device softc structure
88  *
89  * Initialize SR-IOV PF host support at the end of the driver attach process.
90  *
91  * @pre Must be called from sleepable context (calls malloc() w/ M_WAITOK)
92  *
93  * @returns 0 if successful, or
94  * - ENOMEM if there is no memory for the PF/VF schemas or iov device
95  * - ENXIO if the device isn't PCI-E or doesn't support the same SR-IOV
96  *   version as the kernel
97  * - ENOENT if the device doesn't have the SR-IOV capability
98  */
99 int
ice_iov_attach(struct ice_softc * sc)100 ice_iov_attach(struct ice_softc *sc)
101 {
102 	device_t dev = sc->dev;
103 	nvlist_t *pf_schema, *vf_schema;
104 	int error;
105 
106 	pf_schema = pci_iov_schema_alloc_node();
107 	vf_schema = pci_iov_schema_alloc_node();
108 
109 	pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
110 	pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof",
111 	    IOV_SCHEMA_HASDEFAULT, TRUE);
112 	pci_iov_schema_add_bool(vf_schema, "allow-set-mac",
113 	    IOV_SCHEMA_HASDEFAULT, FALSE);
114 	pci_iov_schema_add_bool(vf_schema, "allow-promisc",
115 	    IOV_SCHEMA_HASDEFAULT, FALSE);
116 	pci_iov_schema_add_uint16(vf_schema, "num-queues",
117 	    IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_QUEUES);
118 	pci_iov_schema_add_uint16(vf_schema, "mirror-src-vsi",
119 	    IOV_SCHEMA_HASDEFAULT, ICE_INVALID_MIRROR_VSI);
120 	pci_iov_schema_add_uint16(vf_schema, "max-vlan-allowed",
121 	    IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_VLAN_LIMIT);
122 	pci_iov_schema_add_uint16(vf_schema, "max-mac-filters",
123 	    IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_FILTER_LIMIT);
124 
125 	error = pci_iov_attach(dev, pf_schema, vf_schema);
126 	if (error != 0) {
127 		device_printf(dev,
128 		    "pci_iov_attach failed (error=%s)\n",
129 		    ice_err_str(error));
130 		ice_clear_bit(ICE_FEATURE_SRIOV, sc->feat_en);
131 	} else
132 		ice_set_bit(ICE_FEATURE_SRIOV, sc->feat_en);
133 
134 	return (error);
135 }
136 
137 /**
138  * ice_iov_detach - Teardown SR-IOV PF host support
139  * @sc: device softc structure
140  *
141  * Teardown SR-IOV PF host support at the start of the driver detach process.
142  *
143  * @returns 0 if successful or IOV support hasn't been setup, or
144  * - EBUSY if VFs still exist
145  */
146 int
ice_iov_detach(struct ice_softc * sc)147 ice_iov_detach(struct ice_softc *sc)
148 {
149 	device_t dev = sc->dev;
150 	int error;
151 
152 	error = pci_iov_detach(dev);
153 	if (error != 0) {
154 		device_printf(dev,
155 		    "pci_iov_detach failed (error=%s)\n",
156 		    ice_err_str(error));
157 	}
158 
159 	return (error);
160 }
161 
162 /**
163  * ice_iov_init - Called by the OS before the first VF is created.
164  * @sc: device softc structure
165  * @num_vfs: number of VFs to setup resources for
166  * @params: configuration parameters for the PF
167  *
168  * @returns 0 if successful or an error code on failure
169  */
170 int
ice_iov_init(struct ice_softc * sc,uint16_t num_vfs,const nvlist_t * params __unused)171 ice_iov_init(struct ice_softc *sc, uint16_t num_vfs, const nvlist_t *params __unused)
172 {
173 	/* Allocate array of VFs, for tracking */
174 	sc->vfs = (struct ice_vf *)malloc(sizeof(struct ice_vf) * num_vfs, M_ICE, M_NOWAIT |
175 	    M_ZERO);
176 	if (sc->vfs == NULL)
177 		return (ENOMEM);
178 
179 	/* Initialize each VF with basic information */
180 	for (int i = 0; i < num_vfs; i++)
181 		sc->vfs[i].vf_num = i;
182 
183 	/* Save off number of configured VFs */
184 	sc->num_vfs = num_vfs;
185 
186 	return (0);
187 }
188 
189 /**
190  * ice_iov_get_vf - Get pointer to VF at given index
191  * @sc: device softc structure
192  * @vf_num: Index of VF to retrieve
193  *
194  * @remark will throw an assertion if vf_num is not in the
195  * range of allocated VFs
196  *
197  * @returns a pointer to the VF structure at the given index
198  */
199 static struct ice_vf *
ice_iov_get_vf(struct ice_softc * sc,int vf_num)200 ice_iov_get_vf(struct ice_softc *sc, int vf_num)
201 {
202 	MPASS(vf_num < sc->num_vfs);
203 
204 	return &sc->vfs[vf_num];
205 }
206 
207 /**
208  * ice_iov_add_vf - Called by the OS for each VF to create
209  * @sc: device softc structure
210  * @vfnum: index of VF to configure
211  * @params: configuration parameters for the VF
212  *
213  * @returns 0 if successful or an error code on failure
214  */
215 int
ice_iov_add_vf(struct ice_softc * sc,uint16_t vfnum,const nvlist_t * params)216 ice_iov_add_vf(struct ice_softc *sc, uint16_t vfnum, const nvlist_t *params)
217 {
218 	struct ice_tx_queue *txq;
219 	struct ice_rx_queue *rxq;
220 	device_t dev = sc->dev;
221 	struct ice_vsi *vsi;
222 	struct ice_vf *vf;
223 	int vf_num_queues;
224 	const void *mac;
225 	size_t size;
226 	int error;
227 	int i;
228 
229 	vf = ice_iov_get_vf(sc, vfnum);
230 	vf->vf_flags = VF_FLAG_ENABLED;
231 
232 	/* This VF needs at least one VSI */
233 	vsi = ice_alloc_vsi(sc, ICE_VSI_VF);
234 	if (vsi == NULL)
235 		return (ENOMEM);
236 	vf->vsi = vsi;
237 	vsi->vf_num = vfnum;
238 
239 	vf_num_queues = nvlist_get_number(params, "num-queues");
240 	/* Validate and clamp value if invalid */
241 	if (vf_num_queues < 1 || vf_num_queues > ICE_MAX_SCATTERED_QUEUES)
242 		device_printf(dev, "Invalid num-queues (%d) for VF %d\n",
243 		    vf_num_queues, vf->vf_num);
244 	if (vf_num_queues < 1) {
245 		device_printf(dev, "Setting VF %d num-queues to 1\n", vf->vf_num);
246 		vf_num_queues = 1;
247 	} else if (vf_num_queues > ICE_MAX_SCATTERED_QUEUES) {
248 		device_printf(dev, "Setting VF %d num-queues to %d\n",
249 		    vf->vf_num, ICE_MAX_SCATTERED_QUEUES);
250 		vf_num_queues = ICE_MAX_SCATTERED_QUEUES;
251 	}
252 	vsi->qmap_type = ICE_RESMGR_ALLOC_SCATTERED;
253 
254 	/* Reserve VF queue allocation from PF queues */
255 	ice_alloc_vsi_qmap(vsi, vf_num_queues, vf_num_queues);
256 	vsi->num_tx_queues = vsi->num_rx_queues = vf_num_queues;
257 
258 	/* Assign Tx queues from PF space */
259 	error = ice_resmgr_assign_scattered(&sc->tx_qmgr, vsi->tx_qmap,
260 					     vsi->num_tx_queues);
261 	if (error) {
262 		device_printf(sc->dev, "Unable to assign VF Tx queues: %s\n",
263 			      ice_err_str(error));
264 		goto release_vsi;
265 	}
266 
267 	/* Assign Rx queues from PF space */
268 	error = ice_resmgr_assign_scattered(&sc->rx_qmgr, vsi->rx_qmap,
269 					     vsi->num_rx_queues);
270 	if (error) {
271 		device_printf(sc->dev, "Unable to assign VF Rx queues: %s\n",
272 			      ice_err_str(error));
273 		goto release_vsi;
274 	}
275 
276 	vsi->max_frame_size = ICE_MAX_FRAME_SIZE;
277 
278 	/* Allocate queue structure memory */
279 	vsi->tx_queues = (struct ice_tx_queue *)
280 	    malloc(sizeof(struct ice_tx_queue) * vsi->num_tx_queues, M_ICE,
281 		   M_NOWAIT | M_ZERO);
282 	if (!vsi->tx_queues) {
283 		device_printf(sc->dev, "VF-%d: Unable to allocate Tx queue memory\n",
284 			      vfnum);
285 		error = ENOMEM;
286 		goto release_vsi;
287 	}
288 	for (i = 0, txq = vsi->tx_queues; i < vsi->num_tx_queues; i++, txq++) {
289 		txq->me = i;
290 		txq->vsi = vsi;
291 	}
292 
293 	/* Allocate queue structure memory */
294 	vsi->rx_queues = (struct ice_rx_queue *)
295 	    malloc(sizeof(struct ice_rx_queue) * vsi->num_rx_queues, M_ICE,
296 		   M_NOWAIT | M_ZERO);
297 	if (!vsi->rx_queues) {
298 		device_printf(sc->dev, "VF-%d: Unable to allocate Rx queue memory\n",
299 			      vfnum);
300 		error = ENOMEM;
301 		goto free_txqs;
302 	}
303 	for (i = 0, rxq = vsi->rx_queues; i < vsi->num_rx_queues; i++, rxq++) {
304 		rxq->me = i;
305 		rxq->vsi = vsi;
306 	}
307 
308 	/* Allocate space to store the IRQ vector data */
309 	vf->num_irq_vectors = vf_num_queues + 1;
310 	vf->tx_irqvs = (struct ice_irq_vector *)
311 	    malloc(sizeof(struct ice_irq_vector) * (vf->num_irq_vectors),
312 		   M_ICE, M_NOWAIT);
313 	if (!vf->tx_irqvs) {
314 		device_printf(sc->dev,
315 			      "Unable to allocate TX irqv memory for VF-%d's %d vectors\n",
316 			      vfnum, vf->num_irq_vectors);
317 		error = ENOMEM;
318 		goto free_rxqs;
319 	}
320 	vf->rx_irqvs = (struct ice_irq_vector *)
321 	    malloc(sizeof(struct ice_irq_vector) * (vf->num_irq_vectors),
322 		   M_ICE, M_NOWAIT);
323 	if (!vf->rx_irqvs) {
324 		device_printf(sc->dev,
325 			      "Unable to allocate RX irqv memory for VF-%d's %d vectors\n",
326 			      vfnum, vf->num_irq_vectors);
327 		error = ENOMEM;
328 		goto free_txirqvs;
329 	}
330 
331 	/* Assign VF interrupts from PF space */
332 	if (!(vf->vf_imap =
333 	      (u16 *)malloc(sizeof(u16) * vf->num_irq_vectors,
334 	      M_ICE, M_NOWAIT))) {
335 		device_printf(dev, "Unable to allocate VF-%d imap memory\n", vfnum);
336 		error = ENOMEM;
337 		goto free_rxirqvs;
338 	}
339 	error = ice_resmgr_assign_contiguous(&sc->dev_imgr, vf->vf_imap, vf->num_irq_vectors);
340 	if (error) {
341 		device_printf(dev, "Unable to assign VF-%d interrupt mapping: %s\n",
342 			      vfnum, ice_err_str(error));
343 		goto free_imap;
344 	}
345 
346 	if (nvlist_exists_binary(params, "mac-addr")) {
347 		mac = nvlist_get_binary(params, "mac-addr", &size);
348 		memcpy(vf->mac, mac, ETHER_ADDR_LEN);
349 
350 		if (nvlist_get_bool(params, "allow-set-mac"))
351 			vf->vf_flags |= VF_FLAG_SET_MAC_CAP;
352 	} else
353 		/*
354 		 * If the administrator has not specified a MAC address then
355 		 * we must allow the VF to choose one.
356 		 */
357 		vf->vf_flags |= VF_FLAG_SET_MAC_CAP;
358 
359 	if (nvlist_get_bool(params, "mac-anti-spoof"))
360 		vf->vf_flags |= VF_FLAG_MAC_ANTI_SPOOF;
361 
362 	if (nvlist_get_bool(params, "allow-promisc"))
363 		vf->vf_flags |= VF_FLAG_PROMISC_CAP;
364 
365 	vsi->mirror_src_vsi = nvlist_get_number(params, "mirror-src-vsi");
366 
367 	vf->vlan_limit = nvlist_get_number(params, "max-vlan-allowed");
368 	vf->mac_filter_limit = nvlist_get_number(params, "max-mac-filters");
369 
370 	vf->vf_flags |= VF_FLAG_VLAN_CAP;
371 
372 	/* Create and setup VSI in HW */
373 	error = ice_initialize_vsi(vsi);
374 	if (error) {
375 		device_printf(sc->dev, "Unable to initialize VF %d VSI: %s\n",
376 			      vfnum, ice_err_str(error));
377 		goto release_imap;
378 	}
379 
380 	/* Add the broadcast address */
381 	error = ice_add_vsi_mac_filter(vsi, broadcastaddr);
382 	if (error) {
383 		device_printf(sc->dev, "Unable to add broadcast filter VF %d VSI: %s\n",
384 			      vfnum, ice_err_str(error));
385 		goto release_imap;
386 	}
387 
388 	ice_iov_ready_vf(sc, vf);
389 
390 	return (0);
391 
392 release_imap:
393 	ice_resmgr_release_map(&sc->dev_imgr, vf->vf_imap,
394 			       vf->num_irq_vectors);
395 free_imap:
396 	free(vf->vf_imap, M_ICE);
397 	vf->vf_imap = NULL;
398 free_rxirqvs:
399 	free(vf->rx_irqvs, M_ICE);
400 	vf->rx_irqvs = NULL;
401 free_txirqvs:
402 	free(vf->tx_irqvs, M_ICE);
403 	vf->tx_irqvs = NULL;
404 free_rxqs:
405 	free(vsi->rx_queues, M_ICE);
406 	vsi->rx_queues = NULL;
407 free_txqs:
408 	free(vsi->tx_queues, M_ICE);
409 	vsi->tx_queues = NULL;
410 release_vsi:
411 	ice_release_vsi(vsi);
412 	vf->vsi = NULL;
413 	return (error);
414 }
415 
416 /**
417  * ice_iov_uninit - Called by the OS when VFs are destroyed
418  * @sc: device softc structure
419  */
420 void
ice_iov_uninit(struct ice_softc * sc)421 ice_iov_uninit(struct ice_softc *sc)
422 {
423 	struct ice_vf *vf;
424 	struct ice_vsi *vsi;
425 
426 	/* Release per-VF resources */
427 	for (int i = 0; i < sc->num_vfs; i++) {
428 		vf = &sc->vfs[i];
429 		vsi = vf->vsi;
430 
431 		/* Free VF interrupt reservation */
432 		if (vf->vf_imap) {
433 			free(vf->vf_imap, M_ICE);
434 			vf->vf_imap = NULL;
435 		}
436 
437 		/* Free queue interrupt mapping trackers */
438 		if (vf->tx_irqvs) {
439 			free(vf->tx_irqvs, M_ICE);
440 			vf->tx_irqvs = NULL;
441 		}
442 		if (vf->rx_irqvs) {
443 			free(vf->rx_irqvs, M_ICE);
444 			vf->rx_irqvs = NULL;
445 		}
446 
447 		if (!vsi)
448 			continue;
449 
450 		/* Free VSI queues */
451 		if (vsi->tx_queues) {
452 			free(vsi->tx_queues, M_ICE);
453 			vsi->tx_queues = NULL;
454 		}
455 		if (vsi->rx_queues) {
456 			free(vsi->rx_queues, M_ICE);
457 			vsi->rx_queues = NULL;
458 		}
459 
460 		ice_release_vsi(vsi);
461 		vf->vsi = NULL;
462 	}
463 
464 	/* Release memory used for VF tracking */
465 	if (sc->vfs) {
466 		free(sc->vfs, M_ICE);
467 		sc->vfs = NULL;
468 	}
469 	sc->num_vfs = 0;
470 }
471 
472 /**
473  * ice_iov_handle_vflr - Process VFLR event
474  * @sc: device softc structure
475  *
476  * Identifys which VFs have been reset and re-configure
477  * them.
478  */
479 void
ice_iov_handle_vflr(struct ice_softc * sc)480 ice_iov_handle_vflr(struct ice_softc *sc)
481 {
482 	struct ice_hw *hw = &sc->hw;
483 	struct ice_vf *vf;
484 	u32 reg, reg_idx, bit_idx;
485 
486 	for (int i = 0; i < sc->num_vfs; i++) {
487 		vf = &sc->vfs[i];
488 
489 		reg_idx = (hw->func_caps.vf_base_id + vf->vf_num) / 32;
490 		bit_idx = (hw->func_caps.vf_base_id + vf->vf_num) % 32;
491 		reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx));
492 		if (reg & BIT(bit_idx))
493 			ice_reset_vf(sc, vf, false);
494 	}
495 }
496 
497 /**
498  * ice_iov_ready_vf - Setup VF interrupts and mark it as ready
499  * @sc: device softc structure
500  * @vf: driver's VF structure for the VF to update
501  *
502  * Clears VF reset triggering bit, sets up the PF<->VF interrupt
503  * mapping and marks the VF as active in the HW so that the VF
504  * driver can use it.
505  */
506 static void
ice_iov_ready_vf(struct ice_softc * sc,struct ice_vf * vf)507 ice_iov_ready_vf(struct ice_softc *sc, struct ice_vf *vf)
508 {
509 	struct ice_hw *hw = &sc->hw;
510 	u32 reg;
511 
512 	/* Clear the triggering bit */
513 	reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_num));
514 	reg &= ~VPGEN_VFRTRIG_VFSWR_M;
515 	wr32(hw, VPGEN_VFRTRIG(vf->vf_num), reg);
516 
517 	/* Setup VF interrupt allocation and mapping */
518 	ice_iov_setup_intr_mapping(sc, vf);
519 
520 	/* Indicate to the VF that reset is done */
521 	wr32(hw, VFGEN_RSTAT(vf->vf_num), VIRTCHNL_VFR_VFACTIVE);
522 
523 	ice_flush(hw);
524 }
525 
526 /**
527  * ice_reset_vf - Perform a hardware reset (VFR) on a VF
528  * @sc: device softc structure
529  * @vf: driver's VF structure for VF to be reset
530  * @trigger_vflr: trigger a reset or only handle already executed reset
531  *
532  * Performs a VFR for the given VF. This function busy waits until the
533  * reset completes in the HW, notifies the VF that the reset is done
534  * by setting a bit in a HW register, then returns.
535  *
536  * @remark This also sets up the PF<->VF interrupt mapping and allocations in
537  * the hardware after the hardware reset is finished, via
538  * ice_iov_setup_intr_mapping()
539  */
540 static void
ice_reset_vf(struct ice_softc * sc,struct ice_vf * vf,bool trigger_vflr)541 ice_reset_vf(struct ice_softc *sc, struct ice_vf *vf, bool trigger_vflr)
542 {
543 	u16 global_vf_num, reg_idx, bit_idx;
544 	struct ice_hw *hw = &sc->hw;
545 	int status;
546 	u32 reg;
547 	int i;
548 
549 	global_vf_num = vf->vf_num + hw->func_caps.vf_base_id;
550 
551 	if (trigger_vflr) {
552 		reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_num));
553 		reg |= VPGEN_VFRTRIG_VFSWR_M;
554 		wr32(hw, VPGEN_VFRTRIG(vf->vf_num), reg);
555 	}
556 
557 	/* clear the VFLR bit for the VF in a GLGEN_VFLRSTAT register */
558 	reg_idx = (global_vf_num) / 32;
559 	bit_idx = (global_vf_num) % 32;
560 	wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
561 	ice_flush(hw);
562 
563 	/* Wait until there are no pending PCI transactions */
564 	wr32(hw, PF_PCI_CIAA,
565 	     ICE_PCIE_DEV_STATUS | (global_vf_num << PF_PCI_CIAA_VF_NUM_S));
566 
567 	for (i = 0; i < ICE_PCI_CIAD_WAIT_COUNT; i++) {
568 		reg = rd32(hw, PF_PCI_CIAD);
569 		if (!(reg & PCIEM_STA_TRANSACTION_PND))
570 			break;
571 
572 		DELAY(ICE_PCI_CIAD_WAIT_DELAY_US);
573 	}
574 	if (i == ICE_PCI_CIAD_WAIT_COUNT)
575 		device_printf(sc->dev,
576 			"VF-%d PCI transactions stuck\n", vf->vf_num);
577 
578 	/* Disable TX queues, which is required during VF reset */
579 	status = ice_dis_vsi_txq(hw->port_info, vf->vsi->idx, 0, 0, NULL, NULL,
580 			NULL, ICE_VF_RESET, vf->vf_num, NULL);
581 	if (status)
582 		device_printf(sc->dev,
583 			      "%s: Failed to disable LAN Tx queues: err %s aq_err %s\n",
584 			      __func__, ice_status_str(status),
585 			      ice_aq_str(hw->adminq.sq_last_status));
586 
587 	/* Then check for the VF reset to finish in HW */
588 	for (i = 0; i < ICE_VPGEN_VFRSTAT_WAIT_COUNT; i++) {
589 		reg = rd32(hw, VPGEN_VFRSTAT(vf->vf_num));
590 		if ((reg & VPGEN_VFRSTAT_VFRD_M))
591 			break;
592 
593 		DELAY(ICE_VPGEN_VFRSTAT_WAIT_DELAY_US);
594 	}
595 	if (i == ICE_VPGEN_VFRSTAT_WAIT_COUNT)
596 		device_printf(sc->dev,
597 			"VF-%d Reset is stuck\n", vf->vf_num);
598 
599 	ice_iov_ready_vf(sc, vf);
600 }
601 
602 /**
603  * ice_vc_get_vf_res_msg - Handle VIRTCHNL_OP_GET_VF_RESOURCES msg from VF
604  * @sc: device private structure
605  * @vf: VF tracking structure
606  * @msg_buf: raw message buffer from the VF
607  *
608  * Receives a message from the VF listing its supported capabilities, and
609  * replies to the VF with information about what resources the PF has
610  * allocated for the VF.
611  *
612  * @remark This always replies to the VF with a success status; it does not
613  * fail. It's up to the VF driver to reject or complain about the PF's response.
614  */
615 static void
ice_vc_get_vf_res_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)616 ice_vc_get_vf_res_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
617 {
618 	struct ice_hw *hw = &sc->hw;
619 	struct virtchnl_vf_resource *vf_res;
620 	struct virtchnl_vsi_resource *vsi_res;
621 	u16 vf_res_len;
622 	u32 vf_caps;
623 
624 	/* XXX: Only support one VSI per VF, so this size doesn't need adjusting */
625 	vf_res_len = sizeof(struct virtchnl_vf_resource);
626 	vf_res = (struct virtchnl_vf_resource *)malloc(vf_res_len, M_ICE,
627 	    M_WAITOK | M_ZERO);
628 
629 	vf_res->num_vsis = 1;
630 	vf_res->num_queue_pairs = vf->vsi->num_tx_queues;
631 	vf_res->max_vectors = vf_res->num_queue_pairs + 1;
632 
633 	vf_res->rss_key_size = ICE_GET_SET_RSS_KEY_EXTEND_KEY_SIZE;
634 	vf_res->rss_lut_size = ICE_VSIQF_HLUT_ARRAY_SIZE;
635 	vf_res->max_mtu = 0;
636 
637 	vf_res->vf_cap_flags = VF_BASE_MODE_OFFLOADS;
638 	if (msg_buf != NULL) {
639 		vf_caps = *((u32 *)(msg_buf));
640 
641 		if (vf_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
642 			vf_res->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
643 
644 		if (vf_caps & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
645                         vf_res->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_WB_ON_ITR;
646 	}
647 
648 	vsi_res = &vf_res->vsi_res[0];
649 	vsi_res->vsi_id = vf->vsi->idx;
650 	vsi_res->num_queue_pairs = vf->vsi->num_tx_queues;
651 	vsi_res->vsi_type = VIRTCHNL_VSI_SRIOV;
652 	vsi_res->qset_handle = 0;
653 	if (!ETHER_IS_ZERO(vf->mac))
654 		memcpy(vsi_res->default_mac_addr, vf->mac, ETHER_ADDR_LEN);
655 
656 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_GET_VF_RESOURCES,
657 	    VIRTCHNL_STATUS_SUCCESS, (u8 *)vf_res, vf_res_len, NULL);
658 
659 	free(vf_res, M_ICE);
660 }
661 
662 /**
663  * ice_vc_version_msg - Handle VIRTCHNL_OP_VERSION msg from VF
664  * @sc: device private structure
665  * @vf: VF tracking structure
666  * @msg_buf: raw message buffer from the VF
667  *
668  * Receives a version message from the VF, and responds to the VF with
669  * the version number that the PF will use.
670  *
671  * @remark This always replies to the VF with a success status; it does not
672  * fail.
673  */
674 static void
ice_vc_version_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)675 ice_vc_version_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
676 {
677 	struct virtchnl_version_info *recv_vf_version;
678 	struct ice_hw *hw = &sc->hw;
679 	device_t dev = sc->dev;
680 
681 	recv_vf_version = (struct virtchnl_version_info *)msg_buf;
682 
683 	/* VFs running the 1.0 API expect to get 1.0 back */
684 	if (VF_IS_V10(recv_vf_version)) {
685 		vf->version.major = 1;
686 		vf->version.minor = VIRTCHNL_VERSION_MINOR_NO_VF_CAPS;
687 	} else {
688 		vf->version.major = VIRTCHNL_VERSION_MAJOR;
689 		vf->version.minor = VIRTCHNL_VERSION_MINOR;
690 
691 		if ((recv_vf_version->major != VIRTCHNL_VERSION_MAJOR) ||
692 		    (recv_vf_version->minor != VIRTCHNL_VERSION_MINOR))
693 		    device_printf(dev,
694 		        "%s: VF-%d requested version (%d.%d) differs from PF version (%d.%d)\n",
695 			__func__, vf->vf_num,
696 			recv_vf_version->major, recv_vf_version->minor,
697 			VIRTCHNL_VERSION_MAJOR, VIRTCHNL_VERSION_MINOR);
698 	}
699 
700 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_VERSION,
701 	    VIRTCHNL_STATUS_SUCCESS, (u8 *)&vf->version, sizeof(vf->version),
702 	    NULL);
703 }
704 
705 /**
706  * ice_vf_validate_mac - Validate MAC address before adding it
707  * @vf: VF tracking structure
708  * @addr: MAC address to validate
709  *
710  * Validate a MAC address before adding it to a VF during the handling
711  * of a VIRTCHNL_OP_ADD_ETH_ADDR operation. Notably, this also checks if
712  * the VF is allowed to set its own arbitrary MAC addresses.
713  *
714  * Returns 0 if MAC address is valid for the given vf
715  */
716 static int
ice_vf_validate_mac(struct ice_vf * vf,const uint8_t * addr)717 ice_vf_validate_mac(struct ice_vf *vf, const uint8_t *addr)
718 {
719 
720 	if (ETHER_IS_ZERO(addr) || ETHER_IS_BROADCAST(addr))
721 		return (EINVAL);
722 
723 	/*
724 	 * If the VF is not allowed to change its MAC address, don't let it
725 	 * set a MAC filter for an address that is not a multicast address and
726 	 * is not its assigned MAC.
727 	 */
728 	if (!(vf->vf_flags & VF_FLAG_SET_MAC_CAP) &&
729 	    !(ETHER_IS_MULTICAST(addr) || !bcmp(addr, vf->mac, ETHER_ADDR_LEN)))
730 		return (EPERM);
731 
732 	return (0);
733 }
734 
735 /**
736  * ice_vc_add_eth_addr_msg - Handle VIRTCHNL_OP_ADD_ETH_ADDR msg from VF
737  * @sc: device private structure
738  * @vf: VF tracking structure
739  * @msg_buf: raw message buffer from the VF
740  *
741  * Receives a list of MAC addresses from the VF and adds those addresses
742  * to the VSI's filter list.
743  */
744 static void
ice_vc_add_eth_addr_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)745 ice_vc_add_eth_addr_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
746 {
747 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
748 	struct virtchnl_ether_addr_list *addr_list;
749 	struct ice_hw *hw = &sc->hw;
750 	u16 added_addr_cnt = 0;
751 	int error = 0;
752 
753 	addr_list = (struct virtchnl_ether_addr_list *)msg_buf;
754 
755 	if (addr_list->num_elements >
756 	    (vf->mac_filter_limit - vf->mac_filter_cnt)) {
757 		v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
758 		goto done;
759 	}
760 
761 	for (int i = 0; i < addr_list->num_elements; i++) {
762 		u8 *addr = addr_list->list[i].addr;
763 
764 		/* The type flag is currently ignored; every MAC address is
765 		 * treated as the LEGACY type
766 		 */
767 
768 		error = ice_vf_validate_mac(vf, addr);
769 		if (error == EPERM) {
770 			device_printf(sc->dev,
771 			    "%s: VF-%d: Not permitted to add MAC addr for VSI %d\n",
772 			    __func__, vf->vf_num, vf->vsi->idx);
773 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
774 			continue;
775 		} else if (error) {
776 			device_printf(sc->dev,
777 			    "%s: VF-%d: Did not add invalid MAC addr for VSI %d\n",
778 			    __func__, vf->vf_num, vf->vsi->idx);
779 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
780 			continue;
781 		}
782 
783 		error = ice_add_vsi_mac_filter(vf->vsi, addr);
784 		if (error) {
785 			device_printf(sc->dev,
786 			    "%s: VF-%d: Error adding MAC addr for VSI %d\n",
787 			    __func__, vf->vf_num, vf->vsi->idx);
788 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
789 			continue;
790 		}
791 		/* Don't count VF's MAC against its MAC filter limit */
792 		if (memcmp(addr, vf->mac, ETHER_ADDR_LEN))
793 			added_addr_cnt++;
794 	}
795 
796 	vf->mac_filter_cnt += added_addr_cnt;
797 
798 done:
799 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ADD_ETH_ADDR,
800 	    v_status, NULL, 0, NULL);
801 }
802 
803 /**
804  * ice_vc_del_eth_addr_msg - Handle VIRTCHNL_OP_DEL_ETH_ADDR msg from VF
805  * @sc: device private structure
806  * @vf: VF tracking structure
807  * @msg_buf: raw message buffer from the VF
808  *
809  * Receives a list of MAC addresses from the VF and removes those addresses
810  * from the VSI's filter list.
811  */
812 static void
ice_vc_del_eth_addr_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)813 ice_vc_del_eth_addr_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
814 {
815 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
816 	struct virtchnl_ether_addr_list *addr_list;
817 	struct ice_hw *hw = &sc->hw;
818 	u16 deleted_addr_cnt = 0;
819 	int error = 0;
820 
821 	addr_list = (struct virtchnl_ether_addr_list *)msg_buf;
822 
823 	for (int i = 0; i < addr_list->num_elements; i++) {
824 		error = ice_remove_vsi_mac_filter(vf->vsi, addr_list->list[i].addr);
825 		if (error) {
826 			device_printf(sc->dev,
827 			    "%s: VF-%d: Error removing MAC addr for VSI %d\n",
828 			    __func__, vf->vf_num, vf->vsi->idx);
829 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
830 			continue;
831 		}
832 		/* Don't count VF's MAC against its MAC filter limit */
833 		if (memcmp(addr_list->list[i].addr, vf->mac, ETHER_ADDR_LEN))
834 			deleted_addr_cnt++;
835 	}
836 
837 	if (deleted_addr_cnt >= vf->mac_filter_cnt)
838 		vf->mac_filter_cnt = 0;
839 	else
840 		vf->mac_filter_cnt -= deleted_addr_cnt;
841 
842 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DEL_ETH_ADDR,
843 	    v_status, NULL, 0, NULL);
844 }
845 
846 /**
847  * ice_vc_add_vlan_msg - Handle VIRTCHNL_OP_ADD_VLAN msg from VF
848  * @sc: PF's softc structure
849  * @vf: VF tracking structure
850  * @msg_buf: message buffer from VF
851  *
852  * Adds the VLANs in msg_buf to the VF's VLAN filter list.
853  */
854 static void
ice_vc_add_vlan_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)855 ice_vc_add_vlan_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
856 {
857 	struct ice_hw *hw = &sc->hw;
858 	struct virtchnl_vlan_filter_list *vlan_list;
859 	int status = 0;
860 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
861 	struct ice_vsi *vsi = vf->vsi;
862 
863 	vlan_list = (struct virtchnl_vlan_filter_list *)msg_buf;
864 
865 	if (vlan_list->vsi_id != vsi->idx) {
866 		device_printf(sc->dev,
867 			      "VF-%d: Message has invalid VSI ID (expected %d, got %d)\n",
868 			      vf->vf_num, vsi->idx, vlan_list->vsi_id);
869 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
870 		goto done;
871 	}
872 
873 	if (vlan_list->num_elements > (vf->vlan_limit - vf->vlan_cnt)) {
874 		v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
875 		goto done;
876 	}
877 
878 	status = ice_add_vlan_hw_filters(vsi, vlan_list->vlan_id,
879 					vlan_list->num_elements);
880 	if (status) {
881 		device_printf(sc->dev,
882 			      "VF-%d: Failure adding VLANs to VSI %d, err %s aq_err %s\n",
883 			      vf->vf_num, vsi->idx, ice_status_str(status),
884 			      ice_aq_str(sc->hw.adminq.sq_last_status));
885 		v_status = ice_iov_err_to_virt_err(status);
886 		goto done;
887 	}
888 
889 	vf->vlan_cnt += vlan_list->num_elements;
890 
891 done:
892 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ADD_VLAN,
893 	    v_status, NULL, 0, NULL);
894 }
895 
896 /**
897  * ice_vc_del_vlan_msg - Handle VIRTCHNL_OP_DEL_VLAN msg from VF
898  * @sc: PF's softc structure
899  * @vf: VF tracking structure
900  * @msg_buf: message buffer from VF
901  *
902  * Removes the VLANs in msg_buf from the VF's VLAN filter list.
903  */
904 static void
ice_vc_del_vlan_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)905 ice_vc_del_vlan_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
906 {
907 	struct ice_hw *hw = &sc->hw;
908 	struct virtchnl_vlan_filter_list *vlan_list;
909 	int status = 0;
910 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
911 	struct ice_vsi *vsi = vf->vsi;
912 
913 	vlan_list = (struct virtchnl_vlan_filter_list *)msg_buf;
914 
915 	if (vlan_list->vsi_id != vsi->idx) {
916 		device_printf(sc->dev,
917 			      "VF-%d: Message has invalid VSI ID (expected %d, got %d)\n",
918 			      vf->vf_num, vsi->idx, vlan_list->vsi_id);
919 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
920 		goto done;
921 	}
922 
923 	status = ice_remove_vlan_hw_filters(vsi, vlan_list->vlan_id,
924 					vlan_list->num_elements);
925 	if (status) {
926 		device_printf(sc->dev,
927 			      "VF-%d: Failure deleting VLANs from VSI %d, err %s aq_err %s\n",
928 			      vf->vf_num, vsi->idx, ice_status_str(status),
929 			      ice_aq_str(sc->hw.adminq.sq_last_status));
930 		v_status = ice_iov_err_to_virt_err(status);
931 		goto done;
932 	}
933 
934 	if (vlan_list->num_elements >= vf->vlan_cnt)
935 		vf->vlan_cnt = 0;
936 	else
937 		vf->vlan_cnt -= vlan_list->num_elements;
938 
939 done:
940 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DEL_VLAN,
941 	    v_status, NULL, 0, NULL);
942 }
943 
944 /**
945  * ice_vc_validate_ring_len - Check to see if a descriptor ring length is valid
946  * @ring_len: length of ring
947  *
948  * Check whether a ring size value is valid.
949  *
950  * @returns true if given ring size is valid
951  */
952 static bool
ice_vc_isvalid_ring_len(u16 ring_len)953 ice_vc_isvalid_ring_len(u16 ring_len)
954 {
955 	return (ring_len >= ICE_MIN_DESC_COUNT &&
956 		ring_len <= ICE_MAX_DESC_COUNT &&
957 		!(ring_len % ICE_DESC_COUNT_INCR));
958 }
959 
960 /**
961  * ice_vc_cfg_vsi_qs_msg - Handle VIRTCHNL_OP_CONFIG_VSI_QUEUES msg from VF
962  * @sc: PF's softc structure
963  * @vf: VF tracking structure
964  * @msg_buf: message buffer from VF
965  */
966 static void
ice_vc_cfg_vsi_qs_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)967 ice_vc_cfg_vsi_qs_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
968 {
969 	device_t dev = sc->dev;
970 	struct ice_hw *hw = &sc->hw;
971 	struct virtchnl_vsi_queue_config_info *vqci;
972 	struct virtchnl_queue_pair_info *vqpi;
973 	enum virtchnl_status_code status = VIRTCHNL_STATUS_SUCCESS;
974 	struct ice_vsi *vsi = vf->vsi;
975 	struct ice_tx_queue *txq;
976 	struct ice_rx_queue *rxq;
977 	int i, error = 0;
978 
979 	vqci = (struct virtchnl_vsi_queue_config_info *)msg_buf;
980 
981 	if (vqci->num_queue_pairs > vf->vsi->num_tx_queues &&
982 	    vqci->num_queue_pairs > vf->vsi->num_rx_queues) {
983 		status = VIRTCHNL_STATUS_ERR_PARAM;
984 		goto done;
985 	}
986 
987 	ice_vsi_disable_tx(vf->vsi);
988 	ice_control_all_rx_queues(vf->vsi, false);
989 
990 	/*
991 	 * Clear TX and RX queues config in case VF
992 	 * requests different number of queues.
993 	 */
994 	for (i = 0; i < vsi->num_tx_queues; i++) {
995 		txq = &vsi->tx_queues[i];
996 
997 		txq->desc_count = 0;
998 		txq->tx_paddr = 0;
999 		txq->tc = 0;
1000 	}
1001 
1002 	for (i = 0; i < vsi->num_rx_queues; i++) {
1003 		rxq = &vsi->rx_queues[i];
1004 
1005 		rxq->desc_count = 0;
1006 		rxq->rx_paddr = 0;
1007 	}
1008 
1009 	vqpi = vqci->qpair;
1010 	for (i = 0; i < vqci->num_queue_pairs; i++, vqpi++) {
1011 		/* Initial parameter validation */
1012 		if (vqpi->txq.vsi_id != vf->vsi->idx ||
1013 		    vqpi->rxq.vsi_id != vf->vsi->idx ||
1014 		    vqpi->txq.queue_id != vqpi->rxq.queue_id ||
1015 		    vqpi->txq.headwb_enabled ||
1016 		    vqpi->rxq.splithdr_enabled ||
1017 		    vqpi->rxq.crc_disable ||
1018 		    !(ice_vc_isvalid_ring_len(vqpi->txq.ring_len)) ||
1019 		    !(ice_vc_isvalid_ring_len(vqpi->rxq.ring_len))) {
1020 			status = VIRTCHNL_STATUS_ERR_PARAM;
1021 			goto done;
1022 		}
1023 
1024 		/* Copy parameters into VF's queue/VSI structs */
1025 		txq = &vsi->tx_queues[vqpi->txq.queue_id];
1026 
1027 		txq->desc_count = vqpi->txq.ring_len;
1028 		txq->tx_paddr = vqpi->txq.dma_ring_addr;
1029 		txq->q_handle = vqpi->txq.queue_id;
1030 		txq->tc = 0;
1031 
1032 		rxq = &vsi->rx_queues[vqpi->rxq.queue_id];
1033 
1034 		rxq->desc_count = vqpi->rxq.ring_len;
1035 		rxq->rx_paddr = vqpi->rxq.dma_ring_addr;
1036 		vsi->mbuf_sz = vqpi->rxq.databuffer_size;
1037 	}
1038 
1039 	/* Configure TX queues in HW */
1040 	error = ice_cfg_vsi_for_tx(vsi);
1041 	if (error) {
1042 		device_printf(dev,
1043 			      "VF-%d: Unable to configure VSI for Tx: %s\n",
1044 			      vf->vf_num, ice_err_str(error));
1045 		status = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
1046 		goto done;
1047 	}
1048 
1049 	/* Configure RX queues in HW */
1050 	error = ice_cfg_vsi_for_rx(vsi);
1051 	if (error) {
1052 		device_printf(dev,
1053 			      "VF-%d: Unable to configure VSI for Rx: %s\n",
1054 			      vf->vf_num, ice_err_str(error));
1055 		status = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
1056 		ice_vsi_disable_tx(vsi);
1057 		goto done;
1058 	}
1059 
1060 done:
1061 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
1062 	    status, NULL, 0, NULL);
1063 }
1064 
1065 /**
1066  * ice_vc_cfg_rss_key_msg - Handle VIRTCHNL_OP_CONFIG_RSS_KEY msg from VF
1067  * @sc: PF's softc structure
1068  * @vf: VF tracking structure
1069  * @msg_buf: message buffer from VF
1070  *
1071  * Sets the RSS key for the given VF, using the contents of msg_buf.
1072  */
1073 static void
ice_vc_cfg_rss_key_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1074 ice_vc_cfg_rss_key_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1075 {
1076 	struct ice_aqc_get_set_rss_keys keydata =
1077 	    { .standard_rss_key = {0}, .extended_hash_key = {0} };
1078 	struct ice_hw *hw = &sc->hw;
1079 	struct virtchnl_rss_key *vrk;
1080 	int status = 0;
1081 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1082 	struct ice_vsi *vsi = vf->vsi;
1083 
1084 	vrk = (struct virtchnl_rss_key *)msg_buf;
1085 
1086 	if (vrk->vsi_id != vsi->idx) {
1087 		device_printf(sc->dev,
1088 		    "VF-%d: Message has invalid VSI ID (expected %d, got %d)\n",
1089 		    vf->vf_num, vsi->idx, vrk->vsi_id);
1090 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1091 		goto done;
1092 	}
1093 
1094 	if ((vrk->key_len >
1095 	   (ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE +
1096 	    ICE_AQC_GET_SET_RSS_KEY_DATA_HASH_KEY_SIZE)) ||
1097 	    vrk->key_len == 0) {
1098 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1099 		goto done;
1100 	}
1101 
1102 	memcpy(&keydata, vrk->key, vrk->key_len);
1103 
1104 	status = ice_aq_set_rss_key(hw, vsi->idx, &keydata);
1105 	if (status) {
1106 		device_printf(sc->dev,
1107 			      "ice_aq_set_rss_key status %s, error %s\n",
1108 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
1109 		v_status = ice_iov_err_to_virt_err(status);
1110 		goto done;
1111 	}
1112 
1113 done:
1114 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_CONFIG_RSS_KEY,
1115 	    v_status, NULL, 0, NULL);
1116 }
1117 
1118 /**
1119  * ice_vc_cfg_rss_lut_msg - Handle VIRTCHNL_OP_CONFIG_RSS_LUT msg from VF
1120  * @sc: PF's softc structure
1121  * @vf: VF tracking structure
1122  * @msg_buf: message buffer from VF
1123  *
1124  * Adds the LUT from the VF in msg_buf to the PF via an admin queue call.
1125  */
1126 static void
ice_vc_cfg_rss_lut_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1127 ice_vc_cfg_rss_lut_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1128 {
1129 	struct ice_hw *hw = &sc->hw;
1130 	struct virtchnl_rss_lut *vrl;
1131 	int status = 0;
1132 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1133 	struct ice_aq_get_set_rss_lut_params lut_params = {};
1134 	struct ice_vsi *vsi = vf->vsi;
1135 
1136 	vrl = (struct virtchnl_rss_lut *)msg_buf;
1137 
1138 	if (vrl->vsi_id != vsi->idx) {
1139 		device_printf(sc->dev,
1140 		    "VF-%d: Message has invalid VSI ID (expected %d, got %d)\n",
1141 		    vf->vf_num, vsi->idx, vrl->vsi_id);
1142 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1143 		goto done;
1144 	}
1145 
1146 	if (vrl->lut_entries > ICE_VSIQF_HLUT_ARRAY_SIZE) {
1147 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1148 		goto done;
1149 	}
1150 
1151 	lut_params.vsi_handle = vsi->idx;
1152 	lut_params.lut_size = vsi->rss_table_size;
1153 	lut_params.lut_type = vsi->rss_lut_type;
1154 	lut_params.lut = vrl->lut;
1155 	lut_params.global_lut_id = 0;
1156 
1157 	status = ice_aq_set_rss_lut(hw, &lut_params);
1158 	if (status) {
1159 		device_printf(sc->dev,
1160 			      "VF-%d: Cannot set RSS lut, err %s aq_err %s\n",
1161 			      vf->vf_num, ice_status_str(status),
1162 			      ice_aq_str(hw->adminq.sq_last_status));
1163 		v_status = ice_iov_err_to_virt_err(status);
1164 	}
1165 
1166 done:
1167 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_CONFIG_RSS_LUT,
1168 	    v_status, NULL, 0, NULL);
1169 }
1170 
1171 /**
1172  * ice_vc_set_rss_hena_msg - Handle VIRTCHNL_OP_SET_RSS_HENA msg from VF
1173  * @sc: PF's softc structure
1174  * @vf: VF tracking structure
1175  * @msg_buf: message buffer from VF
1176  *
1177  * Adds the VF's hena (hash enable) bits as flow types to the PF's RSS flow
1178  * type list.
1179  */
1180 static void
ice_vc_set_rss_hena_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1181 ice_vc_set_rss_hena_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1182 {
1183 	struct ice_hw *hw = &sc->hw;
1184 	struct virtchnl_rss_hena *vrh;
1185 	int status = 0;
1186 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1187 	struct ice_vsi *vsi = vf->vsi;
1188 
1189 	MPASS(vsi != NULL);
1190 
1191 	vrh = (struct virtchnl_rss_hena *)msg_buf;
1192 
1193 	/*
1194 	 * Remove existing configuration to make sure only requested
1195 	 * config is applied and allow VFs to disable RSS completly.
1196 	 */
1197 	status = ice_rem_vsi_rss_cfg(hw, vsi->idx);
1198 	if (vrh->hena) {
1199 		/*
1200 		 * Problem with removing config is not fatal, when new one
1201 		 * is requested. Warn about it but try to apply new config
1202 		 * anyway.
1203 		 */
1204 		if (status)
1205 			device_printf(sc->dev,
1206 			    "ice_rem_vsi_rss_cfg status %s, error %s\n",
1207 			    ice_status_str(status),
1208 			    ice_aq_str(hw->adminq.sq_last_status));
1209 		status = ice_add_avf_rss_cfg(hw, vsi->idx, vrh->hena);
1210 		if (status)
1211 			device_printf(sc->dev,
1212 			    "ice_add_avf_rss_cfg status %s, error %s\n",
1213 			    ice_status_str(status),
1214 			    ice_aq_str(hw->adminq.sq_last_status));
1215 	}
1216 	v_status = ice_iov_err_to_virt_err(status);
1217 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_SET_RSS_HENA,
1218 	    v_status, NULL, 0, NULL);
1219 }
1220 
1221 /**
1222  * ice_vc_enable_queues_msg - Handle VIRTCHNL_OP_ENABLE_QUEUES msg from VF
1223  * @sc: PF's softc structure
1224  * @vf: VF tracking structure
1225  * @msg_buf: message buffer from VF
1226  *
1227  * Enables VF queues selected in msg_buf for Tx/Rx traffic.
1228  *
1229  * @remark Only actually operates on Rx queues; Tx queues are enabled in
1230  * CONFIG_VSI_QUEUES message handler.
1231  */
1232 static void
ice_vc_enable_queues_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1233 ice_vc_enable_queues_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1234 {
1235 	struct ice_hw *hw = &sc->hw;
1236 	struct virtchnl_queue_select *vqs;
1237 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1238 	struct ice_vsi *vsi = vf->vsi;
1239 	int bit, error = 0;
1240 
1241 	vqs = (struct virtchnl_queue_select *)msg_buf;
1242 
1243 	if (vqs->vsi_id != vsi->idx) {
1244 		device_printf(sc->dev,
1245 		    "%s: VF-%d: Message has invalid VSI ID (expected %d, got %d)\n",
1246 		    __func__, vf->vf_num, vsi->idx, vqs->vsi_id);
1247 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1248 		goto done;
1249 	}
1250 
1251 	if (!vqs->rx_queues && !vqs->tx_queues) {
1252 		device_printf(sc->dev,
1253 		    "%s: VF-%d: message queue masks are empty\n",
1254 		    __func__, vf->vf_num);
1255 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1256 		goto done;
1257 	}
1258 
1259 	/* Validate rx_queue mask */
1260 	bit = fls(vqs->rx_queues);
1261 	if (bit > vsi->num_rx_queues) {
1262 		device_printf(sc->dev,
1263 		    "%s: VF-%d: message's rx_queues map (0x%08x) has invalid bit set (%d)\n",
1264 		    __func__, vf->vf_num, vqs->rx_queues, bit);
1265 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1266 		goto done;
1267 	}
1268 
1269 	/* Tx ring enable is handled in an earlier message. */
1270 	for_each_set_bit(bit, &vqs->rx_queues, 32) {
1271 		error = ice_control_rx_queue(vsi, bit, true);
1272 		if (error) {
1273 			device_printf(sc->dev,
1274 				      "Unable to enable Rx ring %d for receive: %s\n",
1275 				      bit, ice_err_str(error));
1276 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
1277 			goto done;
1278 		}
1279 	}
1280 
1281 done:
1282 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ENABLE_QUEUES,
1283 	    v_status, NULL, 0, NULL);
1284 }
1285 
1286 /**
1287  * ice_vc_disable_queues_msg - Handle VIRTCHNL_OP_DISABLE_QUEUES msg
1288  * @sc: PF's softc structure
1289  * @vf: VF tracking structure
1290  * @msg_buf: message buffer from VF
1291  *
1292  * Disables all VF queues for the VF's VSI.
1293  *
1294  * @remark Unlike the ENABLE_QUEUES handler, this operates on both
1295  * Tx and Rx queues
1296  */
1297 static void
ice_vc_disable_queues_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf __unused)1298 ice_vc_disable_queues_msg(struct ice_softc *sc, struct ice_vf *vf,
1299 			  u8 *msg_buf __unused)
1300 {
1301 	struct ice_hw *hw = &sc->hw;
1302 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1303 	struct ice_vsi *vsi = vf->vsi;
1304 	int error = 0;
1305 
1306 	error = ice_control_all_rx_queues(vsi, false);
1307 	if (error) {
1308 		device_printf(sc->dev,
1309 			      "Unable to disable Rx rings for transmit: %s\n",
1310 			      ice_err_str(error));
1311 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1312 		goto done;
1313 	}
1314 
1315 	error = ice_vsi_disable_tx(vsi);
1316 	if (error) {
1317 		/* Already prints an error message */
1318 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1319 	}
1320 
1321 done:
1322 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DISABLE_QUEUES,
1323 	    v_status, NULL, 0, NULL);
1324 }
1325 
1326 /**
1327  * ice_vc_cfg_irq_map_msg - Handle VIRTCHNL_OP_CFG_IRQ_MAP msg from VF
1328  * @sc: PF's softc structure
1329  * @vf: VF tracking structure
1330  * @msg_buf: message buffer from VF
1331  *
1332  * Configures the interrupt vectors described in the message in msg_buf. The
1333  * VF needs to send this message during init, so that queues can be allowed
1334  * to generate interrupts.
1335  */
1336 static void
ice_vc_cfg_irq_map_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1337 ice_vc_cfg_irq_map_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1338 {
1339 #define ICE_VIRTCHNL_QUEUE_MAP_SIZE	16
1340 	struct ice_hw *hw = &sc->hw;
1341 	struct virtchnl_irq_map_info *vimi;
1342 	struct virtchnl_vector_map *vvm;
1343 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1344 	struct ice_vsi *vsi = vf->vsi;
1345 	u16 vector;
1346 
1347 	vimi = (struct virtchnl_irq_map_info *)msg_buf;
1348 
1349 	if (vimi->num_vectors > vf->num_irq_vectors) {
1350 		device_printf(sc->dev,
1351 		    "%s: VF-%d: message has more vectors (%d) than configured for VF (%d)\n",
1352 		    __func__, vf->vf_num, vimi->num_vectors, vf->num_irq_vectors);
1353 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1354 		goto done;
1355 	}
1356 
1357 	vvm = vimi->vecmap;
1358 	/* Save off information from message */
1359 	for (int i = 0; i < vimi->num_vectors; i++, vvm++) {
1360 		struct ice_tx_queue *txq;
1361 		struct ice_rx_queue *rxq;
1362 		int bit;
1363 
1364 		if (vvm->vsi_id != vf->vsi->idx) {
1365 			device_printf(sc->dev,
1366 			    "%s: VF-%d: message's VSI ID (%d) does not match VF's (%d) for vector %d\n",
1367 			    __func__, vf->vf_num, vvm->vsi_id, vf->vsi->idx, i);
1368 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
1369 			goto done;
1370 		}
1371 
1372 		/* vvm->vector_id is relative to VF space */
1373 		vector = vvm->vector_id;
1374 
1375 		if (vector >= vf->num_irq_vectors) {
1376 			device_printf(sc->dev,
1377 			    "%s: VF-%d: message's vector ID (%d) is greater than VF's max ID (%d)\n",
1378 			    __func__, vf->vf_num, vector, vf->num_irq_vectors - 1);
1379 			v_status = VIRTCHNL_STATUS_ERR_PARAM;
1380 			goto done;
1381 		}
1382 
1383 		/* The Misc/Admin Queue vector doesn't need mapping */
1384 		if (vector == 0)
1385 			continue;
1386 
1387 		/* coverity[address_of] */
1388 		for_each_set_bit(bit, &vvm->txq_map, ICE_VIRTCHNL_QUEUE_MAP_SIZE) {
1389 			if (bit >= vsi->num_tx_queues) {
1390 				device_printf(sc->dev,
1391 				    "%s: VF-%d: txq map has invalid bit set\n",
1392 				    __func__, vf->vf_num);
1393 				v_status = VIRTCHNL_STATUS_ERR_PARAM;
1394 				goto done;
1395 			}
1396 
1397 			vf->tx_irqvs[vector].me = vector;
1398 
1399 			txq = &vsi->tx_queues[bit];
1400 			txq->irqv = &vf->tx_irqvs[vector];
1401 			txq->itr_idx = vvm->txitr_idx;
1402 		}
1403 		/* coverity[address_of] */
1404 		for_each_set_bit(bit, &vvm->rxq_map, ICE_VIRTCHNL_QUEUE_MAP_SIZE) {
1405 			if (bit >= vsi->num_rx_queues) {
1406 				device_printf(sc->dev,
1407 				    "%s: VF-%d: rxq map has invalid bit set\n",
1408 				    __func__, vf->vf_num);
1409 				v_status = VIRTCHNL_STATUS_ERR_PARAM;
1410 				goto done;
1411 			}
1412 			vf->rx_irqvs[vector].me = vector;
1413 
1414 			rxq = &vsi->rx_queues[bit];
1415 			rxq->irqv = &vf->rx_irqvs[vector];
1416 			rxq->itr_idx = vvm->rxitr_idx;
1417 		}
1418 	}
1419 
1420 	/* Write to T/RQCTL registers to actually map vectors to queues */
1421 	for (int i = 0; i < vf->vsi->num_rx_queues; i++)
1422 		if (vsi->rx_queues[i].irqv != NULL)
1423 			ice_configure_rxq_interrupt(hw, vsi->rx_qmap[i],
1424 			    vsi->rx_queues[i].irqv->me, vsi->rx_queues[i].itr_idx);
1425 
1426 	for (int i = 0; i < vf->vsi->num_tx_queues; i++)
1427 		if (vsi->tx_queues[i].irqv != NULL)
1428 			ice_configure_txq_interrupt(hw, vsi->tx_qmap[i],
1429 			    vsi->tx_queues[i].irqv->me, vsi->tx_queues[i].itr_idx);
1430 
1431 	ice_flush(hw);
1432 
1433 done:
1434 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_CONFIG_IRQ_MAP,
1435 	    v_status, NULL, 0, NULL);
1436 }
1437 
1438 /**
1439  * ice_eth_stats_to_virtchnl_eth_stats - Convert stats for virtchnl
1440  * @istats: VSI stats from HW to convert
1441  * @vstats: stats struct to copy to
1442  *
1443  * This function copies all known stats in struct virtchnl_eth_stats from the
1444  * input struct ice_eth_stats to an output struct virtchnl_eth_stats.
1445  *
1446  * @remark These two structure types currently have the same definition up to
1447  * the size of struct virtchnl_eth_stats (on FreeBSD), but that could change
1448  * in the future.
1449  */
1450 static void
ice_eth_stats_to_virtchnl_eth_stats(struct ice_eth_stats * istats,struct virtchnl_eth_stats * vstats)1451 ice_eth_stats_to_virtchnl_eth_stats(struct ice_eth_stats *istats,
1452 				    struct virtchnl_eth_stats *vstats)
1453 {
1454 	vstats->rx_bytes = istats->rx_bytes;
1455 	vstats->rx_unicast = istats->rx_unicast;
1456 	vstats->rx_multicast = istats->rx_multicast;
1457 	vstats->rx_broadcast = istats->rx_broadcast;
1458 	vstats->rx_discards = istats->rx_discards;
1459 	vstats->rx_unknown_protocol = istats->rx_unknown_protocol;
1460 	vstats->tx_bytes = istats->tx_bytes;
1461 	vstats->tx_unicast = istats->tx_unicast;
1462 	vstats->tx_multicast = istats->tx_multicast;
1463 	vstats->tx_broadcast = istats->tx_broadcast;
1464 	vstats->tx_discards = istats->tx_discards;
1465 	vstats->tx_errors = istats->tx_errors;
1466 }
1467 
1468 /**
1469  * ice_vc_get_stats_msg - Handle VIRTCHNL_OP_GET_STATS msg
1470  * @sc: device private structure
1471  * @vf: VF tracking structure
1472  * @msg_buf: raw message buffer from the VF
1473  *
1474  * Updates the VF's VSI stats and sends those stats back to the VF.
1475  */
1476 static void
ice_vc_get_stats_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1477 ice_vc_get_stats_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1478 {
1479 	struct virtchnl_queue_select *vqs;
1480 	struct virtchnl_eth_stats stats;
1481 	struct ice_vsi *vsi = vf->vsi;
1482 	struct ice_hw *hw = &sc->hw;
1483 
1484 	vqs = (struct virtchnl_queue_select *)msg_buf;
1485 
1486 	if (vqs->vsi_id != vsi->idx) {
1487 		device_printf(sc->dev,
1488 		    "%s: VF-%d: message has invalid VSI ID %d (VF has VSI ID %d)\n",
1489 		    __func__, vf->vf_num, vqs->vsi_id, vsi->idx);
1490 		ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_GET_STATS,
1491 		    VIRTCHNL_STATUS_ERR_PARAM, NULL, 0, NULL);
1492 	}
1493 
1494 	ice_update_vsi_hw_stats(vf->vsi);
1495 	ice_eth_stats_to_virtchnl_eth_stats(&vsi->hw_stats.cur, &stats);
1496 
1497 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_GET_STATS,
1498 	    VIRTCHNL_STATUS_SUCCESS, (u8 *)&stats,
1499 	    sizeof(struct virtchnl_eth_stats), NULL);
1500 }
1501 
1502 /**
1503  * ice_vc_cfg_promisc_mode_msg - Handle VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE
1504  * @sc: PF's softc structure
1505  * @vf: VF tracking structure
1506  * @msg_buf: message buffer from VF
1507  *
1508  * Configures the promiscuous modes for the given VSI in msg_buf.
1509  */
1510 static void
ice_vc_cfg_promisc_mode_msg(struct ice_softc * sc,struct ice_vf * vf,u8 * msg_buf)1511 ice_vc_cfg_promisc_mode_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
1512 {
1513 	struct ice_hw *hw = &sc->hw;
1514 	struct virtchnl_promisc_info *vpi;
1515 	enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
1516 	int status = 0;
1517 	struct ice_vsi *vsi = vf->vsi;
1518 	ice_declare_bitmap(old_promisc_mask, ICE_PROMISC_MAX);
1519 	ice_declare_bitmap(req_promisc_mask, ICE_PROMISC_MAX);
1520 	ice_declare_bitmap(clear_promisc_mask, ICE_PROMISC_MAX);
1521 	ice_declare_bitmap(set_promisc_mask, ICE_PROMISC_MAX);
1522 	ice_declare_bitmap(old_req_xor_mask, ICE_PROMISC_MAX);
1523 	u16 vid;
1524 
1525 	vpi = (struct virtchnl_promisc_info *)msg_buf;
1526 
1527 	/* Check to see if VF has permission to configure promiscuous mode */
1528 	if (!(vf->vf_flags & VF_FLAG_PROMISC_CAP)) {
1529 		device_printf(sc->dev,
1530 			      "VF-%d: attempted to configure promiscuous mode\n",
1531 			      vf->vf_num);
1532 		/* Don't reply to VF with an error */
1533 		goto done;
1534 	}
1535 
1536 	if (vpi->vsi_id != vsi->idx) {
1537 		device_printf(sc->dev,
1538 			      "VF-%d: Message has invalid VSI ID (expected %d, got %d)\n",
1539 			      vf->vf_num, vsi->idx, vpi->vsi_id);
1540 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1541 		goto done;
1542 	}
1543 
1544 	if (vpi->flags & ~ICE_VIRTCHNL_VALID_PROMISC_FLAGS) {
1545 		device_printf(sc->dev,
1546 			      "VF-%d: Message has invalid promiscuous flags set (valid 0x%02x, got 0x%02x)\n",
1547 			      vf->vf_num, ICE_VIRTCHNL_VALID_PROMISC_FLAGS,
1548 			      vpi->flags);
1549 		v_status = VIRTCHNL_STATUS_ERR_PARAM;
1550 		goto done;
1551 
1552 	}
1553 
1554 	ice_zero_bitmap(req_promisc_mask, ICE_PROMISC_MAX);
1555 	/* Convert virtchnl flags to ice AQ promiscuous mode flags */
1556 	if (vpi->flags & FLAG_VF_UNICAST_PROMISC) {
1557 		ice_set_bit(ICE_PROMISC_UCAST_TX, req_promisc_mask);
1558 		ice_set_bit(ICE_PROMISC_UCAST_RX, req_promisc_mask);
1559 	}
1560 	if (vpi->flags & FLAG_VF_MULTICAST_PROMISC) {
1561 		ice_set_bit(ICE_PROMISC_MCAST_TX, req_promisc_mask);
1562 		ice_set_bit(ICE_PROMISC_MCAST_RX, req_promisc_mask);
1563 	}
1564 
1565 	status = ice_get_vsi_promisc(hw, vsi->idx, old_promisc_mask, &vid);
1566 	if (status) {
1567 		device_printf(sc->dev,
1568 			      "VF-%d: Failed to get promiscuous mode mask for VSI %d, err %s aq_err %s\n",
1569 			      vf->vf_num, vsi->idx,
1570 			      ice_status_str(status),
1571 			      ice_aq_str(hw->adminq.sq_last_status));
1572 		v_status = ice_iov_err_to_virt_err(status);
1573 		goto done;
1574 	}
1575 
1576 	/* Figure out what got added and what got removed */
1577 	ice_zero_bitmap(old_req_xor_mask, ICE_PROMISC_MAX);
1578 	ice_xor_bitmap(old_req_xor_mask, old_promisc_mask, req_promisc_mask, ICE_PROMISC_MAX);
1579 	ice_and_bitmap(clear_promisc_mask, old_req_xor_mask, old_promisc_mask, ICE_PROMISC_MAX);
1580 	ice_and_bitmap(set_promisc_mask, old_req_xor_mask, req_promisc_mask, ICE_PROMISC_MAX);
1581 
1582 	if (ice_is_any_bit_set(clear_promisc_mask, ICE_PROMISC_MAX)) {
1583 		status = ice_clear_vsi_promisc(hw, vsi->idx,
1584 					       clear_promisc_mask, 0);
1585 		if (status) {
1586 			device_printf(sc->dev,
1587 				      "VF-%d: Failed to clear promiscuous mode for VSI %d, err %s aq_err %s\n",
1588 				      vf->vf_num, vsi->idx,
1589 				      ice_status_str(status),
1590 				      ice_aq_str(hw->adminq.sq_last_status));
1591 			v_status = ice_iov_err_to_virt_err(status);
1592 			goto done;
1593 		}
1594 	}
1595 
1596 	if (ice_is_any_bit_set(set_promisc_mask, ICE_PROMISC_MAX)) {
1597 		status = ice_set_vsi_promisc(hw, vsi->idx, set_promisc_mask, 0);
1598 		if (status) {
1599 			device_printf(sc->dev,
1600 				      "VF-%d: Failed to set promiscuous mode for VSI %d, err %s aq_err %s\n",
1601 				      vf->vf_num, vsi->idx,
1602 				      ice_status_str(status),
1603 				      ice_aq_str(hw->adminq.sq_last_status));
1604 			v_status = ice_iov_err_to_virt_err(status);
1605 			goto done;
1606 		}
1607 	}
1608 
1609 done:
1610 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
1611 	    v_status, NULL, 0, NULL);
1612 }
1613 
1614 /**
1615  * ice_vc_notify_all_vfs_link_state - Notify all VFs of PF link state
1616  * @sc: device private structure
1617  *
1618  * Sends a message to all VFs about the status of the PF's link
1619  * state. For more details, @see ice_vc_notify_vf_link_state.
1620  */
1621 void
ice_vc_notify_all_vfs_link_state(struct ice_softc * sc)1622 ice_vc_notify_all_vfs_link_state(struct ice_softc *sc)
1623 {
1624 	for (int i = 0; i < sc->num_vfs; i++)
1625 		ice_vc_notify_vf_link_state(sc, &sc->vfs[i]);
1626 }
1627 
1628 /**
1629  * ice_vc_notify_vf_link_state - Notify VF of PF link state
1630  * @sc: device private structure
1631  * @vf: VF tracking structure
1632  *
1633  * Sends an event message to the specified VF with information about
1634  * the current link state from the PF's port. This includes whether
1635  * link is up or down, and the link speed in 100Mbps units.
1636  */
1637 static void
ice_vc_notify_vf_link_state(struct ice_softc * sc,struct ice_vf * vf)1638 ice_vc_notify_vf_link_state(struct ice_softc *sc, struct ice_vf *vf)
1639 {
1640 	struct virtchnl_pf_event event = {};
1641 	struct ice_hw *hw = &sc->hw;
1642 
1643 	event.event = VIRTCHNL_EVENT_LINK_CHANGE;
1644 	event.severity = PF_EVENT_SEVERITY_INFO;
1645 	event.event_data.link_event_adv.link_status = sc->link_up;
1646 	event.event_data.link_event_adv.link_speed =
1647 		(u32)ice_conv_link_speed_to_virtchnl(true,
1648 		    hw->port_info->phy.link_info.link_speed);
1649 
1650 	ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_EVENT,
1651 	    VIRTCHNL_STATUS_SUCCESS, (u8 *)&event, sizeof(event), NULL);
1652 }
1653 
1654 /**
1655  * ice_vc_handle_vf_msg - Handle a message from a VF
1656  * @sc: device private structure
1657  * @event: event received from the HW MBX queue
1658  *
1659  * Called whenever an event is received from a VF on the HW mailbox queue.
1660  * Responsible for handling these messages as well as responding to the
1661  * VF afterwards, depending on the received message type.
1662  */
1663 void
ice_vc_handle_vf_msg(struct ice_softc * sc,struct ice_rq_event_info * event)1664 ice_vc_handle_vf_msg(struct ice_softc *sc, struct ice_rq_event_info *event)
1665 {
1666 	struct ice_hw *hw = &sc->hw;
1667 	device_t dev = sc->dev;
1668 	struct ice_vf *vf;
1669 	int err = 0;
1670 
1671 	u32 v_opcode = event->desc.cookie_high;
1672 	u16 v_id = event->desc.retval;
1673 	u8 *msg = event->msg_buf;
1674 	u16 msglen = event->msg_len;
1675 
1676 	if (v_id >= sc->num_vfs) {
1677 		device_printf(dev, "%s: Received msg from invalid VF-%d: opcode %d, len %d\n",
1678 		    __func__, v_id, v_opcode, msglen);
1679 		return;
1680 	}
1681 
1682 	vf = &sc->vfs[v_id];
1683 
1684 	/* Perform basic checks on the msg */
1685 	err = virtchnl_vc_validate_vf_msg(&vf->version, v_opcode, msg, msglen);
1686 	if (err) {
1687 		device_printf(dev, "%s: Received invalid msg from VF-%d: opcode %d, len %d, error %d\n",
1688 		    __func__, vf->vf_num, v_opcode, msglen, err);
1689 		ice_aq_send_msg_to_vf(hw, v_id, v_opcode, VIRTCHNL_STATUS_ERR_PARAM, NULL, 0, NULL);
1690 		return;
1691 	}
1692 
1693 	switch (v_opcode) {
1694 	case VIRTCHNL_OP_VERSION:
1695 		ice_vc_version_msg(sc, vf, msg);
1696 		break;
1697 	case VIRTCHNL_OP_RESET_VF:
1698 		ice_reset_vf(sc, vf, true);
1699 		break;
1700 	case VIRTCHNL_OP_GET_VF_RESOURCES:
1701 		ice_vc_get_vf_res_msg(sc, vf, msg);
1702 		break;
1703 	case VIRTCHNL_OP_ADD_ETH_ADDR:
1704 		ice_vc_add_eth_addr_msg(sc, vf, msg);
1705 		break;
1706 	case VIRTCHNL_OP_DEL_ETH_ADDR:
1707 		ice_vc_del_eth_addr_msg(sc, vf, msg);
1708 		break;
1709 	case VIRTCHNL_OP_ADD_VLAN:
1710 		ice_vc_add_vlan_msg(sc, vf, msg);
1711 		break;
1712 	case VIRTCHNL_OP_DEL_VLAN:
1713 		ice_vc_del_vlan_msg(sc, vf, msg);
1714 		break;
1715 	case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
1716 		ice_vc_cfg_vsi_qs_msg(sc, vf, msg);
1717 		break;
1718 	case VIRTCHNL_OP_CONFIG_RSS_KEY:
1719 		ice_vc_cfg_rss_key_msg(sc, vf, msg);
1720 		break;
1721 	case VIRTCHNL_OP_CONFIG_RSS_LUT:
1722 		ice_vc_cfg_rss_lut_msg(sc, vf, msg);
1723 		break;
1724 	case VIRTCHNL_OP_SET_RSS_HENA:
1725 		ice_vc_set_rss_hena_msg(sc, vf, msg);
1726 		break;
1727 	case VIRTCHNL_OP_ENABLE_QUEUES:
1728 		ice_vc_enable_queues_msg(sc, vf, msg);
1729 		ice_vc_notify_vf_link_state(sc, vf);
1730 		break;
1731 	case VIRTCHNL_OP_DISABLE_QUEUES:
1732 		ice_vc_disable_queues_msg(sc, vf, msg);
1733 		break;
1734 	case VIRTCHNL_OP_CONFIG_IRQ_MAP:
1735 		ice_vc_cfg_irq_map_msg(sc, vf, msg);
1736 		break;
1737 	case VIRTCHNL_OP_GET_STATS:
1738 		ice_vc_get_stats_msg(sc, vf, msg);
1739 		break;
1740 	case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
1741 		ice_vc_cfg_promisc_mode_msg(sc, vf, msg);
1742 		break;
1743 	default:
1744 		device_printf(dev, "%s: Received unknown msg from VF-%d: opcode %d, len %d\n",
1745 		    __func__, vf->vf_num, v_opcode, msglen);
1746 		ice_aq_send_msg_to_vf(hw, v_id, v_opcode,
1747 		    VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL, 0, NULL);
1748 		break;
1749 	}
1750 }
1751 
1752 /**
1753  * ice_iov_setup_intr_mapping - Setup interrupt config for a VF
1754  * @sc: device softc structure
1755  * @vf: driver's VF structure for VF to be configured
1756  *
1757  * Before a VF can be used, and after a VF reset, the PF must configure
1758  * the VF's interrupt allocation registers. This includes allocating
1759  * interrupts from the PF's interrupt pool to the VF using the
1760  * VPINT_ALLOC(_PCI) registers, and setting up a mapping from PF vectors
1761  * to VF vectors in GLINT_VECT2FUNC.
1762  *
1763  * As well, this sets up queue allocation registers and maps the mailbox
1764  * interrupt for the VF.
1765  */
1766 static void
ice_iov_setup_intr_mapping(struct ice_softc * sc,struct ice_vf * vf)1767 ice_iov_setup_intr_mapping(struct ice_softc *sc, struct ice_vf *vf)
1768 {
1769 	struct ice_hw *hw = &sc->hw;
1770 	struct ice_vsi *vsi = vf->vsi;
1771 	u16 v;
1772 
1773 	/* Calculate indices for register ops below */
1774 	u16 vf_first_irq_idx = vf->vf_imap[0];
1775 	u16 vf_last_irq_idx = (vf_first_irq_idx + vf->num_irq_vectors) - 1;
1776 	u16 abs_vf_first_irq_idx = hw->func_caps.common_cap.msix_vector_first_id +
1777 	    vf_first_irq_idx;
1778 	u16 abs_vf_last_irq_idx = (abs_vf_first_irq_idx + vf->num_irq_vectors) - 1;
1779 	u16 abs_vf_num = vf->vf_num + hw->func_caps.vf_base_id;
1780 
1781 	/* Map out VF interrupt allocation in global device space. Both
1782 	 * VPINT_ALLOC and VPINT_ALLOC_PCI use the same values.
1783 	 */
1784 	wr32(hw, VPINT_ALLOC(vf->vf_num),
1785 	    (((abs_vf_first_irq_idx << VPINT_ALLOC_FIRST_S) & VPINT_ALLOC_FIRST_M) |
1786 	    ((abs_vf_last_irq_idx << VPINT_ALLOC_LAST_S) & VPINT_ALLOC_LAST_M) |
1787 	    VPINT_ALLOC_VALID_M));
1788 	wr32(hw, VPINT_ALLOC_PCI(vf->vf_num),
1789 	    (((abs_vf_first_irq_idx << VPINT_ALLOC_PCI_FIRST_S) & VPINT_ALLOC_PCI_FIRST_M) |
1790 	    ((abs_vf_last_irq_idx << VPINT_ALLOC_PCI_LAST_S) & VPINT_ALLOC_PCI_LAST_M) |
1791 	    VPINT_ALLOC_PCI_VALID_M));
1792 
1793 	/* Create inverse mapping of vectors to PF/VF combinations */
1794 	for (v = vf_first_irq_idx; v <= vf_last_irq_idx; v++)
1795 	{
1796 		wr32(hw, GLINT_VECT2FUNC(v),
1797 		    (((abs_vf_num << GLINT_VECT2FUNC_VF_NUM_S) & GLINT_VECT2FUNC_VF_NUM_M) |
1798 		     ((hw->pf_id << GLINT_VECT2FUNC_PF_NUM_S) & GLINT_VECT2FUNC_PF_NUM_M)));
1799 	}
1800 
1801 	/* Map mailbox interrupt to MSI-X index 0. Disable ITR for it, too. */
1802 	wr32(hw, VPINT_MBX_CTL(abs_vf_num),
1803 	    ((0 << VPINT_MBX_CTL_MSIX_INDX_S) & VPINT_MBX_CTL_MSIX_INDX_M) |
1804 	    ((0x3 << VPINT_MBX_CTL_ITR_INDX_S) & VPINT_MBX_CTL_ITR_INDX_M) |
1805 	    VPINT_MBX_CTL_CAUSE_ENA_M);
1806 
1807 	/* Mark the TX queue mapping registers as valid */
1808 	wr32(hw, VPLAN_TXQ_MAPENA(vf->vf_num), VPLAN_TXQ_MAPENA_TX_ENA_M);
1809 
1810 	/* Indicate to HW that VF has scattered queue allocation */
1811 	wr32(hw, VPLAN_TX_QBASE(vf->vf_num), VPLAN_TX_QBASE_VFQTABLE_ENA_M);
1812 	for (int i = 0; i < vsi->num_tx_queues; i++) {
1813 		wr32(hw, VPLAN_TX_QTABLE(i, vf->vf_num),
1814 		    (vsi->tx_qmap[i] << VPLAN_TX_QTABLE_QINDEX_S) & VPLAN_TX_QTABLE_QINDEX_M);
1815 	}
1816 
1817 	/* Mark the RX queue mapping registers as valid */
1818 	wr32(hw, VPLAN_RXQ_MAPENA(vf->vf_num), VPLAN_RXQ_MAPENA_RX_ENA_M);
1819 	wr32(hw, VPLAN_RX_QBASE(vf->vf_num), VPLAN_RX_QBASE_VFQTABLE_ENA_M);
1820 	for (int i = 0; i < vsi->num_rx_queues; i++) {
1821 		wr32(hw, VPLAN_RX_QTABLE(i, vf->vf_num),
1822 		    (vsi->rx_qmap[i] << VPLAN_RX_QTABLE_QINDEX_S) & VPLAN_RX_QTABLE_QINDEX_M);
1823 	}
1824 }
1825 
1826 /**
1827  * ice_err_to_virt err - translate ice errors into virtchnl errors
1828  * @ice_err: status returned from ice function
1829  */
1830 static enum virtchnl_status_code
ice_iov_err_to_virt_err(int ice_err)1831 ice_iov_err_to_virt_err(int ice_err)
1832 {
1833 	switch (ice_err) {
1834 	case 0:
1835 		return VIRTCHNL_STATUS_SUCCESS;
1836 	case ICE_ERR_BAD_PTR:
1837 	case ICE_ERR_INVAL_SIZE:
1838 	case ICE_ERR_DEVICE_NOT_SUPPORTED:
1839 	case ICE_ERR_PARAM:
1840 	case ICE_ERR_CFG:
1841 		return VIRTCHNL_STATUS_ERR_PARAM;
1842 	case ICE_ERR_NO_MEMORY:
1843 		return VIRTCHNL_STATUS_ERR_NO_MEMORY;
1844 	case ICE_ERR_NOT_READY:
1845 	case ICE_ERR_RESET_FAILED:
1846 	case ICE_ERR_FW_API_VER:
1847 	case ICE_ERR_AQ_ERROR:
1848 	case ICE_ERR_AQ_TIMEOUT:
1849 	case ICE_ERR_AQ_FULL:
1850 	case ICE_ERR_AQ_NO_WORK:
1851 	case ICE_ERR_AQ_EMPTY:
1852 		return VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
1853 	default:
1854 		return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
1855 	}
1856 }
1857