hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/ethernet/sfc/ef10_sriov.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /****************************************************************************
23 * Driver for Solarflare network controllers and boards
34 * Copyright 2015 Solarflare Communications Inc.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms of the GNU General Public License version 2 as published
7
- * by the Free Software Foundation, incorporated herein by reference.
85 */
96 #include <linux/etherdevice.h>
107 #include <linux/pci.h>
....@@ -235,15 +232,14 @@
235232
236233 static int efx_ef10_vadaptor_alloc_set_features(struct efx_nic *efx)
237234 {
238
- struct efx_ef10_nic_data *nic_data = efx->nic_data;
239235 u32 port_flags;
240236 int rc;
241237
242
- rc = efx_ef10_vadaptor_alloc(efx, nic_data->vport_id);
238
+ rc = efx_ef10_vadaptor_alloc(efx, efx->vport_id);
243239 if (rc)
244240 goto fail_vadaptor_alloc;
245241
246
- rc = efx_ef10_vadaptor_query(efx, nic_data->vport_id,
242
+ rc = efx_ef10_vadaptor_query(efx, efx->vport_id,
247243 &port_flags, NULL, NULL);
248244 if (rc)
249245 goto fail_vadaptor_query;
....@@ -284,11 +280,11 @@
284280
285281 rc = efx_ef10_vport_alloc(efx, EVB_PORT_ID_ASSIGNED,
286282 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL,
287
- EFX_EF10_NO_VLAN, &nic_data->vport_id);
283
+ EFX_EF10_NO_VLAN, &efx->vport_id);
288284 if (rc)
289285 goto fail2;
290286
291
- rc = efx_ef10_vport_add_mac(efx, nic_data->vport_id, net_dev->dev_addr);
287
+ rc = efx_ef10_vport_add_mac(efx, efx->vport_id, net_dev->dev_addr);
292288 if (rc)
293289 goto fail3;
294290 ether_addr_copy(nic_data->vport_mac, net_dev->dev_addr);
....@@ -299,11 +295,11 @@
299295
300296 return 0;
301297 fail4:
302
- efx_ef10_vport_del_mac(efx, nic_data->vport_id, nic_data->vport_mac);
298
+ efx_ef10_vport_del_mac(efx, efx->vport_id, nic_data->vport_mac);
303299 eth_zero_addr(nic_data->vport_mac);
304300 fail3:
305
- efx_ef10_vport_free(efx, nic_data->vport_id);
306
- nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
301
+ efx_ef10_vport_free(efx, efx->vport_id);
302
+ efx->vport_id = EVB_PORT_ID_ASSIGNED;
307303 fail2:
308304 efx_ef10_vswitch_free(efx, EVB_PORT_ID_ASSIGNED);
309305 fail1:
....@@ -358,22 +354,22 @@
358354
359355 efx_ef10_sriov_free_vf_vswitching(efx);
360356
361
- efx_ef10_vadaptor_free(efx, nic_data->vport_id);
357
+ efx_ef10_vadaptor_free(efx, efx->vport_id);
362358
363
- if (nic_data->vport_id == EVB_PORT_ID_ASSIGNED)
359
+ if (efx->vport_id == EVB_PORT_ID_ASSIGNED)
364360 return; /* No vswitch was ever created */
365361
366362 if (!is_zero_ether_addr(nic_data->vport_mac)) {
367
- efx_ef10_vport_del_mac(efx, nic_data->vport_id,
363
+ efx_ef10_vport_del_mac(efx, efx->vport_id,
368364 efx->net_dev->dev_addr);
369365 eth_zero_addr(nic_data->vport_mac);
370366 }
371
- efx_ef10_vport_free(efx, nic_data->vport_id);
372
- nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
367
+ efx_ef10_vport_free(efx, efx->vport_id);
368
+ efx->vport_id = EVB_PORT_ID_ASSIGNED;
373369
374370 /* Only free the vswitch if no VFs are assigned */
375371 if (!pci_vfs_assigned(efx->pci_dev))
376
- efx_ef10_vswitch_free(efx, nic_data->vport_id);
372
+ efx_ef10_vswitch_free(efx, efx->vport_id);
377373 }
378374
379375 void efx_ef10_vswitching_remove_vf(struct efx_nic *efx)
....@@ -415,8 +411,9 @@
415411 static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)
416412 {
417413 struct pci_dev *dev = efx->pci_dev;
414
+ struct efx_ef10_nic_data *nic_data = efx->nic_data;
418415 unsigned int vfs_assigned = pci_vfs_assigned(dev);
419
- int rc = 0;
416
+ int i, rc = 0;
420417
421418 if (vfs_assigned && !force) {
422419 netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "
....@@ -424,10 +421,13 @@
424421 return -EBUSY;
425422 }
426423
427
- if (!vfs_assigned)
424
+ if (!vfs_assigned) {
425
+ for (i = 0; i < efx->vf_count; i++)
426
+ nic_data->vf[i].pci_dev = NULL;
428427 pci_disable_sriov(dev);
429
- else
428
+ } else {
430429 rc = -EBUSY;
430
+ }
431431
432432 efx_ef10_sriov_free_vf_vswitching(efx);
433433 efx->vf_count = 0;
....@@ -524,10 +524,9 @@
524524
525525 if (!is_zero_ether_addr(mac)) {
526526 rc = efx_ef10_vport_add_mac(efx, vf->vport_id, mac);
527
- if (rc) {
528
- eth_zero_addr(vf->mac);
527
+ if (rc)
529528 goto fail;
530
- }
529
+
531530 if (vf->efx)
532531 ether_addr_copy(vf->efx->net_dev->dev_addr, mac);
533532 }
....@@ -688,10 +687,70 @@
688687 return rc ? rc : rc2;
689688 }
690689
691
-int efx_ef10_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf_i,
692
- bool spoofchk)
690
+static int efx_ef10_sriov_set_privilege_mask(struct efx_nic *efx, int vf_i,
691
+ u32 mask, u32 value)
693692 {
694
- return spoofchk ? -EOPNOTSUPP : 0;
693
+ MCDI_DECLARE_BUF(pm_outbuf, MC_CMD_PRIVILEGE_MASK_OUT_LEN);
694
+ MCDI_DECLARE_BUF(pm_inbuf, MC_CMD_PRIVILEGE_MASK_IN_LEN);
695
+ struct efx_ef10_nic_data *nic_data = efx->nic_data;
696
+ u32 old_mask, new_mask;
697
+ size_t outlen;
698
+ int rc;
699
+
700
+ EFX_WARN_ON_PARANOID((value & ~mask) != 0);
701
+
702
+ /* Get privilege mask */
703
+ MCDI_POPULATE_DWORD_2(pm_inbuf, PRIVILEGE_MASK_IN_FUNCTION,
704
+ PRIVILEGE_MASK_IN_FUNCTION_PF, nic_data->pf_index,
705
+ PRIVILEGE_MASK_IN_FUNCTION_VF, vf_i);
706
+
707
+ rc = efx_mcdi_rpc(efx, MC_CMD_PRIVILEGE_MASK,
708
+ pm_inbuf, sizeof(pm_inbuf),
709
+ pm_outbuf, sizeof(pm_outbuf), &outlen);
710
+
711
+ if (rc != 0)
712
+ return rc;
713
+ if (outlen != MC_CMD_PRIVILEGE_MASK_OUT_LEN)
714
+ return -EIO;
715
+
716
+ old_mask = MCDI_DWORD(pm_outbuf, PRIVILEGE_MASK_OUT_OLD_MASK);
717
+
718
+ new_mask = old_mask & ~mask;
719
+ new_mask |= value;
720
+
721
+ if (new_mask == old_mask)
722
+ return 0;
723
+
724
+ new_mask |= MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE;
725
+
726
+ /* Set privilege mask */
727
+ MCDI_SET_DWORD(pm_inbuf, PRIVILEGE_MASK_IN_NEW_MASK, new_mask);
728
+
729
+ rc = efx_mcdi_rpc(efx, MC_CMD_PRIVILEGE_MASK,
730
+ pm_inbuf, sizeof(pm_inbuf),
731
+ pm_outbuf, sizeof(pm_outbuf), &outlen);
732
+
733
+ if (rc != 0)
734
+ return rc;
735
+ if (outlen != MC_CMD_PRIVILEGE_MASK_OUT_LEN)
736
+ return -EIO;
737
+
738
+ return 0;
739
+}
740
+
741
+int efx_ef10_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf_i, bool spoofchk)
742
+{
743
+ struct efx_ef10_nic_data *nic_data = efx->nic_data;
744
+
745
+ /* Can't enable spoofchk if firmware doesn't support it. */
746
+ if (!(nic_data->datapath_caps &
747
+ BIT(MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_LBN)) &&
748
+ spoofchk)
749
+ return -EOPNOTSUPP;
750
+
751
+ return efx_ef10_sriov_set_privilege_mask(efx, vf_i,
752
+ MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING_TX,
753
+ spoofchk ? 0 : MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING_TX);
695754 }
696755
697756 int efx_ef10_sriov_set_vf_link_state(struct efx_nic *efx, int vf_i,