brintos

brintos / linux-shallow public Read only

0
0
Text · 19.9 KiB · 9aae0d8 Raw
808 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/****************************************************************************3 * Driver for Solarflare network controllers and boards4 * Copyright 2015 Solarflare Communications Inc.5 */6#include <linux/etherdevice.h>7#include <linux/pci.h>8#include <linux/module.h>9#include "net_driver.h"10#include "ef10_sriov.h"11#include "efx.h"12#include "nic.h"13#include "mcdi_pcol.h"14 15static int efx_ef10_evb_port_assign(struct efx_nic *efx, unsigned int port_id,16				    unsigned int vf_fn)17{18	MCDI_DECLARE_BUF(inbuf, MC_CMD_EVB_PORT_ASSIGN_IN_LEN);19	struct efx_ef10_nic_data *nic_data = efx->nic_data;20 21	MCDI_SET_DWORD(inbuf, EVB_PORT_ASSIGN_IN_PORT_ID, port_id);22	MCDI_POPULATE_DWORD_2(inbuf, EVB_PORT_ASSIGN_IN_FUNCTION,23			      EVB_PORT_ASSIGN_IN_PF, nic_data->pf_index,24			      EVB_PORT_ASSIGN_IN_VF, vf_fn);25 26	return efx_mcdi_rpc(efx, MC_CMD_EVB_PORT_ASSIGN, inbuf, sizeof(inbuf),27			    NULL, 0, NULL);28}29 30static int efx_ef10_vswitch_alloc(struct efx_nic *efx, unsigned int port_id,31				  unsigned int vswitch_type)32{33	MCDI_DECLARE_BUF(inbuf, MC_CMD_VSWITCH_ALLOC_IN_LEN);34	int rc;35 36	MCDI_SET_DWORD(inbuf, VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID, port_id);37	MCDI_SET_DWORD(inbuf, VSWITCH_ALLOC_IN_TYPE, vswitch_type);38	MCDI_SET_DWORD(inbuf, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS, 2);39	MCDI_POPULATE_DWORD_1(inbuf, VSWITCH_ALLOC_IN_FLAGS,40			      VSWITCH_ALLOC_IN_FLAG_AUTO_PORT, 0);41 42	/* Quietly try to allocate 2 VLAN tags */43	rc = efx_mcdi_rpc_quiet(efx, MC_CMD_VSWITCH_ALLOC, inbuf, sizeof(inbuf),44				NULL, 0, NULL);45 46	/* If 2 VLAN tags is too many, revert to trying with 1 VLAN tags */47	if (rc == -EPROTO) {48		MCDI_SET_DWORD(inbuf, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS, 1);49		rc = efx_mcdi_rpc(efx, MC_CMD_VSWITCH_ALLOC, inbuf,50				  sizeof(inbuf), NULL, 0, NULL);51	} else if (rc) {52		efx_mcdi_display_error(efx, MC_CMD_VSWITCH_ALLOC,53				       MC_CMD_VSWITCH_ALLOC_IN_LEN,54				       NULL, 0, rc);55	}56	return rc;57}58 59static int efx_ef10_vswitch_free(struct efx_nic *efx, unsigned int port_id)60{61	MCDI_DECLARE_BUF(inbuf, MC_CMD_VSWITCH_FREE_IN_LEN);62 63	MCDI_SET_DWORD(inbuf, VSWITCH_FREE_IN_UPSTREAM_PORT_ID, port_id);64 65	return efx_mcdi_rpc(efx, MC_CMD_VSWITCH_FREE, inbuf, sizeof(inbuf),66			    NULL, 0, NULL);67}68 69static int efx_ef10_vport_alloc(struct efx_nic *efx,70				unsigned int port_id_in,71				unsigned int vport_type,72				u16 vlan,73				unsigned int *port_id_out)74{75	MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_ALLOC_IN_LEN);76	MCDI_DECLARE_BUF(outbuf, MC_CMD_VPORT_ALLOC_OUT_LEN);77	size_t outlen;78	int rc;79 80	EFX_WARN_ON_PARANOID(!port_id_out);81 82	MCDI_SET_DWORD(inbuf, VPORT_ALLOC_IN_UPSTREAM_PORT_ID, port_id_in);83	MCDI_SET_DWORD(inbuf, VPORT_ALLOC_IN_TYPE, vport_type);84	MCDI_SET_DWORD(inbuf, VPORT_ALLOC_IN_NUM_VLAN_TAGS,85		       (vlan != EFX_EF10_NO_VLAN));86	MCDI_POPULATE_DWORD_1(inbuf, VPORT_ALLOC_IN_FLAGS,87			      VPORT_ALLOC_IN_FLAG_AUTO_PORT, 0);88	if (vlan != EFX_EF10_NO_VLAN)89		MCDI_POPULATE_DWORD_1(inbuf, VPORT_ALLOC_IN_VLAN_TAGS,90				      VPORT_ALLOC_IN_VLAN_TAG_0, vlan);91 92	rc = efx_mcdi_rpc(efx, MC_CMD_VPORT_ALLOC, inbuf, sizeof(inbuf),93			  outbuf, sizeof(outbuf), &outlen);94	if (rc)95		return rc;96	if (outlen < MC_CMD_VPORT_ALLOC_OUT_LEN)97		return -EIO;98 99	*port_id_out = MCDI_DWORD(outbuf, VPORT_ALLOC_OUT_VPORT_ID);100	return 0;101}102 103static int efx_ef10_vport_free(struct efx_nic *efx, unsigned int port_id)104{105	MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_FREE_IN_LEN);106 107	MCDI_SET_DWORD(inbuf, VPORT_FREE_IN_VPORT_ID, port_id);108 109	return efx_mcdi_rpc(efx, MC_CMD_VPORT_FREE, inbuf, sizeof(inbuf),110			    NULL, 0, NULL);111}112 113static void efx_ef10_sriov_free_vf_vports(struct efx_nic *efx)114{115	struct efx_ef10_nic_data *nic_data = efx->nic_data;116	int i;117 118	if (!nic_data->vf)119		return;120 121	for (i = 0; i < efx->vf_count; i++) {122		struct ef10_vf *vf = nic_data->vf + i;123 124		/* If VF is assigned, do not free the vport  */125		if (vf->pci_dev && pci_is_dev_assigned(vf->pci_dev))126			continue;127 128		if (vf->vport_assigned) {129			efx_ef10_evb_port_assign(efx, EVB_PORT_ID_NULL, i);130			vf->vport_assigned = 0;131		}132 133		if (!is_zero_ether_addr(vf->mac)) {134			efx_ef10_vport_del_mac(efx, vf->vport_id, vf->mac);135			eth_zero_addr(vf->mac);136		}137 138		if (vf->vport_id) {139			efx_ef10_vport_free(efx, vf->vport_id);140			vf->vport_id = 0;141		}142 143		vf->efx = NULL;144	}145}146 147static void efx_ef10_sriov_free_vf_vswitching(struct efx_nic *efx)148{149	struct efx_ef10_nic_data *nic_data = efx->nic_data;150 151	efx_ef10_sriov_free_vf_vports(efx);152	kfree(nic_data->vf);153	nic_data->vf = NULL;154}155 156static int efx_ef10_sriov_assign_vf_vport(struct efx_nic *efx,157					  unsigned int vf_i)158{159	struct efx_ef10_nic_data *nic_data = efx->nic_data;160	struct ef10_vf *vf = nic_data->vf + vf_i;161	int rc;162 163	if (WARN_ON_ONCE(!nic_data->vf))164		return -EOPNOTSUPP;165 166	rc = efx_ef10_vport_alloc(efx, EVB_PORT_ID_ASSIGNED,167				  MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL,168				  vf->vlan, &vf->vport_id);169	if (rc)170		return rc;171 172	rc = efx_ef10_vport_add_mac(efx, vf->vport_id, vf->mac);173	if (rc) {174		eth_zero_addr(vf->mac);175		return rc;176	}177 178	rc =  efx_ef10_evb_port_assign(efx, vf->vport_id, vf_i);179	if (rc)180		return rc;181 182	vf->vport_assigned = 1;183	return 0;184}185 186static int efx_ef10_sriov_alloc_vf_vswitching(struct efx_nic *efx)187{188	struct efx_ef10_nic_data *nic_data = efx->nic_data;189	unsigned int i;190	int rc;191 192	nic_data->vf = kcalloc(efx->vf_count, sizeof(struct ef10_vf),193			       GFP_KERNEL);194	if (!nic_data->vf)195		return -ENOMEM;196 197	for (i = 0; i < efx->vf_count; i++) {198		eth_random_addr(nic_data->vf[i].mac);199		nic_data->vf[i].efx = NULL;200		nic_data->vf[i].vlan = EFX_EF10_NO_VLAN;201 202		rc = efx_ef10_sriov_assign_vf_vport(efx, i);203		if (rc)204			goto fail;205	}206 207	return 0;208fail:209	efx_ef10_sriov_free_vf_vswitching(efx);210	return rc;211}212 213static int efx_ef10_sriov_restore_vf_vswitching(struct efx_nic *efx)214{215	unsigned int i;216	int rc;217 218	for (i = 0; i < efx->vf_count; i++) {219		rc = efx_ef10_sriov_assign_vf_vport(efx, i);220		if (rc)221			goto fail;222	}223 224	return 0;225fail:226	efx_ef10_sriov_free_vf_vswitching(efx);227	return rc;228}229 230static int efx_ef10_vadaptor_alloc_set_features(struct efx_nic *efx)231{232	u32 port_flags;233	int rc;234 235	rc = efx_ef10_vadaptor_alloc(efx, efx->vport_id);236	if (rc)237		goto fail_vadaptor_alloc;238 239	rc = efx_ef10_vadaptor_query(efx, efx->vport_id,240				     &port_flags, NULL, NULL);241	if (rc)242		goto fail_vadaptor_query;243 244	if (port_flags &245	    (1 << MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_LBN))246		efx->fixed_features |= NETIF_F_HW_VLAN_CTAG_FILTER;247	else248		efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;249 250	return 0;251 252fail_vadaptor_query:253	efx_ef10_vadaptor_free(efx, EVB_PORT_ID_ASSIGNED);254fail_vadaptor_alloc:255	return rc;256}257 258/* On top of the default firmware vswitch setup, create a VEB vswitch and259 * expansion vport for use by this function.260 */261int efx_ef10_vswitching_probe_pf(struct efx_nic *efx)262{263	struct efx_ef10_nic_data *nic_data = efx->nic_data;264	struct net_device *net_dev = efx->net_dev;265	int rc;266 267	if (pci_sriov_get_totalvfs(efx->pci_dev) <= 0) {268		/* vswitch not needed as we have no VFs */269		efx_ef10_vadaptor_alloc_set_features(efx);270		return 0;271	}272 273	rc = efx_ef10_vswitch_alloc(efx, EVB_PORT_ID_ASSIGNED,274				    MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB);275	if (rc)276		goto fail1;277 278	rc = efx_ef10_vport_alloc(efx, EVB_PORT_ID_ASSIGNED,279				  MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL,280				  EFX_EF10_NO_VLAN, &efx->vport_id);281	if (rc)282		goto fail2;283 284	rc = efx_ef10_vport_add_mac(efx, efx->vport_id, net_dev->dev_addr);285	if (rc)286		goto fail3;287	ether_addr_copy(nic_data->vport_mac, net_dev->dev_addr);288 289	rc = efx_ef10_vadaptor_alloc_set_features(efx);290	if (rc)291		goto fail4;292 293	return 0;294fail4:295	efx_ef10_vport_del_mac(efx, efx->vport_id, nic_data->vport_mac);296	eth_zero_addr(nic_data->vport_mac);297fail3:298	efx_ef10_vport_free(efx, efx->vport_id);299	efx->vport_id = EVB_PORT_ID_ASSIGNED;300fail2:301	efx_ef10_vswitch_free(efx, EVB_PORT_ID_ASSIGNED);302fail1:303	return rc;304}305 306int efx_ef10_vswitching_probe_vf(struct efx_nic *efx)307{308	return efx_ef10_vadaptor_alloc_set_features(efx);309}310 311int efx_ef10_vswitching_restore_pf(struct efx_nic *efx)312{313	struct efx_ef10_nic_data *nic_data = efx->nic_data;314	int rc;315 316	if (!nic_data->must_probe_vswitching)317		return 0;318 319	rc = efx_ef10_vswitching_probe_pf(efx);320	if (rc)321		goto fail;322 323	rc = efx_ef10_sriov_restore_vf_vswitching(efx);324	if (rc)325		goto fail;326 327	nic_data->must_probe_vswitching = false;328fail:329	return rc;330}331 332int efx_ef10_vswitching_restore_vf(struct efx_nic *efx)333{334	struct efx_ef10_nic_data *nic_data = efx->nic_data;335	int rc;336 337	if (!nic_data->must_probe_vswitching)338		return 0;339 340	rc = efx_ef10_vadaptor_free(efx, EVB_PORT_ID_ASSIGNED);341	if (rc)342		return rc;343 344	nic_data->must_probe_vswitching = false;345	return 0;346}347 348void efx_ef10_vswitching_remove_pf(struct efx_nic *efx)349{350	struct efx_ef10_nic_data *nic_data = efx->nic_data;351 352	efx_ef10_sriov_free_vf_vswitching(efx);353 354	efx_ef10_vadaptor_free(efx, efx->vport_id);355 356	if (efx->vport_id == EVB_PORT_ID_ASSIGNED)357		return; /* No vswitch was ever created */358 359	if (!is_zero_ether_addr(nic_data->vport_mac)) {360		efx_ef10_vport_del_mac(efx, efx->vport_id,361				       efx->net_dev->dev_addr);362		eth_zero_addr(nic_data->vport_mac);363	}364	efx_ef10_vport_free(efx, efx->vport_id);365	efx->vport_id = EVB_PORT_ID_ASSIGNED;366 367	/* Only free the vswitch if no VFs are assigned */368	if (!pci_vfs_assigned(efx->pci_dev))369		efx_ef10_vswitch_free(efx, efx->vport_id);370}371 372void efx_ef10_vswitching_remove_vf(struct efx_nic *efx)373{374	efx_ef10_vadaptor_free(efx, EVB_PORT_ID_ASSIGNED);375}376 377static int efx_ef10_pci_sriov_enable(struct efx_nic *efx, int num_vfs)378{379	int rc = 0;380	struct pci_dev *dev = efx->pci_dev;381 382	efx->vf_count = num_vfs;383 384	rc = efx_ef10_sriov_alloc_vf_vswitching(efx);385	if (rc)386		goto fail1;387 388	rc = pci_enable_sriov(dev, num_vfs);389	if (rc)390		goto fail2;391 392	return 0;393fail2:394	efx_ef10_sriov_free_vf_vswitching(efx);395fail1:396	efx->vf_count = 0;397	netif_err(efx, probe, efx->net_dev,398		  "Failed to enable SRIOV VFs\n");399	return rc;400}401 402/* Disable SRIOV and remove VFs403 * If some VFs are attached to a guest (using Xen, only) nothing is404 * done if force=false, and vports are freed if force=true (for the non405 * attachedc ones, only) but SRIOV is not disabled and VFs are not406 * removed in either case.407 */408static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)409{410	struct pci_dev *dev = efx->pci_dev;411	struct efx_ef10_nic_data *nic_data = efx->nic_data;412	unsigned int vfs_assigned = pci_vfs_assigned(dev);413	int i, rc = 0;414 415	if (vfs_assigned && !force) {416		netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "417			   "please detach them before disabling SR-IOV\n");418		return -EBUSY;419	}420 421	if (!vfs_assigned) {422		for (i = 0; i < efx->vf_count; i++)423			nic_data->vf[i].pci_dev = NULL;424		pci_disable_sriov(dev);425	} else {426		rc = -EBUSY;427	}428 429	efx_ef10_sriov_free_vf_vswitching(efx);430	efx->vf_count = 0;431	return rc;432}433 434int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs)435{436	if (num_vfs == 0)437		return efx_ef10_pci_sriov_disable(efx, false);438	else439		return efx_ef10_pci_sriov_enable(efx, num_vfs);440}441 442int efx_ef10_sriov_init(struct efx_nic *efx)443{444	return 0;445}446 447void efx_ef10_sriov_fini(struct efx_nic *efx)448{449	struct efx_ef10_nic_data *nic_data = efx->nic_data;450	int rc;451 452	if (!nic_data->vf) {453		/* Remove any un-assigned orphaned VFs. This can happen if the PF driver454		 * was unloaded while any VF was assigned to a guest (using Xen, only).455		 */456		if (pci_num_vf(efx->pci_dev) && !pci_vfs_assigned(efx->pci_dev))457			pci_disable_sriov(efx->pci_dev);458		return;459	}460 461	/* Disable SRIOV and remove any VFs in the host */462	rc = efx_ef10_pci_sriov_disable(efx, true);463	if (rc)464		netif_dbg(efx, drv, efx->net_dev,465			  "Disabling SRIOV was not successful rc=%d\n", rc);466	else467		netif_dbg(efx, drv, efx->net_dev, "SRIOV disabled\n");468}469 470static int efx_ef10_vport_del_vf_mac(struct efx_nic *efx, unsigned int port_id,471				     u8 *mac)472{473	MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN);474	MCDI_DECLARE_BUF_ERR(outbuf);475	size_t outlen;476	int rc;477 478	MCDI_SET_DWORD(inbuf, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, port_id);479	ether_addr_copy(MCDI_PTR(inbuf, VPORT_DEL_MAC_ADDRESS_IN_MACADDR), mac);480 481	rc = efx_mcdi_rpc(efx, MC_CMD_VPORT_DEL_MAC_ADDRESS, inbuf,482			  sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);483 484	return rc;485}486 487int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, const u8 *mac)488{489	struct efx_ef10_nic_data *nic_data = efx->nic_data;490	struct ef10_vf *vf;491	int rc;492 493	if (!nic_data->vf)494		return -EOPNOTSUPP;495 496	if (vf_i >= efx->vf_count)497		return -EINVAL;498	vf = nic_data->vf + vf_i;499 500	if (vf->efx) {501		efx_device_detach_sync(vf->efx);502		efx_net_stop(vf->efx->net_dev);503 504		vf->efx->type->filter_table_remove(vf->efx);505 506		rc = efx_ef10_vadaptor_free(vf->efx, EVB_PORT_ID_ASSIGNED);507		if (rc)508			return rc;509	}510 511	rc = efx_ef10_evb_port_assign(efx, EVB_PORT_ID_NULL, vf_i);512	if (rc)513		return rc;514 515	if (!is_zero_ether_addr(vf->mac)) {516		rc = efx_ef10_vport_del_vf_mac(efx, vf->vport_id, vf->mac);517		if (rc)518			return rc;519	}520 521	if (!is_zero_ether_addr(mac)) {522		rc = efx_ef10_vport_add_mac(efx, vf->vport_id, mac);523		if (rc)524			goto fail;525 526		if (vf->efx)527			eth_hw_addr_set(vf->efx->net_dev, mac);528	}529 530	ether_addr_copy(vf->mac, mac);531 532	rc = efx_ef10_evb_port_assign(efx, vf->vport_id, vf_i);533	if (rc)534		goto fail;535 536	if (vf->efx) {537		/* VF cannot use the vport_id that the PF created */538		rc = efx_ef10_vadaptor_alloc(vf->efx, EVB_PORT_ID_ASSIGNED);539		if (rc)540			return rc;541		vf->efx->type->filter_table_probe(vf->efx);542		efx_net_open(vf->efx->net_dev);543		efx_device_attach_if_not_resetting(vf->efx);544	}545 546	return 0;547 548fail:549	eth_zero_addr(vf->mac);550	return rc;551}552 553int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan,554			       u8 qos)555{556	struct efx_ef10_nic_data *nic_data = efx->nic_data;557	struct ef10_vf *vf;558	u16 new_vlan;559	int rc = 0, rc2 = 0;560 561	if (vf_i >= efx->vf_count)562		return -EINVAL;563	if (qos != 0)564		return -EINVAL;565 566	vf = nic_data->vf + vf_i;567 568	new_vlan = (vlan == 0) ? EFX_EF10_NO_VLAN : vlan;569	if (new_vlan == vf->vlan)570		return 0;571 572	if (vf->efx) {573		efx_device_detach_sync(vf->efx);574		efx_net_stop(vf->efx->net_dev);575 576		mutex_lock(&vf->efx->mac_lock);577		vf->efx->type->filter_table_remove(vf->efx);578 579		rc = efx_ef10_vadaptor_free(vf->efx, EVB_PORT_ID_ASSIGNED);580		if (rc)581			goto restore_filters;582	}583 584	if (vf->vport_assigned) {585		rc = efx_ef10_evb_port_assign(efx, EVB_PORT_ID_NULL, vf_i);586		if (rc) {587			netif_warn(efx, drv, efx->net_dev,588				   "Failed to change vlan on VF %d.\n", vf_i);589			netif_warn(efx, drv, efx->net_dev,590				   "This is likely because the VF is bound to a driver in a VM.\n");591			netif_warn(efx, drv, efx->net_dev,592				   "Please unload the driver in the VM.\n");593			goto restore_vadaptor;594		}595		vf->vport_assigned = 0;596	}597 598	if (!is_zero_ether_addr(vf->mac)) {599		rc = efx_ef10_vport_del_mac(efx, vf->vport_id, vf->mac);600		if (rc)601			goto restore_evb_port;602	}603 604	if (vf->vport_id) {605		rc = efx_ef10_vport_free(efx, vf->vport_id);606		if (rc)607			goto restore_mac;608		vf->vport_id = 0;609	}610 611	/* Do the actual vlan change */612	vf->vlan = new_vlan;613 614	/* Restore everything in reverse order */615	rc = efx_ef10_vport_alloc(efx, EVB_PORT_ID_ASSIGNED,616				  MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL,617				  vf->vlan, &vf->vport_id);618	if (rc)619		goto reset_nic_up_write;620 621restore_mac:622	if (!is_zero_ether_addr(vf->mac)) {623		rc2 = efx_ef10_vport_add_mac(efx, vf->vport_id, vf->mac);624		if (rc2) {625			eth_zero_addr(vf->mac);626			goto reset_nic_up_write;627		}628	}629 630restore_evb_port:631	rc2 = efx_ef10_evb_port_assign(efx, vf->vport_id, vf_i);632	if (rc2)633		goto reset_nic_up_write;634	else635		vf->vport_assigned = 1;636 637restore_vadaptor:638	if (vf->efx) {639		rc2 = efx_ef10_vadaptor_alloc(vf->efx, EVB_PORT_ID_ASSIGNED);640		if (rc2)641			goto reset_nic_up_write;642	}643 644restore_filters:645	if (vf->efx) {646		rc2 = vf->efx->type->filter_table_probe(vf->efx);647		if (rc2)648			goto reset_nic_up_write;649 650		mutex_unlock(&vf->efx->mac_lock);651 652		rc2 = efx_net_open(vf->efx->net_dev);653		if (rc2)654			goto reset_nic;655 656		efx_device_attach_if_not_resetting(vf->efx);657	}658	return rc;659 660reset_nic_up_write:661	if (vf->efx)662		mutex_unlock(&vf->efx->mac_lock);663reset_nic:664	if (vf->efx) {665		netif_err(efx, drv, efx->net_dev,666			  "Failed to restore VF - scheduling reset.\n");667		efx_schedule_reset(vf->efx, RESET_TYPE_DATAPATH);668	} else {669		netif_err(efx, drv, efx->net_dev,670			  "Failed to restore the VF and cannot reset the VF "671			  "- VF is not functional.\n");672		netif_err(efx, drv, efx->net_dev,673			  "Please reload the driver attached to the VF.\n");674	}675 676	return rc ? rc : rc2;677}678 679static int efx_ef10_sriov_set_privilege_mask(struct efx_nic *efx, int vf_i,680					     u32 mask, u32 value)681{682	MCDI_DECLARE_BUF(pm_outbuf, MC_CMD_PRIVILEGE_MASK_OUT_LEN);683	MCDI_DECLARE_BUF(pm_inbuf, MC_CMD_PRIVILEGE_MASK_IN_LEN);684	struct efx_ef10_nic_data *nic_data = efx->nic_data;685	u32 old_mask, new_mask;686	size_t outlen;687	int rc;688 689	EFX_WARN_ON_PARANOID((value & ~mask) != 0);690 691	/* Get privilege mask */692	MCDI_POPULATE_DWORD_2(pm_inbuf, PRIVILEGE_MASK_IN_FUNCTION,693			      PRIVILEGE_MASK_IN_FUNCTION_PF, nic_data->pf_index,694			      PRIVILEGE_MASK_IN_FUNCTION_VF, vf_i);695 696	rc = efx_mcdi_rpc(efx, MC_CMD_PRIVILEGE_MASK,697			  pm_inbuf, sizeof(pm_inbuf),698			  pm_outbuf, sizeof(pm_outbuf), &outlen);699 700	if (rc != 0)701		return rc;702	if (outlen != MC_CMD_PRIVILEGE_MASK_OUT_LEN)703		return -EIO;704 705	old_mask = MCDI_DWORD(pm_outbuf, PRIVILEGE_MASK_OUT_OLD_MASK);706 707	new_mask = old_mask & ~mask;708	new_mask |= value;709 710	if (new_mask == old_mask)711		return 0;712 713	new_mask |= MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE;714 715	/* Set privilege mask */716	MCDI_SET_DWORD(pm_inbuf, PRIVILEGE_MASK_IN_NEW_MASK, new_mask);717 718	rc = efx_mcdi_rpc(efx, MC_CMD_PRIVILEGE_MASK,719			  pm_inbuf, sizeof(pm_inbuf),720			  pm_outbuf, sizeof(pm_outbuf), &outlen);721 722	if (rc != 0)723		return rc;724	if (outlen != MC_CMD_PRIVILEGE_MASK_OUT_LEN)725		return -EIO;726 727	return 0;728}729 730int efx_ef10_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf_i, bool spoofchk)731{732	struct efx_ef10_nic_data *nic_data = efx->nic_data;733 734	/* Can't enable spoofchk if firmware doesn't support it. */735	if (!(nic_data->datapath_caps &736	      BIT(MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_LBN)) &&737	    spoofchk)738		return -EOPNOTSUPP;739 740	return efx_ef10_sriov_set_privilege_mask(efx, vf_i,741		MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING_TX,742		spoofchk ? 0 : MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING_TX);743}744 745int efx_ef10_sriov_set_vf_link_state(struct efx_nic *efx, int vf_i,746				     int link_state)747{748	MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_STATE_MODE_IN_LEN);749	struct efx_ef10_nic_data *nic_data = efx->nic_data;750 751	BUILD_BUG_ON(IFLA_VF_LINK_STATE_AUTO !=752		     MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO);753	BUILD_BUG_ON(IFLA_VF_LINK_STATE_ENABLE !=754		     MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP);755	BUILD_BUG_ON(IFLA_VF_LINK_STATE_DISABLE !=756		     MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN);757	MCDI_POPULATE_DWORD_2(inbuf, LINK_STATE_MODE_IN_FUNCTION,758			      LINK_STATE_MODE_IN_FUNCTION_PF,759			      nic_data->pf_index,760			      LINK_STATE_MODE_IN_FUNCTION_VF, vf_i);761	MCDI_SET_DWORD(inbuf, LINK_STATE_MODE_IN_NEW_MODE, link_state);762	return efx_mcdi_rpc(efx, MC_CMD_LINK_STATE_MODE, inbuf, sizeof(inbuf),763			    NULL, 0, NULL); /* don't care what old mode was */764}765 766int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i,767				 struct ifla_vf_info *ivf)768{769	MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_STATE_MODE_IN_LEN);770	MCDI_DECLARE_BUF(outbuf, MC_CMD_LINK_STATE_MODE_OUT_LEN);771 772	struct efx_ef10_nic_data *nic_data = efx->nic_data;773	struct ef10_vf *vf;774	size_t outlen;775	int rc;776 777	if (vf_i >= efx->vf_count)778		return -EINVAL;779 780	if (!nic_data->vf)781		return -EOPNOTSUPP;782 783	vf = nic_data->vf + vf_i;784 785	ivf->vf = vf_i;786	ivf->min_tx_rate = 0;787	ivf->max_tx_rate = 0;788	ether_addr_copy(ivf->mac, vf->mac);789	ivf->vlan = (vf->vlan == EFX_EF10_NO_VLAN) ? 0 : vf->vlan;790	ivf->qos = 0;791 792	MCDI_POPULATE_DWORD_2(inbuf, LINK_STATE_MODE_IN_FUNCTION,793			      LINK_STATE_MODE_IN_FUNCTION_PF,794			      nic_data->pf_index,795			      LINK_STATE_MODE_IN_FUNCTION_VF, vf_i);796	MCDI_SET_DWORD(inbuf, LINK_STATE_MODE_IN_NEW_MODE,797		       MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE);798	rc = efx_mcdi_rpc(efx, MC_CMD_LINK_STATE_MODE, inbuf, sizeof(inbuf),799			  outbuf, sizeof(outbuf), &outlen);800	if (rc)801		return rc;802	if (outlen < MC_CMD_LINK_STATE_MODE_OUT_LEN)803		return -EIO;804	ivf->linkstate = MCDI_DWORD(outbuf, LINK_STATE_MODE_OUT_OLD_MODE);805 806	return 0;807}808