Commit 67ab160e authored by Edward Cree's avatar Edward Cree Committed by Jakub Kicinski
Browse files

sfc: insert default MAE rules to connect VFs to representors



Default rules are low-priority switching rules which the hardware uses
 in the absence of higher-priority rules.  Each representor requires a
 corresponding rule matching traffic from its representee VF and
 delivering to the PF (where a check on INGRESS_MPORT in
 __ef100_rx_packet() will direct it to the representor).  No rule is
 required in the reverse direction, because representor TX uses a TX
 override descriptor to bypass the MAE and deliver directly to the VF.
Since inserting any rule into the MAE disables the firmware's own
 default rules, also insert a pair of rules to connect the PF to the
 physical network port and vice-versa.

Signed-off-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f50e8fcd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -8,7 +8,8 @@ sfc-y += efx.o efx_common.o efx_channels.o nic.o \
			   ef100.o ef100_nic.o ef100_netdev.o \
			   ef100_ethtool.o ef100_rx.o ef100_tx.o
sfc-$(CONFIG_SFC_MTD)	+= mtd.o
sfc-$(CONFIG_SFC_SRIOV)	+= sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o mae.o
sfc-$(CONFIG_SFC_SRIOV)	+= sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
                           mae.o tc.o

obj-$(CONFIG_SFC)	+= sfc.o

+3 −0
Original line number Diff line number Diff line
@@ -431,6 +431,9 @@ static void ef100_pci_remove(struct pci_dev *pci_dev)

	probe_data = container_of(efx, struct efx_probe_data, efx);
	ef100_remove_netdev(probe_data);
#ifdef CONFIG_SFC_SRIOV
	efx_fini_struct_tc(efx);
#endif

	ef100_remove(efx);
	efx_fini_io(efx);
+4 −0
Original line number Diff line number Diff line
@@ -329,6 +329,10 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)

	ef100_unregister_netdev(efx);

#ifdef CONFIG_SFC_SRIOV
	efx_fini_tc(efx);
#endif

	down_write(&efx->filter_sem);
	efx_mcdi_filter_table_remove(efx);
	up_write(&efx->filter_sem);
+17 −0
Original line number Diff line number Diff line
@@ -1094,12 +1094,29 @@ int ef100_probe_netdev_pf(struct efx_nic *efx)
		return 0;

#ifdef CONFIG_SFC_SRIOV
	rc = efx_init_struct_tc(efx);
	if (rc)
		return rc;

	rc = efx_ef100_get_base_mport(efx);
	if (rc) {
		netif_warn(efx, probe, net_dev,
			   "Failed to probe base mport rc %d; representors will not function\n",
			   rc);
	}

	rc = efx_init_tc(efx);
	if (rc) {
		/* Either we don't have an MAE at all (i.e. legacy v-switching),
		 * or we do but we failed to probe it.  In the latter case, we
		 * may not have set up default rules, in which case we won't be
		 * able to pass any traffic.  However, we don't fail the probe,
		 * because the user might need to use the netdevice to apply
		 * configuration changes to fix whatever's wrong with the MAE.
		 */
		netif_warn(efx, probe, net_dev, "Failed to probe MAE rc %d\n",
			   rc);
	}
#endif
	return 0;

+16 −4
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv,
	efv->parent = efx;
	efv->idx = i;
	INIT_LIST_HEAD(&efv->list);
	efv->dflt.fw_id = MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL;
	INIT_LIST_HEAD(&efv->dflt.acts.list);
	INIT_LIST_HEAD(&efv->rx_list);
	spin_lock_init(&efv->rx_lock);
	efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE |
@@ -212,7 +214,14 @@ static int efx_ef100_configure_rep(struct efx_rep *efv)
	/* mport label should fit in 16 bits */
	WARN_ON(efv->mport >> 16);

	return 0;
	return efx_tc_configure_default_rule_rep(efv);
}

static void efx_ef100_deconfigure_rep(struct efx_rep *efv)
{
	struct efx_nic *efx = efv->parent;

	efx_tc_deconfigure_default_rule(efx, &efv->dflt);
}

static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv)
@@ -246,19 +255,21 @@ int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
		pci_err(efx->pci_dev,
			"Failed to configure representor for VF %d, rc %d\n",
			i, rc);
		goto fail;
		goto fail1;
	}
	rc = register_netdev(efv->net_dev);
	if (rc) {
		pci_err(efx->pci_dev,
			"Failed to register representor for VF %d, rc %d\n",
			i, rc);
		goto fail;
		goto fail2;
	}
	pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i,
		efv->net_dev->name);
	return 0;
fail:
fail2:
	efx_ef100_deconfigure_rep(efv);
fail1:
	efx_ef100_rep_destroy_netdev(efv);
	return rc;
}
@@ -272,6 +283,7 @@ void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv)
		return;
	netif_dbg(efx, drv, rep_dev, "Removing VF representor\n");
	unregister_netdev(rep_dev);
	efx_ef100_deconfigure_rep(efv);
	efx_ef100_rep_destroy_netdev(efv);
}

Loading