1/******************************************************************************
2
3  Copyright (c) 2013-2018, 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_iov.h"
35
36/* Private functions */
37static void	ixl_vf_map_vsi_queue(struct i40e_hw *hw, struct ixl_vf *vf, int qnum, uint32_t val);
38static void	ixl_vf_disable_queue_intr(struct i40e_hw *hw, uint32_t vfint_reg);
39static void	ixl_vf_unregister_intr(struct i40e_hw *hw, uint32_t vpint_reg);
40
41static int	ixl_vc_opcode_level(uint16_t opcode);
42
43static int	ixl_vf_mac_valid(struct ixl_vf *vf, const uint8_t *addr);
44
45static int	ixl_vf_alloc_vsi(struct ixl_pf *pf, struct ixl_vf *vf);
46static int	ixl_vf_setup_vsi(struct ixl_pf *pf, struct ixl_vf *vf);
47static void	ixl_vf_map_queues(struct ixl_pf *pf, struct ixl_vf *vf);
48static void	ixl_vf_vsi_release(struct ixl_pf *pf, struct ixl_vsi *vsi);
49static void	ixl_vf_release_resources(struct ixl_pf *pf, struct ixl_vf *vf);
50static int	ixl_flush_pcie(struct ixl_pf *pf, struct ixl_vf *vf);
51static void	ixl_reset_vf(struct ixl_pf *pf, struct ixl_vf *vf);
52static void	ixl_reinit_vf(struct ixl_pf *pf, struct ixl_vf *vf);
53static void	ixl_send_vf_msg(struct ixl_pf *pf, struct ixl_vf *vf, uint16_t op, enum i40e_status_code status, void *msg, uint16_t len);
54static void	ixl_send_vf_ack(struct ixl_pf *pf, struct ixl_vf *vf, uint16_t op);
55static void	ixl_send_vf_nack_msg(struct ixl_pf *pf, struct ixl_vf *vf, uint16_t op, enum i40e_status_code status, const char *file, int line);
56static void	ixl_vf_version_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
57static void	ixl_vf_reset_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
58static void	ixl_vf_get_resources_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
59static int	ixl_vf_config_tx_queue(struct ixl_pf *pf, struct ixl_vf *vf, struct virtchnl_txq_info *info);
60static int	ixl_vf_config_rx_queue(struct ixl_pf *pf, struct ixl_vf *vf, struct virtchnl_rxq_info *info);
61static void	ixl_vf_config_vsi_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
62static void	ixl_vf_set_qctl(struct ixl_pf *pf, const struct virtchnl_vector_map *vector, enum i40e_queue_type cur_type, uint16_t cur_queue,
63    enum i40e_queue_type *last_type, uint16_t *last_queue);
64static void	ixl_vf_config_vector(struct ixl_pf *pf, struct ixl_vf *vf, const struct virtchnl_vector_map *vector);
65static void	ixl_vf_config_irq_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
66static void	ixl_vf_enable_queues_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
67static void	ixl_vf_disable_queues_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
68static void	ixl_vf_add_mac_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
69static void	ixl_vf_del_mac_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
70static enum i40e_status_code	ixl_vf_enable_vlan_strip(struct ixl_pf *pf, struct ixl_vf *vf);
71static void	ixl_vf_add_vlan_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
72static void	ixl_vf_del_vlan_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
73static void	ixl_vf_config_promisc_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
74static void	ixl_vf_get_stats_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg, uint16_t msg_size);
75static int	ixl_vf_reserve_queues(struct ixl_pf *pf, struct ixl_vf *vf, int num_queues);
76static int	ixl_config_pf_vsi_loopback(struct ixl_pf *pf, bool enable);
77
78static int	ixl_adminq_err_to_errno(enum i40e_admin_queue_err err);
79
80/*
81 * TODO: Move pieces of this into iflib and call the rest in a handler?
82 *
83 * e.g. ixl_if_iov_set_schema
84 *
85 * It's odd to do pci_iov_detach() there while doing pci_iov_attach()
86 * in the driver.
87 */
88void
89ixl_initialize_sriov(struct ixl_pf *pf)
90{
91	device_t dev = pf->dev;
92	struct i40e_hw *hw = &pf->hw;
93	nvlist_t	*pf_schema, *vf_schema;
94	int		iov_error;
95
96	pf_schema = pci_iov_schema_alloc_node();
97	vf_schema = pci_iov_schema_alloc_node();
98	pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
99	pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof",
100	    IOV_SCHEMA_HASDEFAULT, TRUE);
101	pci_iov_schema_add_bool(vf_schema, "allow-set-mac",
102	    IOV_SCHEMA_HASDEFAULT, FALSE);
103	pci_iov_schema_add_bool(vf_schema, "allow-promisc",
104	    IOV_SCHEMA_HASDEFAULT, FALSE);
105	pci_iov_schema_add_uint16(vf_schema, "num-queues",
106	    IOV_SCHEMA_HASDEFAULT,
107	    max(1, min(hw->func_caps.num_msix_vectors_vf - 1, IAVF_MAX_QUEUES)));
108
109	iov_error = pci_iov_attach(dev, pf_schema, vf_schema);
110	if (iov_error != 0) {
111		device_printf(dev,
112		    "Failed to initialize SR-IOV (error=%d)\n",
113		    iov_error);
114	} else
115		device_printf(dev, "SR-IOV ready\n");
116
117	pf->vc_debug_lvl = 1;
118}
119
120/*
121 * Allocate the VSI for a VF.
122 */
123static int
124ixl_vf_alloc_vsi(struct ixl_pf *pf, struct ixl_vf *vf)
125{
126	device_t dev;
127	struct i40e_hw *hw;
128	struct i40e_vsi_context vsi_ctx;
129	int i;
130	enum i40e_status_code code;
131
132	hw = &pf->hw;
133	dev = pf->dev;
134
135	vsi_ctx.pf_num = hw->pf_id;
136	vsi_ctx.uplink_seid = pf->veb_seid;
137	vsi_ctx.connection_type = IXL_VSI_DATA_PORT;
138	vsi_ctx.vf_num = hw->func_caps.vf_base_id + vf->vf_num;
139	vsi_ctx.flags = I40E_AQ_VSI_TYPE_VF;
140
141	bzero(&vsi_ctx.info, sizeof(vsi_ctx.info));
142
143	vsi_ctx.info.valid_sections = htole16(I40E_AQ_VSI_PROP_SWITCH_VALID);
144	if (pf->enable_vf_loopback)
145		vsi_ctx.info.switch_id =
146		   htole16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
147
148	vsi_ctx.info.valid_sections |= htole16(I40E_AQ_VSI_PROP_SECURITY_VALID);
149	vsi_ctx.info.sec_flags = 0;
150	if (vf->vf_flags & VF_FLAG_MAC_ANTI_SPOOF)
151		vsi_ctx.info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
152
153	vsi_ctx.info.valid_sections |= htole16(I40E_AQ_VSI_PROP_VLAN_VALID);
154	vsi_ctx.info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_ALL |
155	    I40E_AQ_VSI_PVLAN_EMOD_NOTHING;
156
157	vsi_ctx.info.valid_sections |=
158	    htole16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID);
159	vsi_ctx.info.mapping_flags = htole16(I40E_AQ_VSI_QUE_MAP_NONCONTIG);
160
161	/* XXX: Only scattered allocation is supported for VFs right now */
162	for (i = 0; i < vf->qtag.num_active; i++)
163		vsi_ctx.info.queue_mapping[i] = vf->qtag.qidx[i];
164	for (; i < nitems(vsi_ctx.info.queue_mapping); i++)
165		vsi_ctx.info.queue_mapping[i] = htole16(I40E_AQ_VSI_QUEUE_MASK);
166
167	vsi_ctx.info.tc_mapping[0] = htole16(
168	    (0 << I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) |
169	    ((fls(vf->qtag.num_allocated) - 1) << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT));
170
171	code = i40e_aq_add_vsi(hw, &vsi_ctx, NULL);
172	if (code != I40E_SUCCESS)
173		return (ixl_adminq_err_to_errno(hw->aq.asq_last_status));
174	vf->vsi.seid = vsi_ctx.seid;
175	vf->vsi.vsi_num = vsi_ctx.vsi_number;
176	vf->vsi.num_rx_queues = vf->qtag.num_active;
177	vf->vsi.num_tx_queues = vf->qtag.num_active;
178
179	code = i40e_aq_get_vsi_params(hw, &vsi_ctx, NULL);
180	if (code != I40E_SUCCESS)
181		return (ixl_adminq_err_to_errno(hw->aq.asq_last_status));
182
183	code = i40e_aq_config_vsi_bw_limit(hw, vf->vsi.seid, 0, 0, NULL);
184	if (code != I40E_SUCCESS) {
185		device_printf(dev, "Failed to disable BW limit: %d\n",
186		    ixl_adminq_err_to_errno(hw->aq.asq_last_status));
187		return (ixl_adminq_err_to_errno(hw->aq.asq_last_status));
188	}
189
190	memcpy(&vf->vsi.info, &vsi_ctx.info, sizeof(vf->vsi.info));
191	return (0);
192}
193
194static int
195ixl_vf_setup_vsi(struct ixl_pf *pf, struct ixl_vf *vf)
196{
197	struct i40e_hw *hw;
198	int error;
199
200	hw = &pf->hw;
201	vf->vsi.flags |= IXL_FLAGS_IS_VF;
202
203	error = ixl_vf_alloc_vsi(pf, vf);
204	if (error != 0)
205		return (error);
206
207	vf->vsi.dev = pf->dev;
208
209	ixl_init_filters(&vf->vsi);
210	/* Let VF receive broadcast Ethernet frames */
211	error = i40e_aq_set_vsi_broadcast(hw, vf->vsi.seid, TRUE, NULL);
212	if (error)
213		device_printf(pf->dev, "Error configuring VF VSI for broadcast promiscuous\n");
214	/* Re-add VF's MAC/VLAN filters to its VSI */
215	ixl_reconfigure_filters(&vf->vsi);
216
217	return (0);
218}
219
220static void
221ixl_vf_map_vsi_queue(struct i40e_hw *hw, struct ixl_vf *vf, int qnum,
222    uint32_t val)
223{
224	uint32_t qtable;
225	int index, shift;
226
227	/*
228	 * Two queues are mapped in a single register, so we have to do some
229	 * gymnastics to convert the queue number into a register index and
230	 * shift.
231	 */
232	index = qnum / 2;
233	shift = (qnum % 2) * I40E_VSILAN_QTABLE_QINDEX_1_SHIFT;
234
235	qtable = i40e_read_rx_ctl(hw, I40E_VSILAN_QTABLE(index, vf->vsi.vsi_num));
236	qtable &= ~(I40E_VSILAN_QTABLE_QINDEX_0_MASK << shift);
237	qtable |= val << shift;
238	i40e_write_rx_ctl(hw, I40E_VSILAN_QTABLE(index, vf->vsi.vsi_num), qtable);
239}
240
241static void
242ixl_vf_map_queues(struct ixl_pf *pf, struct ixl_vf *vf)
243{
244	struct i40e_hw *hw;
245	uint32_t qtable;
246	int i;
247
248	hw = &pf->hw;
249
250	/*
251	 * Contiguous mappings aren't actually supported by the hardware,
252	 * so we have to use non-contiguous mappings.
253	 */
254	i40e_write_rx_ctl(hw, I40E_VSILAN_QBASE(vf->vsi.vsi_num),
255	     I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK);
256
257	/* Enable LAN traffic on this VF */
258	wr32(hw, I40E_VPLAN_MAPENA(vf->vf_num),
259	    I40E_VPLAN_MAPENA_TXRX_ENA_MASK);
260
261	/* Program index of each VF queue into PF queue space
262	 * (This is only needed if QTABLE is enabled) */
263	for (i = 0; i < vf->vsi.num_tx_queues; i++) {
264		qtable = ixl_pf_qidx_from_vsi_qidx(&vf->qtag, i) <<
265		    I40E_VPLAN_QTABLE_QINDEX_SHIFT;
266
267		wr32(hw, I40E_VPLAN_QTABLE(i, vf->vf_num), qtable);
268	}
269	for (; i < IXL_MAX_VSI_QUEUES; i++)
270		wr32(hw, I40E_VPLAN_QTABLE(i, vf->vf_num),
271		    I40E_VPLAN_QTABLE_QINDEX_MASK);
272
273	/* Map queues allocated to VF to its VSI;
274	 * This mapping matches the VF-wide mapping since the VF
275	 * is only given a single VSI */
276	for (i = 0; i < vf->vsi.num_tx_queues; i++)
277		ixl_vf_map_vsi_queue(hw, vf, i,
278		    ixl_pf_qidx_from_vsi_qidx(&vf->qtag, i));
279
280	/* Set rest of VSI queues as unused. */
281	for (; i < IXL_MAX_VSI_QUEUES; i++)
282		ixl_vf_map_vsi_queue(hw, vf, i,
283		    I40E_VSILAN_QTABLE_QINDEX_0_MASK);
284
285	ixl_flush(hw);
286}
287
288static void
289ixl_vf_vsi_release(struct ixl_pf *pf, struct ixl_vsi *vsi)
290{
291	struct i40e_hw *hw;
292
293	hw = &pf->hw;
294
295	if (vsi->seid == 0)
296		return;
297
298	i40e_aq_delete_element(hw, vsi->seid, NULL);
299}
300
301static void
302ixl_vf_disable_queue_intr(struct i40e_hw *hw, uint32_t vfint_reg)
303{
304
305	wr32(hw, vfint_reg, I40E_VFINT_DYN_CTLN_CLEARPBA_MASK);
306	ixl_flush(hw);
307}
308
309static void
310ixl_vf_unregister_intr(struct i40e_hw *hw, uint32_t vpint_reg)
311{
312
313	wr32(hw, vpint_reg, I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_MASK |
314	    I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK);
315	ixl_flush(hw);
316}
317
318static void
319ixl_vf_release_resources(struct ixl_pf *pf, struct ixl_vf *vf)
320{
321	struct i40e_hw *hw;
322	uint32_t vfint_reg, vpint_reg;
323	int i;
324
325	hw = &pf->hw;
326
327	ixl_vf_vsi_release(pf, &vf->vsi);
328
329	/* Index 0 has a special register. */
330	ixl_vf_disable_queue_intr(hw, I40E_VFINT_DYN_CTL0(vf->vf_num));
331
332	for (i = 1; i < hw->func_caps.num_msix_vectors_vf; i++) {
333		vfint_reg = IXL_VFINT_DYN_CTLN_REG(hw, i , vf->vf_num);
334		ixl_vf_disable_queue_intr(hw, vfint_reg);
335	}
336
337	/* Index 0 has a special register. */
338	ixl_vf_unregister_intr(hw, I40E_VPINT_LNKLST0(vf->vf_num));
339
340	for (i = 1; i < hw->func_caps.num_msix_vectors_vf; i++) {
341		vpint_reg = IXL_VPINT_LNKLSTN_REG(hw, i, vf->vf_num);
342		ixl_vf_unregister_intr(hw, vpint_reg);
343	}
344
345	vf->vsi.num_tx_queues = 0;
346	vf->vsi.num_rx_queues = 0;
347}
348
349static int
350ixl_flush_pcie(struct ixl_pf *pf, struct ixl_vf *vf)
351{
352	struct i40e_hw *hw;
353	int i;
354	uint16_t global_vf_num;
355	uint32_t ciad;
356
357	hw = &pf->hw;
358	global_vf_num = hw->func_caps.vf_base_id + vf->vf_num;
359
360	wr32(hw, I40E_PF_PCI_CIAA, IXL_PF_PCI_CIAA_VF_DEVICE_STATUS |
361	     (global_vf_num << I40E_PF_PCI_CIAA_VF_NUM_SHIFT));
362	for (i = 0; i < IXL_VF_RESET_TIMEOUT; i++) {
363		ciad = rd32(hw, I40E_PF_PCI_CIAD);
364		if ((ciad & IXL_PF_PCI_CIAD_VF_TRANS_PENDING_MASK) == 0)
365			return (0);
366		DELAY(1);
367	}
368
369	return (ETIMEDOUT);
370}
371
372static void
373ixl_reset_vf(struct ixl_pf *pf, struct ixl_vf *vf)
374{
375	struct i40e_hw *hw;
376	uint32_t vfrtrig;
377
378	hw = &pf->hw;
379
380	ixl_dbg_iov(pf, "Resetting VF-%d\n", vf->vf_num);
381
382	vfrtrig = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_num));
383	vfrtrig |= I40E_VPGEN_VFRTRIG_VFSWR_MASK;
384	wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_num), vfrtrig);
385	ixl_flush(hw);
386
387	ixl_reinit_vf(pf, vf);
388
389	ixl_dbg_iov(pf, "Resetting VF-%d done.\n", vf->vf_num);
390}
391
392static void
393ixl_reinit_vf(struct ixl_pf *pf, struct ixl_vf *vf)
394{
395	struct i40e_hw *hw;
396	uint32_t vfrstat, vfrtrig;
397	int i, error;
398
399	hw = &pf->hw;
400
401	error = ixl_flush_pcie(pf, vf);
402	if (error != 0)
403		device_printf(pf->dev,
404		    "Timed out waiting for PCIe activity to stop on VF-%d\n",
405		    vf->vf_num);
406
407	for (i = 0; i < IXL_VF_RESET_TIMEOUT; i++) {
408		DELAY(10);
409
410		vfrstat = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_num));
411		if (vfrstat & I40E_VPGEN_VFRSTAT_VFRD_MASK)
412			break;
413	}
414
415	if (i == IXL_VF_RESET_TIMEOUT)
416		device_printf(pf->dev, "VF %d failed to reset\n", vf->vf_num);
417
418	wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_num), VIRTCHNL_VFR_COMPLETED);
419
420	vfrtrig = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_num));
421	vfrtrig &= ~I40E_VPGEN_VFRTRIG_VFSWR_MASK;
422	wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_num), vfrtrig);
423
424	if (vf->vsi.seid != 0)
425		ixl_disable_rings(pf, &vf->vsi, &vf->qtag);
426	ixl_pf_qmgr_clear_queue_flags(&vf->qtag);
427
428	ixl_vf_release_resources(pf, vf);
429	ixl_vf_setup_vsi(pf, vf);
430	ixl_vf_map_queues(pf, vf);
431
432	wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_num), VIRTCHNL_VFR_VFACTIVE);
433	ixl_flush(hw);
434}
435
436static int
437ixl_vc_opcode_level(uint16_t opcode)
438{
439	switch (opcode) {
440	case VIRTCHNL_OP_GET_STATS:
441		return (10);
442	default:
443		return (5);
444	}
445}
446
447static void
448ixl_send_vf_msg(struct ixl_pf *pf, struct ixl_vf *vf, uint16_t op,
449    enum i40e_status_code status, void *msg, uint16_t len)
450{
451	struct i40e_hw *hw;
452	int global_vf_id;
453
454	hw = &pf->hw;
455	global_vf_id = hw->func_caps.vf_base_id + vf->vf_num;
456
457	I40E_VC_DEBUG(pf, ixl_vc_opcode_level(op),
458	    "Sending msg (op=%s[%d], status=%d) to VF-%d\n",
459	    ixl_vc_opcode_str(op), op, status, vf->vf_num);
460
461	i40e_aq_send_msg_to_vf(hw, global_vf_id, op, status, msg, len, NULL);
462}
463
464static void
465ixl_send_vf_ack(struct ixl_pf *pf, struct ixl_vf *vf, uint16_t op)
466{
467
468	ixl_send_vf_msg(pf, vf, op, I40E_SUCCESS, NULL, 0);
469}
470
471static void
472ixl_send_vf_nack_msg(struct ixl_pf *pf, struct ixl_vf *vf, uint16_t op,
473    enum i40e_status_code status, const char *file, int line)
474{
475
476	I40E_VC_DEBUG(pf, 1,
477	    "Sending NACK (op=%s[%d], err=%s[%d]) to VF-%d from %s:%d\n",
478	    ixl_vc_opcode_str(op), op, i40e_stat_str(&pf->hw, status),
479	    status, vf->vf_num, file, line);
480	ixl_send_vf_msg(pf, vf, op, status, NULL, 0);
481}
482
483static void
484ixl_vf_version_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
485    uint16_t msg_size)
486{
487	struct virtchnl_version_info *recv_vf_version;
488	device_t dev = pf->dev;
489
490	recv_vf_version = (struct virtchnl_version_info *)msg;
491
492	/* VFs running the 1.0 API expect to get 1.0 back */
493	if (VF_IS_V10(recv_vf_version)) {
494		vf->version.major = 1;
495		vf->version.minor = VIRTCHNL_VERSION_MINOR_NO_VF_CAPS;
496	} else {
497		vf->version.major = VIRTCHNL_VERSION_MAJOR;
498		vf->version.minor = VIRTCHNL_VERSION_MINOR;
499
500		if ((recv_vf_version->major != VIRTCHNL_VERSION_MAJOR) ||
501		    (recv_vf_version->minor != VIRTCHNL_VERSION_MINOR))
502		    device_printf(dev,
503		        "%s: VF-%d requested version (%d.%d) differs from PF version (%d.%d)\n",
504			__func__, vf->vf_num,
505			recv_vf_version->major, recv_vf_version->minor,
506			VIRTCHNL_VERSION_MAJOR, VIRTCHNL_VERSION_MINOR);
507	}
508
509	ixl_send_vf_msg(pf, vf, VIRTCHNL_OP_VERSION, I40E_SUCCESS,
510	    &vf->version, sizeof(vf->version));
511}
512
513static void
514ixl_vf_reset_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
515    uint16_t msg_size)
516{
517	ixl_reset_vf(pf, vf);
518
519	/* No response to a reset message. */
520}
521
522static void
523ixl_vf_get_resources_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
524    uint16_t msg_size)
525{
526	struct virtchnl_vf_resource reply;
527
528	bzero(&reply, sizeof(reply));
529
530	if (vf->version.minor == VIRTCHNL_VERSION_MINOR_NO_VF_CAPS)
531		reply.vf_cap_flags = VIRTCHNL_VF_OFFLOAD_L2 |
532					 VIRTCHNL_VF_OFFLOAD_RSS_REG |
533					 VIRTCHNL_VF_OFFLOAD_VLAN;
534	else
535		/* Force VF RSS setup by PF in 1.1+ VFs */
536		reply.vf_cap_flags = *(u32 *)msg & (
537					 VIRTCHNL_VF_OFFLOAD_L2 |
538					 VIRTCHNL_VF_OFFLOAD_RSS_PF |
539					 VIRTCHNL_VF_OFFLOAD_VLAN);
540
541	reply.num_vsis = 1;
542	reply.num_queue_pairs = vf->vsi.num_tx_queues;
543	reply.max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
544	reply.rss_key_size = 52;
545	reply.rss_lut_size = 64;
546	reply.vsi_res[0].vsi_id = vf->vsi.vsi_num;
547	reply.vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV;
548	reply.vsi_res[0].num_queue_pairs = vf->vsi.num_tx_queues;
549	memcpy(reply.vsi_res[0].default_mac_addr, vf->mac, ETHER_ADDR_LEN);
550
551	ixl_send_vf_msg(pf, vf, VIRTCHNL_OP_GET_VF_RESOURCES,
552	    I40E_SUCCESS, &reply, sizeof(reply));
553}
554
555static int
556ixl_vf_config_tx_queue(struct ixl_pf *pf, struct ixl_vf *vf,
557    struct virtchnl_txq_info *info)
558{
559	struct i40e_hw *hw;
560	struct i40e_hmc_obj_txq txq;
561	uint16_t global_queue_num, global_vf_num;
562	enum i40e_status_code status;
563	uint32_t qtx_ctl;
564
565	hw = &pf->hw;
566	global_queue_num = ixl_pf_qidx_from_vsi_qidx(&vf->qtag, info->queue_id);
567	global_vf_num = hw->func_caps.vf_base_id + vf->vf_num;
568	bzero(&txq, sizeof(txq));
569
570	DDPRINTF(pf->dev, "VF %d: PF TX queue %d / VF TX queue %d (Global VF %d)\n",
571	    vf->vf_num, global_queue_num, info->queue_id, global_vf_num);
572
573	status = i40e_clear_lan_tx_queue_context(hw, global_queue_num);
574	if (status != I40E_SUCCESS)
575		return (EINVAL);
576
577	txq.base = info->dma_ring_addr / IXL_TX_CTX_BASE_UNITS;
578
579	txq.head_wb_ena = info->headwb_enabled;
580	txq.head_wb_addr = info->dma_headwb_addr;
581	txq.qlen = info->ring_len;
582	txq.rdylist = le16_to_cpu(vf->vsi.info.qs_handle[0]);
583	txq.rdylist_act = 0;
584
585	status = i40e_set_lan_tx_queue_context(hw, global_queue_num, &txq);
586	if (status != I40E_SUCCESS)
587		return (EINVAL);
588
589	qtx_ctl = I40E_QTX_CTL_VF_QUEUE |
590	    (hw->pf_id << I40E_QTX_CTL_PF_INDX_SHIFT) |
591	    (global_vf_num << I40E_QTX_CTL_VFVM_INDX_SHIFT);
592	wr32(hw, I40E_QTX_CTL(global_queue_num), qtx_ctl);
593	ixl_flush(hw);
594
595	ixl_pf_qmgr_mark_queue_configured(&vf->qtag, info->queue_id, true);
596
597	return (0);
598}
599
600static int
601ixl_vf_config_rx_queue(struct ixl_pf *pf, struct ixl_vf *vf,
602    struct virtchnl_rxq_info *info)
603{
604	struct i40e_hw *hw;
605	struct i40e_hmc_obj_rxq rxq;
606	uint16_t global_queue_num;
607	enum i40e_status_code status;
608
609	hw = &pf->hw;
610	global_queue_num = ixl_pf_qidx_from_vsi_qidx(&vf->qtag, info->queue_id);
611	bzero(&rxq, sizeof(rxq));
612
613	DDPRINTF(pf->dev, "VF %d: PF RX queue %d / VF RX queue %d\n",
614	    vf->vf_num, global_queue_num, info->queue_id);
615
616	if (info->databuffer_size > IXL_VF_MAX_BUFFER)
617		return (EINVAL);
618
619	if (info->max_pkt_size > IXL_VF_MAX_FRAME ||
620	    info->max_pkt_size < ETHER_MIN_LEN)
621		return (EINVAL);
622
623	if (info->splithdr_enabled) {
624		if (info->hdr_size > IXL_VF_MAX_HDR_BUFFER)
625			return (EINVAL);
626
627		rxq.hsplit_0 = info->rx_split_pos &
628		    (I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_L2 |
629		     I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_IP |
630		     I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_TCP_UDP |
631		     I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_SCTP);
632		rxq.hbuff = info->hdr_size >> I40E_RXQ_CTX_HBUFF_SHIFT;
633
634		rxq.dtype = 2;
635	}
636
637	status = i40e_clear_lan_rx_queue_context(hw, global_queue_num);
638	if (status != I40E_SUCCESS)
639		return (EINVAL);
640
641	rxq.base = info->dma_ring_addr / IXL_RX_CTX_BASE_UNITS;
642	rxq.qlen = info->ring_len;
643
644	rxq.dbuff = info->databuffer_size >> I40E_RXQ_CTX_DBUFF_SHIFT;
645
646	rxq.dsize = 1;
647	rxq.crcstrip = 1;
648	rxq.l2tsel = 1;
649
650	rxq.rxmax = info->max_pkt_size;
651	rxq.tphrdesc_ena = 1;
652	rxq.tphwdesc_ena = 1;
653	rxq.tphdata_ena = 1;
654	rxq.tphhead_ena = 1;
655	rxq.lrxqthresh = 1;
656	rxq.prefena = 1;
657
658	status = i40e_set_lan_rx_queue_context(hw, global_queue_num, &rxq);
659	if (status != I40E_SUCCESS)
660		return (EINVAL);
661
662	ixl_pf_qmgr_mark_queue_configured(&vf->qtag, info->queue_id, false);
663
664	return (0);
665}
666
667static void
668ixl_vf_config_vsi_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
669    uint16_t msg_size)
670{
671	struct virtchnl_vsi_queue_config_info *info;
672	struct virtchnl_queue_pair_info *pair;
673	int i;
674
675	info = msg;
676	if (info->num_queue_pairs == 0 || info->num_queue_pairs > vf->vsi.num_tx_queues) {
677		device_printf(pf->dev, "VF %d: invalid # of qpairs (msg has %d, VSI has %d)\n",
678		    vf->vf_num, info->num_queue_pairs, vf->vsi.num_tx_queues);
679		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
680		    I40E_ERR_PARAM);
681		return;
682	}
683
684	if (info->vsi_id != vf->vsi.vsi_num) {
685		device_printf(pf->dev, "VF %d: VSI id in recvd message (%d) does not match expected id (%d)\n",
686		    vf->vf_num, info->vsi_id, vf->vsi.vsi_num);
687		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
688		    I40E_ERR_PARAM);
689		return;
690	}
691
692	for (i = 0; i < info->num_queue_pairs; i++) {
693		pair = &info->qpair[i];
694
695		if (pair->txq.vsi_id != vf->vsi.vsi_num ||
696		    pair->rxq.vsi_id != vf->vsi.vsi_num ||
697		    pair->txq.queue_id != pair->rxq.queue_id ||
698		    pair->txq.queue_id >= vf->vsi.num_tx_queues) {
699
700			i40e_send_vf_nack(pf, vf,
701			    VIRTCHNL_OP_CONFIG_VSI_QUEUES, I40E_ERR_PARAM);
702			return;
703		}
704
705		if (ixl_vf_config_tx_queue(pf, vf, &pair->txq) != 0) {
706			i40e_send_vf_nack(pf, vf,
707			    VIRTCHNL_OP_CONFIG_VSI_QUEUES, I40E_ERR_PARAM);
708			return;
709		}
710
711		if (ixl_vf_config_rx_queue(pf, vf, &pair->rxq) != 0) {
712			i40e_send_vf_nack(pf, vf,
713			    VIRTCHNL_OP_CONFIG_VSI_QUEUES, I40E_ERR_PARAM);
714			return;
715		}
716	}
717
718	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES);
719}
720
721static void
722ixl_vf_set_qctl(struct ixl_pf *pf,
723    const struct virtchnl_vector_map *vector,
724    enum i40e_queue_type cur_type, uint16_t cur_queue,
725    enum i40e_queue_type *last_type, uint16_t *last_queue)
726{
727	uint32_t offset, qctl;
728	uint16_t itr_indx;
729
730	if (cur_type == I40E_QUEUE_TYPE_RX) {
731		offset = I40E_QINT_RQCTL(cur_queue);
732		itr_indx = vector->rxitr_idx;
733	} else {
734		offset = I40E_QINT_TQCTL(cur_queue);
735		itr_indx = vector->txitr_idx;
736	}
737
738	qctl = htole32((vector->vector_id << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) |
739	    (*last_type << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) |
740	    (*last_queue << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) |
741	    I40E_QINT_RQCTL_CAUSE_ENA_MASK |
742	    (itr_indx << I40E_QINT_RQCTL_ITR_INDX_SHIFT));
743
744	wr32(&pf->hw, offset, qctl);
745
746	*last_type = cur_type;
747	*last_queue = cur_queue;
748}
749
750static void
751ixl_vf_config_vector(struct ixl_pf *pf, struct ixl_vf *vf,
752    const struct virtchnl_vector_map *vector)
753{
754	struct i40e_hw *hw;
755	u_int qindex;
756	enum i40e_queue_type type, last_type;
757	uint32_t lnklst_reg;
758	uint16_t rxq_map, txq_map, cur_queue, last_queue;
759
760	hw = &pf->hw;
761
762	rxq_map = vector->rxq_map;
763	txq_map = vector->txq_map;
764
765	last_queue = IXL_END_OF_INTR_LNKLST;
766	last_type = I40E_QUEUE_TYPE_RX;
767
768	/*
769	 * The datasheet says to optimize performance, RX queues and TX queues
770	 * should be interleaved in the interrupt linked list, so we process
771	 * both at once here.
772	 */
773	while ((rxq_map != 0) || (txq_map != 0)) {
774		if (txq_map != 0) {
775			qindex = ffs(txq_map) - 1;
776			type = I40E_QUEUE_TYPE_TX;
777			cur_queue = ixl_pf_qidx_from_vsi_qidx(&vf->qtag, qindex);
778			ixl_vf_set_qctl(pf, vector, type, cur_queue,
779			    &last_type, &last_queue);
780			txq_map &= ~(1 << qindex);
781		}
782
783		if (rxq_map != 0) {
784			qindex = ffs(rxq_map) - 1;
785			type = I40E_QUEUE_TYPE_RX;
786			cur_queue = ixl_pf_qidx_from_vsi_qidx(&vf->qtag, qindex);
787			ixl_vf_set_qctl(pf, vector, type, cur_queue,
788			    &last_type, &last_queue);
789			rxq_map &= ~(1 << qindex);
790		}
791	}
792
793	if (vector->vector_id == 0)
794		lnklst_reg = I40E_VPINT_LNKLST0(vf->vf_num);
795	else
796		lnklst_reg = IXL_VPINT_LNKLSTN_REG(hw, vector->vector_id,
797		    vf->vf_num);
798	wr32(hw, lnklst_reg,
799	    (last_queue << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT) |
800	    (last_type << I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT));
801
802	ixl_flush(hw);
803}
804
805static void
806ixl_vf_config_irq_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
807    uint16_t msg_size)
808{
809	struct virtchnl_irq_map_info *map;
810	struct virtchnl_vector_map *vector;
811	struct i40e_hw *hw;
812	int i, largest_txq, largest_rxq;
813
814	hw = &pf->hw;
815	map = msg;
816
817	for (i = 0; i < map->num_vectors; i++) {
818		vector = &map->vecmap[i];
819
820		if ((vector->vector_id >= hw->func_caps.num_msix_vectors_vf) ||
821		    vector->vsi_id != vf->vsi.vsi_num) {
822			i40e_send_vf_nack(pf, vf,
823			    VIRTCHNL_OP_CONFIG_IRQ_MAP, I40E_ERR_PARAM);
824			return;
825		}
826
827		if (vector->rxq_map != 0) {
828			largest_rxq = fls(vector->rxq_map) - 1;
829			if (largest_rxq >= vf->vsi.num_rx_queues) {
830				i40e_send_vf_nack(pf, vf,
831				    VIRTCHNL_OP_CONFIG_IRQ_MAP,
832				    I40E_ERR_PARAM);
833				return;
834			}
835		}
836
837		if (vector->txq_map != 0) {
838			largest_txq = fls(vector->txq_map) - 1;
839			if (largest_txq >= vf->vsi.num_tx_queues) {
840				i40e_send_vf_nack(pf, vf,
841				    VIRTCHNL_OP_CONFIG_IRQ_MAP,
842				    I40E_ERR_PARAM);
843				return;
844			}
845		}
846
847		if (vector->rxitr_idx > IXL_MAX_ITR_IDX ||
848		    vector->txitr_idx > IXL_MAX_ITR_IDX) {
849			i40e_send_vf_nack(pf, vf,
850			    VIRTCHNL_OP_CONFIG_IRQ_MAP,
851			    I40E_ERR_PARAM);
852			return;
853		}
854
855		ixl_vf_config_vector(pf, vf, vector);
856	}
857
858	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_CONFIG_IRQ_MAP);
859}
860
861static void
862ixl_vf_enable_queues_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
863    uint16_t msg_size)
864{
865	struct virtchnl_queue_select *select;
866	int error = 0;
867
868	select = msg;
869
870	if (select->vsi_id != vf->vsi.vsi_num ||
871	    select->rx_queues == 0 || select->tx_queues == 0) {
872		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ENABLE_QUEUES,
873		    I40E_ERR_PARAM);
874		return;
875	}
876
877	/* Enable TX rings selected by the VF */
878	for (int i = 0; i < 32; i++) {
879		if ((1 << i) & select->tx_queues) {
880			/* Warn if queue is out of VF allocation range */
881			if (i >= vf->vsi.num_tx_queues) {
882				device_printf(pf->dev, "VF %d: TX ring %d is outside of VF VSI allocation!\n",
883				    vf->vf_num, i);
884				break;
885			}
886			/* Skip this queue if it hasn't been configured */
887			if (!ixl_pf_qmgr_is_queue_configured(&vf->qtag, i, true))
888				continue;
889			/* Warn if this queue is already marked as enabled */
890			if (ixl_pf_qmgr_is_queue_enabled(&vf->qtag, i, true))
891				ixl_dbg_iov(pf, "VF %d: TX ring %d is already enabled!\n",
892				    vf->vf_num, i);
893
894			error = ixl_enable_tx_ring(pf, &vf->qtag, i);
895			if (error)
896				break;
897			else
898				ixl_pf_qmgr_mark_queue_enabled(&vf->qtag, i, true);
899		}
900	}
901
902	/* Enable RX rings selected by the VF */
903	for (int i = 0; i < 32; i++) {
904		if ((1 << i) & select->rx_queues) {
905			/* Warn if queue is out of VF allocation range */
906			if (i >= vf->vsi.num_rx_queues) {
907				device_printf(pf->dev, "VF %d: RX ring %d is outside of VF VSI allocation!\n",
908				    vf->vf_num, i);
909				break;
910			}
911			/* Skip this queue if it hasn't been configured */
912			if (!ixl_pf_qmgr_is_queue_configured(&vf->qtag, i, false))
913				continue;
914			/* Warn if this queue is already marked as enabled */
915			if (ixl_pf_qmgr_is_queue_enabled(&vf->qtag, i, false))
916				ixl_dbg_iov(pf, "VF %d: RX ring %d is already enabled!\n",
917				    vf->vf_num, i);
918			error = ixl_enable_rx_ring(pf, &vf->qtag, i);
919			if (error)
920				break;
921			else
922				ixl_pf_qmgr_mark_queue_enabled(&vf->qtag, i, false);
923		}
924	}
925
926	if (error) {
927		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ENABLE_QUEUES,
928		    I40E_ERR_TIMEOUT);
929		return;
930	}
931
932	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_ENABLE_QUEUES);
933}
934
935static void
936ixl_vf_disable_queues_msg(struct ixl_pf *pf, struct ixl_vf *vf,
937    void *msg, uint16_t msg_size)
938{
939	struct virtchnl_queue_select *select;
940	int error = 0;
941
942	select = msg;
943
944	if (select->vsi_id != vf->vsi.vsi_num ||
945	    select->rx_queues == 0 || select->tx_queues == 0) {
946		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_DISABLE_QUEUES,
947		    I40E_ERR_PARAM);
948		return;
949	}
950
951	/* Disable TX rings selected by the VF */
952	for (int i = 0; i < 32; i++) {
953		if ((1 << i) & select->tx_queues) {
954			/* Warn if queue is out of VF allocation range */
955			if (i >= vf->vsi.num_tx_queues) {
956				device_printf(pf->dev, "VF %d: TX ring %d is outside of VF VSI allocation!\n",
957				    vf->vf_num, i);
958				break;
959			}
960			/* Skip this queue if it hasn't been configured */
961			if (!ixl_pf_qmgr_is_queue_configured(&vf->qtag, i, true))
962				continue;
963			/* Warn if this queue is already marked as disabled */
964			if (!ixl_pf_qmgr_is_queue_enabled(&vf->qtag, i, true)) {
965				ixl_dbg_iov(pf, "VF %d: TX ring %d is already disabled!\n",
966				    vf->vf_num, i);
967				continue;
968			}
969			error = ixl_disable_tx_ring(pf, &vf->qtag, i);
970			if (error)
971				break;
972			else
973				ixl_pf_qmgr_mark_queue_disabled(&vf->qtag, i, true);
974		}
975	}
976
977	/* Enable RX rings selected by the VF */
978	for (int i = 0; i < 32; i++) {
979		if ((1 << i) & select->rx_queues) {
980			/* Warn if queue is out of VF allocation range */
981			if (i >= vf->vsi.num_rx_queues) {
982				device_printf(pf->dev, "VF %d: RX ring %d is outside of VF VSI allocation!\n",
983				    vf->vf_num, i);
984				break;
985			}
986			/* Skip this queue if it hasn't been configured */
987			if (!ixl_pf_qmgr_is_queue_configured(&vf->qtag, i, false))
988				continue;
989			/* Warn if this queue is already marked as disabled */
990			if (!ixl_pf_qmgr_is_queue_enabled(&vf->qtag, i, false)) {
991				ixl_dbg_iov(pf, "VF %d: RX ring %d is already disabled!\n",
992				    vf->vf_num, i);
993				continue;
994			}
995			error = ixl_disable_rx_ring(pf, &vf->qtag, i);
996			if (error)
997				break;
998			else
999				ixl_pf_qmgr_mark_queue_disabled(&vf->qtag, i, false);
1000		}
1001	}
1002
1003	if (error) {
1004		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_DISABLE_QUEUES,
1005		    I40E_ERR_TIMEOUT);
1006		return;
1007	}
1008
1009	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_DISABLE_QUEUES);
1010}
1011
1012static int
1013ixl_vf_mac_valid(struct ixl_vf *vf, const uint8_t *addr)
1014{
1015
1016	if (ETHER_IS_ZERO(addr) || ETHER_IS_BROADCAST(addr))
1017		return (EINVAL);
1018
1019	/*
1020	 * If the VF is not allowed to change its MAC address, don't let it
1021	 * set a MAC filter for an address that is not a multicast address and
1022	 * is not its assigned MAC.
1023	 */
1024	if (!(vf->vf_flags & VF_FLAG_SET_MAC_CAP) &&
1025	    !(ETHER_IS_MULTICAST(addr) || !ixl_ether_is_equal(addr, vf->mac)))
1026		return (EPERM);
1027
1028	return (0);
1029}
1030
1031static void
1032ixl_vf_add_mac_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1033    uint16_t msg_size)
1034{
1035	struct virtchnl_ether_addr_list *addr_list;
1036	struct virtchnl_ether_addr *addr;
1037	struct ixl_vsi *vsi;
1038	int i;
1039
1040	vsi = &vf->vsi;
1041	addr_list = msg;
1042
1043	if (addr_list->vsi_id != vsi->vsi_num) {
1044		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_ETH_ADDR,
1045		    I40E_ERR_PARAM);
1046		return;
1047	}
1048
1049	for (i = 0; i < addr_list->num_elements; i++) {
1050		if (ixl_vf_mac_valid(vf, addr_list->list[i].addr) != 0) {
1051			i40e_send_vf_nack(pf, vf,
1052			    VIRTCHNL_OP_ADD_ETH_ADDR, I40E_ERR_PARAM);
1053			return;
1054		}
1055	}
1056
1057	for (i = 0; i < addr_list->num_elements; i++) {
1058		addr = &addr_list->list[i];
1059		ixl_add_filter(vsi, addr->addr, IXL_VLAN_ANY);
1060	}
1061
1062	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_ADD_ETH_ADDR);
1063}
1064
1065static void
1066ixl_vf_del_mac_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1067    uint16_t msg_size)
1068{
1069	struct virtchnl_ether_addr_list *addr_list;
1070	struct virtchnl_ether_addr *addr;
1071	struct ixl_vsi *vsi;
1072	int i;
1073
1074	vsi = &vf->vsi;
1075	addr_list = msg;
1076
1077	if (addr_list->vsi_id != vsi->vsi_num) {
1078		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_DEL_ETH_ADDR,
1079		    I40E_ERR_PARAM);
1080		return;
1081	}
1082
1083	for (i = 0; i < addr_list->num_elements; i++) {
1084		addr = &addr_list->list[i];
1085		if (ETHER_IS_ZERO(addr->addr) || ETHER_IS_BROADCAST(addr->addr)) {
1086			i40e_send_vf_nack(pf, vf,
1087			    VIRTCHNL_OP_DEL_ETH_ADDR, I40E_ERR_PARAM);
1088			return;
1089		}
1090	}
1091
1092	for (i = 0; i < addr_list->num_elements; i++) {
1093		addr = &addr_list->list[i];
1094		ixl_del_filter(&vf->vsi, addr->addr, IXL_VLAN_ANY);
1095	}
1096
1097	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_DEL_ETH_ADDR);
1098}
1099
1100static enum i40e_status_code
1101ixl_vf_enable_vlan_strip(struct ixl_pf *pf, struct ixl_vf *vf)
1102{
1103	struct i40e_vsi_context vsi_ctx;
1104
1105	vsi_ctx.seid = vf->vsi.seid;
1106
1107	bzero(&vsi_ctx.info, sizeof(vsi_ctx.info));
1108	vsi_ctx.info.valid_sections = htole16(I40E_AQ_VSI_PROP_VLAN_VALID);
1109	vsi_ctx.info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_ALL |
1110	    I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH;
1111	return (i40e_aq_update_vsi_params(&pf->hw, &vsi_ctx, NULL));
1112}
1113
1114static void
1115ixl_vf_add_vlan_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1116    uint16_t msg_size)
1117{
1118	struct virtchnl_vlan_filter_list *filter_list;
1119	enum i40e_status_code code;
1120	int i;
1121
1122	filter_list = msg;
1123
1124	if (filter_list->vsi_id != vf->vsi.vsi_num) {
1125		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_VLAN,
1126		    I40E_ERR_PARAM);
1127		return;
1128	}
1129
1130	if (!(vf->vf_flags & VF_FLAG_VLAN_CAP)) {
1131		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_VLAN,
1132		    I40E_ERR_PARAM);
1133		return;
1134	}
1135
1136	for (i = 0; i < filter_list->num_elements; i++) {
1137		if (filter_list->vlan_id[i] > EVL_VLID_MASK) {
1138			i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_VLAN,
1139			    I40E_ERR_PARAM);
1140			return;
1141		}
1142	}
1143
1144	code = ixl_vf_enable_vlan_strip(pf, vf);
1145	if (code != I40E_SUCCESS) {
1146		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_VLAN,
1147		    I40E_ERR_PARAM);
1148	}
1149
1150	for (i = 0; i < filter_list->num_elements; i++)
1151		ixl_add_filter(&vf->vsi, vf->mac, filter_list->vlan_id[i]);
1152
1153	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_ADD_VLAN);
1154}
1155
1156static void
1157ixl_vf_del_vlan_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1158    uint16_t msg_size)
1159{
1160	struct virtchnl_vlan_filter_list *filter_list;
1161	int i;
1162
1163	filter_list = msg;
1164
1165	if (filter_list->vsi_id != vf->vsi.vsi_num) {
1166		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_DEL_VLAN,
1167		    I40E_ERR_PARAM);
1168		return;
1169	}
1170
1171	for (i = 0; i < filter_list->num_elements; i++) {
1172		if (filter_list->vlan_id[i] > EVL_VLID_MASK) {
1173			i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_VLAN,
1174			    I40E_ERR_PARAM);
1175			return;
1176		}
1177	}
1178
1179	if (!(vf->vf_flags & VF_FLAG_VLAN_CAP)) {
1180		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_ADD_VLAN,
1181		    I40E_ERR_PARAM);
1182		return;
1183	}
1184
1185	for (i = 0; i < filter_list->num_elements; i++)
1186		ixl_del_filter(&vf->vsi, vf->mac, filter_list->vlan_id[i]);
1187
1188	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_DEL_VLAN);
1189}
1190
1191static void
1192ixl_vf_config_promisc_msg(struct ixl_pf *pf, struct ixl_vf *vf,
1193    void *msg, uint16_t msg_size)
1194{
1195	struct virtchnl_promisc_info *info;
1196	struct i40e_hw *hw = &pf->hw;
1197	enum i40e_status_code code;
1198
1199	if (!(vf->vf_flags & VF_FLAG_PROMISC_CAP)) {
1200		/*
1201		 * Do the same thing as the Linux PF driver -- lie to the VF
1202		 */
1203		ixl_send_vf_ack(pf, vf,
1204		    VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE);
1205		return;
1206	}
1207
1208	info = msg;
1209	if (info->vsi_id != vf->vsi.vsi_num) {
1210		i40e_send_vf_nack(pf, vf,
1211		    VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, I40E_ERR_PARAM);
1212		return;
1213	}
1214
1215	code = i40e_aq_set_vsi_unicast_promiscuous(hw, vf->vsi.seid,
1216	    info->flags & FLAG_VF_UNICAST_PROMISC, NULL, TRUE);
1217	if (code != I40E_SUCCESS) {
1218		device_printf(pf->dev, "i40e_aq_set_vsi_unicast_promiscuous (seid %d) failed: status %s,"
1219		    " error %s\n", vf->vsi.seid, i40e_stat_str(hw, code),
1220		    i40e_aq_str(hw, hw->aq.asq_last_status));
1221		i40e_send_vf_nack(pf, vf,
1222		    VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, I40E_ERR_PARAM);
1223		return;
1224	}
1225
1226	code = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi.seid,
1227	    info->flags & FLAG_VF_MULTICAST_PROMISC, NULL);
1228	if (code != I40E_SUCCESS) {
1229		device_printf(pf->dev, "i40e_aq_set_vsi_multicast_promiscuous (seid %d) failed: status %s,"
1230		    " error %s\n", vf->vsi.seid, i40e_stat_str(hw, code),
1231		    i40e_aq_str(hw, hw->aq.asq_last_status));
1232		i40e_send_vf_nack(pf, vf,
1233		    VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, I40E_ERR_PARAM);
1234		return;
1235	}
1236
1237	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE);
1238}
1239
1240static void
1241ixl_vf_get_stats_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1242    uint16_t msg_size)
1243{
1244	struct virtchnl_queue_select *queue;
1245
1246	queue = msg;
1247	if (queue->vsi_id != vf->vsi.vsi_num) {
1248		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_GET_STATS,
1249		    I40E_ERR_PARAM);
1250		return;
1251	}
1252
1253	ixl_update_eth_stats(&vf->vsi);
1254
1255	ixl_send_vf_msg(pf, vf, VIRTCHNL_OP_GET_STATS,
1256	    I40E_SUCCESS, &vf->vsi.eth_stats, sizeof(vf->vsi.eth_stats));
1257}
1258
1259static void
1260ixl_vf_config_rss_key_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1261    uint16_t msg_size)
1262{
1263	struct i40e_hw *hw;
1264	struct virtchnl_rss_key *key;
1265	struct i40e_aqc_get_set_rss_key_data key_data;
1266	enum i40e_status_code status;
1267
1268	hw = &pf->hw;
1269
1270	key = msg;
1271
1272	if (key->key_len > 52) {
1273		device_printf(pf->dev, "VF %d: Key size in msg (%d) is greater than max key size (%d)\n",
1274		    vf->vf_num, key->key_len, 52);
1275		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_KEY,
1276		    I40E_ERR_PARAM);
1277		return;
1278	}
1279
1280	if (key->vsi_id != vf->vsi.vsi_num) {
1281		device_printf(pf->dev, "VF %d: VSI id in recvd message (%d) does not match expected id (%d)\n",
1282		    vf->vf_num, key->vsi_id, vf->vsi.vsi_num);
1283		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_KEY,
1284		    I40E_ERR_PARAM);
1285		return;
1286	}
1287
1288	/* Fill out hash using MAC-dependent method */
1289	if (hw->mac.type == I40E_MAC_X722) {
1290		bzero(&key_data, sizeof(key_data));
1291		if (key->key_len <= 40)
1292			bcopy(key->key, key_data.standard_rss_key, key->key_len);
1293		else {
1294			bcopy(key->key, key_data.standard_rss_key, 40);
1295			bcopy(&key->key[40], key_data.extended_hash_key, key->key_len - 40);
1296		}
1297		status = i40e_aq_set_rss_key(hw, vf->vsi.vsi_num, &key_data);
1298		if (status) {
1299			device_printf(pf->dev, "i40e_aq_set_rss_key status %s, error %s\n",
1300			    i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
1301			i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_KEY,
1302			    I40E_ERR_ADMIN_QUEUE_ERROR);
1303			return;
1304		}
1305	} else {
1306		for (int i = 0; i < (key->key_len / 4); i++)
1307			i40e_write_rx_ctl(hw, I40E_VFQF_HKEY1(i, vf->vf_num), ((u32 *)key->key)[i]);
1308	}
1309
1310	DDPRINTF(pf->dev, "VF %d: Programmed key starting with 0x%x ok!",
1311	    vf->vf_num, key->key[0]);
1312
1313	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_KEY);
1314}
1315
1316static void
1317ixl_vf_config_rss_lut_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1318    uint16_t msg_size)
1319{
1320	struct i40e_hw *hw;
1321	struct virtchnl_rss_lut *lut;
1322	enum i40e_status_code status;
1323
1324	hw = &pf->hw;
1325
1326	lut = msg;
1327
1328	if (lut->lut_entries > 64) {
1329		device_printf(pf->dev, "VF %d: # of LUT entries in msg (%d) is greater than max (%d)\n",
1330		    vf->vf_num, lut->lut_entries, 64);
1331		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_LUT,
1332		    I40E_ERR_PARAM);
1333		return;
1334	}
1335
1336	if (lut->vsi_id != vf->vsi.vsi_num) {
1337		device_printf(pf->dev, "VF %d: VSI id in recvd message (%d) does not match expected id (%d)\n",
1338		    vf->vf_num, lut->vsi_id, vf->vsi.vsi_num);
1339		i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_LUT,
1340		    I40E_ERR_PARAM);
1341		return;
1342	}
1343
1344	/* Fill out LUT using MAC-dependent method */
1345	if (hw->mac.type == I40E_MAC_X722) {
1346		status = i40e_aq_set_rss_lut(hw, vf->vsi.vsi_num, false, lut->lut, lut->lut_entries);
1347		if (status) {
1348			device_printf(pf->dev, "i40e_aq_set_rss_lut status %s, error %s\n",
1349			    i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
1350			i40e_send_vf_nack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_LUT,
1351			    I40E_ERR_ADMIN_QUEUE_ERROR);
1352			return;
1353		}
1354	} else {
1355		for (int i = 0; i < (lut->lut_entries / 4); i++)
1356			i40e_write_rx_ctl(hw, I40E_VFQF_HLUT1(i, vf->vf_num), ((u32 *)lut->lut)[i]);
1357	}
1358
1359	DDPRINTF(pf->dev, "VF %d: Programmed LUT starting with 0x%x and length %d ok!",
1360	    vf->vf_num, lut->lut[0], lut->lut_entries);
1361
1362	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_CONFIG_RSS_LUT);
1363}
1364
1365static void
1366ixl_vf_set_rss_hena_msg(struct ixl_pf *pf, struct ixl_vf *vf, void *msg,
1367    uint16_t msg_size)
1368{
1369	struct i40e_hw *hw;
1370	struct virtchnl_rss_hena *hena;
1371
1372	hw = &pf->hw;
1373	hena = msg;
1374
1375	/* Set HENA */
1376	i40e_write_rx_ctl(hw, I40E_VFQF_HENA1(0, vf->vf_num), (u32)hena->hena);
1377	i40e_write_rx_ctl(hw, I40E_VFQF_HENA1(1, vf->vf_num), (u32)(hena->hena >> 32));
1378
1379	DDPRINTF(pf->dev, "VF %d: Programmed HENA with 0x%016lx",
1380	    vf->vf_num, hena->hena);
1381
1382	ixl_send_vf_ack(pf, vf, VIRTCHNL_OP_SET_RSS_HENA);
1383}
1384
1385static void
1386ixl_notify_vf_link_state(struct ixl_pf *pf, struct ixl_vf *vf)
1387{
1388	struct virtchnl_pf_event event;
1389	struct i40e_hw *hw;
1390
1391	hw = &pf->hw;
1392	event.event = VIRTCHNL_EVENT_LINK_CHANGE;
1393	event.severity = PF_EVENT_SEVERITY_INFO;
1394	event.event_data.link_event.link_status = pf->vsi.link_active;
1395	event.event_data.link_event.link_speed =
1396	    i40e_virtchnl_link_speed(hw->phy.link_info.link_speed);
1397
1398	ixl_send_vf_msg(pf, vf, VIRTCHNL_OP_EVENT, I40E_SUCCESS, &event,
1399			sizeof(event));
1400}
1401
1402void
1403ixl_broadcast_link_state(struct ixl_pf *pf)
1404{
1405	int i;
1406
1407	for (i = 0; i < pf->num_vfs; i++)
1408		ixl_notify_vf_link_state(pf, &pf->vfs[i]);
1409}
1410
1411void
1412ixl_handle_vf_msg(struct ixl_pf *pf, struct i40e_arq_event_info *event)
1413{
1414	device_t dev = pf->dev;
1415	struct ixl_vf *vf;
1416	uint16_t vf_num, msg_size;
1417	uint32_t opcode;
1418	void *msg;
1419	int err;
1420
1421	vf_num = le16toh(event->desc.retval) - pf->hw.func_caps.vf_base_id;
1422	opcode = le32toh(event->desc.cookie_high);
1423
1424	if (vf_num >= pf->num_vfs) {
1425		device_printf(pf->dev, "Got msg from illegal VF: %d\n", vf_num);
1426		return;
1427	}
1428
1429	vf = &pf->vfs[vf_num];
1430	msg = event->msg_buf;
1431	msg_size = event->msg_len;
1432
1433	I40E_VC_DEBUG(pf, ixl_vc_opcode_level(opcode),
1434	    "Got msg %s(%d) from%sVF-%d of size %d\n",
1435	    ixl_vc_opcode_str(opcode), opcode,
1436	    (vf->vf_flags & VF_FLAG_ENABLED) ? " " : " disabled ",
1437	    vf_num, msg_size);
1438
1439	/* Perform basic checks on the msg */
1440	err = virtchnl_vc_validate_vf_msg(&vf->version, opcode, msg, msg_size);
1441	if (err) {
1442		device_printf(dev, "%s: Received invalid msg from VF-%d: opcode %d, len %d, error %d\n",
1443		    __func__, vf->vf_num, opcode, msg_size, err);
1444		i40e_send_vf_nack(pf, vf, opcode, I40E_ERR_PARAM);
1445		return;
1446	}
1447
1448	/* This must be a stray msg from a previously destroyed VF. */
1449	if (!(vf->vf_flags & VF_FLAG_ENABLED))
1450		return;
1451
1452	switch (opcode) {
1453	case VIRTCHNL_OP_VERSION:
1454		ixl_vf_version_msg(pf, vf, msg, msg_size);
1455		break;
1456	case VIRTCHNL_OP_RESET_VF:
1457		ixl_vf_reset_msg(pf, vf, msg, msg_size);
1458		break;
1459	case VIRTCHNL_OP_GET_VF_RESOURCES:
1460		ixl_vf_get_resources_msg(pf, vf, msg, msg_size);
1461		/* Notify VF of link state after it obtains queues, as this is
1462		 * the last thing it will do as part of initialization
1463		 */
1464		ixl_notify_vf_link_state(pf, vf);
1465		break;
1466	case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
1467		ixl_vf_config_vsi_msg(pf, vf, msg, msg_size);
1468		break;
1469	case VIRTCHNL_OP_CONFIG_IRQ_MAP:
1470		ixl_vf_config_irq_msg(pf, vf, msg, msg_size);
1471		break;
1472	case VIRTCHNL_OP_ENABLE_QUEUES:
1473		ixl_vf_enable_queues_msg(pf, vf, msg, msg_size);
1474		/* Notify VF of link state after it obtains queues, as this is
1475		 * the last thing it will do as part of initialization
1476		 */
1477		ixl_notify_vf_link_state(pf, vf);
1478		break;
1479	case VIRTCHNL_OP_DISABLE_QUEUES:
1480		ixl_vf_disable_queues_msg(pf, vf, msg, msg_size);
1481		break;
1482	case VIRTCHNL_OP_ADD_ETH_ADDR:
1483		ixl_vf_add_mac_msg(pf, vf, msg, msg_size);
1484		break;
1485	case VIRTCHNL_OP_DEL_ETH_ADDR:
1486		ixl_vf_del_mac_msg(pf, vf, msg, msg_size);
1487		break;
1488	case VIRTCHNL_OP_ADD_VLAN:
1489		ixl_vf_add_vlan_msg(pf, vf, msg, msg_size);
1490		break;
1491	case VIRTCHNL_OP_DEL_VLAN:
1492		ixl_vf_del_vlan_msg(pf, vf, msg, msg_size);
1493		break;
1494	case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
1495		ixl_vf_config_promisc_msg(pf, vf, msg, msg_size);
1496		break;
1497	case VIRTCHNL_OP_GET_STATS:
1498		ixl_vf_get_stats_msg(pf, vf, msg, msg_size);
1499		break;
1500	case VIRTCHNL_OP_CONFIG_RSS_KEY:
1501		ixl_vf_config_rss_key_msg(pf, vf, msg, msg_size);
1502		break;
1503	case VIRTCHNL_OP_CONFIG_RSS_LUT:
1504		ixl_vf_config_rss_lut_msg(pf, vf, msg, msg_size);
1505		break;
1506	case VIRTCHNL_OP_SET_RSS_HENA:
1507		ixl_vf_set_rss_hena_msg(pf, vf, msg, msg_size);
1508		break;
1509
1510	/* These two opcodes have been superseded by CONFIG_VSI_QUEUES. */
1511	case VIRTCHNL_OP_CONFIG_TX_QUEUE:
1512	case VIRTCHNL_OP_CONFIG_RX_QUEUE:
1513	default:
1514		i40e_send_vf_nack(pf, vf, opcode, I40E_ERR_NOT_IMPLEMENTED);
1515		break;
1516	}
1517}
1518
1519/* Handle any VFs that have reset themselves via a Function Level Reset(FLR). */
1520void
1521ixl_handle_vflr(struct ixl_pf *pf)
1522{
1523	struct ixl_vf *vf;
1524	struct i40e_hw *hw;
1525	uint16_t global_vf_num;
1526	uint32_t vflrstat_index, vflrstat_mask, vflrstat, icr0;
1527	int i;
1528
1529	hw = &pf->hw;
1530
1531	ixl_dbg_iov(pf, "%s: begin\n", __func__);
1532
1533	/* Re-enable VFLR interrupt cause so driver doesn't miss a
1534	 * reset interrupt for another VF */
1535	icr0 = rd32(hw, I40E_PFINT_ICR0_ENA);
1536	icr0 |= I40E_PFINT_ICR0_ENA_VFLR_MASK;
1537	wr32(hw, I40E_PFINT_ICR0_ENA, icr0);
1538	ixl_flush(hw);
1539
1540	for (i = 0; i < pf->num_vfs; i++) {
1541		global_vf_num = hw->func_caps.vf_base_id + i;
1542
1543		vf = &pf->vfs[i];
1544		if (!(vf->vf_flags & VF_FLAG_ENABLED))
1545			continue;
1546
1547		vflrstat_index = IXL_GLGEN_VFLRSTAT_INDEX(global_vf_num);
1548		vflrstat_mask = IXL_GLGEN_VFLRSTAT_MASK(global_vf_num);
1549		vflrstat = rd32(hw, I40E_GLGEN_VFLRSTAT(vflrstat_index));
1550		if (vflrstat & vflrstat_mask) {
1551			wr32(hw, I40E_GLGEN_VFLRSTAT(vflrstat_index),
1552			    vflrstat_mask);
1553
1554			ixl_dbg_iov(pf, "Reinitializing VF-%d\n", i);
1555			ixl_reinit_vf(pf, vf);
1556			ixl_dbg_iov(pf, "Reinitializing VF-%d done\n", i);
1557		}
1558	}
1559
1560}
1561
1562static int
1563ixl_adminq_err_to_errno(enum i40e_admin_queue_err err)
1564{
1565
1566	switch (err) {
1567	case I40E_AQ_RC_EPERM:
1568		return (EPERM);
1569	case I40E_AQ_RC_ENOENT:
1570		return (ENOENT);
1571	case I40E_AQ_RC_ESRCH:
1572		return (ESRCH);
1573	case I40E_AQ_RC_EINTR:
1574		return (EINTR);
1575	case I40E_AQ_RC_EIO:
1576		return (EIO);
1577	case I40E_AQ_RC_ENXIO:
1578		return (ENXIO);
1579	case I40E_AQ_RC_E2BIG:
1580		return (E2BIG);
1581	case I40E_AQ_RC_EAGAIN:
1582		return (EAGAIN);
1583	case I40E_AQ_RC_ENOMEM:
1584		return (ENOMEM);
1585	case I40E_AQ_RC_EACCES:
1586		return (EACCES);
1587	case I40E_AQ_RC_EFAULT:
1588		return (EFAULT);
1589	case I40E_AQ_RC_EBUSY:
1590		return (EBUSY);
1591	case I40E_AQ_RC_EEXIST:
1592		return (EEXIST);
1593	case I40E_AQ_RC_EINVAL:
1594		return (EINVAL);
1595	case I40E_AQ_RC_ENOTTY:
1596		return (ENOTTY);
1597	case I40E_AQ_RC_ENOSPC:
1598		return (ENOSPC);
1599	case I40E_AQ_RC_ENOSYS:
1600		return (ENOSYS);
1601	case I40E_AQ_RC_ERANGE:
1602		return (ERANGE);
1603	case I40E_AQ_RC_EFLUSHED:
1604		return (EINVAL);	/* No exact equivalent in errno.h */
1605	case I40E_AQ_RC_BAD_ADDR:
1606		return (EFAULT);
1607	case I40E_AQ_RC_EMODE:
1608		return (EPERM);
1609	case I40E_AQ_RC_EFBIG:
1610		return (EFBIG);
1611	default:
1612		return (EINVAL);
1613	}
1614}
1615
1616static int
1617ixl_config_pf_vsi_loopback(struct ixl_pf *pf, bool enable)
1618{
1619	struct i40e_hw *hw = &pf->hw;
1620	device_t dev = pf->dev;
1621	struct ixl_vsi *vsi = &pf->vsi;
1622	struct i40e_vsi_context	ctxt;
1623	int error;
1624
1625	memset(&ctxt, 0, sizeof(ctxt));
1626
1627	ctxt.seid = vsi->seid;
1628	if (pf->veb_seid != 0)
1629		ctxt.uplink_seid = pf->veb_seid;
1630	ctxt.pf_num = hw->pf_id;
1631	ctxt.connection_type = IXL_VSI_DATA_PORT;
1632
1633	ctxt.info.valid_sections = htole16(I40E_AQ_VSI_PROP_SWITCH_VALID);
1634	ctxt.info.switch_id = (enable) ?
1635	    htole16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) : 0;
1636
1637	/* error is set to 0 on success */
1638	error = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
1639	if (error) {
1640		device_printf(dev, "i40e_aq_update_vsi_params() failed, error %d,"
1641		    " aq_error %d\n", error, hw->aq.asq_last_status);
1642	}
1643
1644	return (error);
1645}
1646
1647int
1648ixl_if_iov_init(if_ctx_t ctx, uint16_t num_vfs, const nvlist_t *params)
1649{
1650	struct ixl_pf *pf = iflib_get_softc(ctx);
1651	device_t dev = iflib_get_dev(ctx);
1652	struct i40e_hw *hw;
1653	struct ixl_vsi *pf_vsi;
1654	enum i40e_status_code ret;
1655	int error;
1656
1657	hw = &pf->hw;
1658	pf_vsi = &pf->vsi;
1659
1660	pf->vfs = malloc(sizeof(struct ixl_vf) * num_vfs, M_IXL, M_NOWAIT |
1661	    M_ZERO);
1662	if (pf->vfs == NULL) {
1663		error = ENOMEM;
1664		goto fail;
1665	}
1666
1667	/*
1668	 * Add the VEB and ...
1669	 * - do nothing: VEPA mode
1670	 * - enable loopback mode on connected VSIs: VEB mode
1671	 */
1672	ret = i40e_aq_add_veb(hw, pf_vsi->uplink_seid, pf_vsi->seid,
1673	    1, FALSE, &pf->veb_seid, FALSE, NULL);
1674	if (ret != I40E_SUCCESS) {
1675		error = hw->aq.asq_last_status;
1676		device_printf(dev, "i40e_aq_add_veb failed; status %s error %s",
1677		    i40e_stat_str(hw, ret), i40e_aq_str(hw, error));
1678		goto fail;
1679	}
1680	if (pf->enable_vf_loopback)
1681		ixl_config_pf_vsi_loopback(pf, true);
1682
1683	/*
1684	 * Adding a VEB brings back the default MAC filter(s). Remove them,
1685	 * and let the driver add the proper filters back.
1686	 */
1687	ixl_del_default_hw_filters(pf_vsi);
1688	ixl_reconfigure_filters(pf_vsi);
1689
1690	pf->num_vfs = num_vfs;
1691	return (0);
1692
1693fail:
1694	free(pf->vfs, M_IXL);
1695	pf->vfs = NULL;
1696	return (error);
1697}
1698
1699void
1700ixl_if_iov_uninit(if_ctx_t ctx)
1701{
1702	struct ixl_pf *pf = iflib_get_softc(ctx);
1703	struct i40e_hw *hw;
1704	struct ixl_vf *vfs;
1705	int i, num_vfs;
1706
1707	hw = &pf->hw;
1708
1709	for (i = 0; i < pf->num_vfs; i++) {
1710		if (pf->vfs[i].vsi.seid != 0)
1711			i40e_aq_delete_element(hw, pf->vfs[i].vsi.seid, NULL);
1712		ixl_pf_qmgr_release(&pf->qmgr, &pf->vfs[i].qtag);
1713		ixl_free_filters(&pf->vfs[i].vsi.ftl);
1714		ixl_dbg_iov(pf, "VF %d: %d released\n",
1715		    i, pf->vfs[i].qtag.num_allocated);
1716		ixl_dbg_iov(pf, "Unallocated total: %d\n", ixl_pf_qmgr_get_num_free(&pf->qmgr));
1717	}
1718
1719	if (pf->veb_seid != 0) {
1720		i40e_aq_delete_element(hw, pf->veb_seid, NULL);
1721		pf->veb_seid = 0;
1722	}
1723	/* Reset PF VSI loopback mode */
1724	if (pf->enable_vf_loopback)
1725		ixl_config_pf_vsi_loopback(pf, false);
1726
1727	vfs = pf->vfs;
1728	num_vfs = pf->num_vfs;
1729
1730	pf->vfs = NULL;
1731	pf->num_vfs = 0;
1732
1733	/* sysctl_ctx_free might sleep, but this func is called w/ an sx lock */
1734	for (i = 0; i < num_vfs; i++)
1735		sysctl_ctx_free(&vfs[i].vsi.sysctl_ctx);
1736	free(vfs, M_IXL);
1737}
1738
1739static int
1740ixl_vf_reserve_queues(struct ixl_pf *pf, struct ixl_vf *vf, int num_queues)
1741{
1742	device_t dev = pf->dev;
1743	int error;
1744
1745	/* Validate, and clamp value if invalid */
1746	if (num_queues < 1 || num_queues > 16)
1747		device_printf(dev, "Invalid num-queues (%d) for VF %d\n",
1748		    num_queues, vf->vf_num);
1749	if (num_queues < 1) {
1750		device_printf(dev, "Setting VF %d num-queues to 1\n", vf->vf_num);
1751		num_queues = 1;
1752	} else if (num_queues > IAVF_MAX_QUEUES) {
1753		device_printf(dev, "Setting VF %d num-queues to %d\n", vf->vf_num, IAVF_MAX_QUEUES);
1754		num_queues = IAVF_MAX_QUEUES;
1755	}
1756	error = ixl_pf_qmgr_alloc_scattered(&pf->qmgr, num_queues, &vf->qtag);
1757	if (error) {
1758		device_printf(dev, "Error allocating %d queues for VF %d's VSI\n",
1759		    num_queues, vf->vf_num);
1760		return (ENOSPC);
1761	}
1762
1763	ixl_dbg_iov(pf, "VF %d: %d allocated, %d active\n",
1764	    vf->vf_num, vf->qtag.num_allocated, vf->qtag.num_active);
1765	ixl_dbg_iov(pf, "Unallocated total: %d\n", ixl_pf_qmgr_get_num_free(&pf->qmgr));
1766
1767	return (0);
1768}
1769
1770int
1771ixl_if_iov_vf_add(if_ctx_t ctx, uint16_t vfnum, const nvlist_t *params)
1772{
1773	struct ixl_pf *pf = iflib_get_softc(ctx);
1774	char sysctl_name[IXL_QUEUE_NAME_LEN];
1775	struct ixl_vf *vf;
1776	const void *mac;
1777	size_t size;
1778	int error;
1779	int vf_num_queues;
1780
1781	vf = &pf->vfs[vfnum];
1782	vf->vf_num = vfnum;
1783	vf->vsi.back = pf;
1784	vf->vf_flags = VF_FLAG_ENABLED;
1785
1786	/* Reserve queue allocation from PF */
1787	vf_num_queues = nvlist_get_number(params, "num-queues");
1788	error = ixl_vf_reserve_queues(pf, vf, vf_num_queues);
1789	if (error != 0)
1790		goto out;
1791
1792	error = ixl_vf_setup_vsi(pf, vf);
1793	if (error != 0)
1794		goto out;
1795
1796	if (nvlist_exists_binary(params, "mac-addr")) {
1797		mac = nvlist_get_binary(params, "mac-addr", &size);
1798		bcopy(mac, vf->mac, ETHER_ADDR_LEN);
1799
1800		if (nvlist_get_bool(params, "allow-set-mac"))
1801			vf->vf_flags |= VF_FLAG_SET_MAC_CAP;
1802	} else
1803		/*
1804		 * If the administrator has not specified a MAC address then
1805		 * we must allow the VF to choose one.
1806		 */
1807		vf->vf_flags |= VF_FLAG_SET_MAC_CAP;
1808
1809	if (nvlist_get_bool(params, "mac-anti-spoof"))
1810		vf->vf_flags |= VF_FLAG_MAC_ANTI_SPOOF;
1811
1812	if (nvlist_get_bool(params, "allow-promisc"))
1813		vf->vf_flags |= VF_FLAG_PROMISC_CAP;
1814
1815	vf->vf_flags |= VF_FLAG_VLAN_CAP;
1816
1817	/* VF needs to be reset before it can be used */
1818	ixl_reset_vf(pf, vf);
1819out:
1820	if (error == 0) {
1821		snprintf(sysctl_name, sizeof(sysctl_name), "vf%d", vfnum);
1822		ixl_vsi_add_sysctls(&vf->vsi, sysctl_name, false);
1823	}
1824
1825	return (error);
1826}
1827
1828