From: Edward Cree Date: Tue, 5 May 2015 23:59:18 +0000 (+0100) Subject: sfc: Cope with permissions enforcement added to firmware for SR-IOV X-Git-Tag: omap-for-v4.2/fixes-rc1^2~134^2~352^2~2 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=267d9d73872966c4e7d0271fed314d8ace65e895;p=pandora-kernel.git sfc: Cope with permissions enforcement added to firmware for SR-IOV * Accept EPERM in some simple cases, the following cases are handled: 1) efx_mcdi_read_assertion() Unprivileged PCI functions aren't allowed to GET_ASSERTS. We return success as it's up to the primary PF to deal with asserts. 2) efx_mcdi_mon_probe() in efx_ef10_probe() Unprivileged PCI functions aren't allowed to read sensor info, and worrying about sensor data is the primary PF's job. 3) phy_op->reconfigure() in efx_init_port() and efx_reset_up() Unprivileged functions aren't allowed to MC_CMD_SET_LINK, they just have to accept the settings (including flow-control, which is what efx_init_port() is worried about) they've been given. 4) Fallback to GET_WORKAROUNDS in efx_ef10_probe() Unprivileged PCI functions aren't allowed to set workarounds. So if efx_mcdi_set_workaround() fails EPERM, use efx_mcdi_get_workarounds() to find out if workaround_35388 is enabled. 5) If DRV_ATTACH gets EPERM, try without specifying fw-variant Unprivileged PCI functions have to use a FIRMWARE_ID of 0xffffffff (MC_CMD_FW_DONT_CARE). 6) Don't try to exit_assertion unless one had fired Previously we called efx_mcdi_exit_assertion even if efx_mcdi_read_assertion had received MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS. This is unnecessary, and the resulting MC_CMD_REBOOT, even if the AFTER_ASSERTION flag made it a no-op, would fail EPERM for unprivileged PCI functions. So make efx_mcdi_read_assertion return whether an assert happened, and only call efx_mcdi_exit_assertion if it has. Signed-off-by: Shradha Shah Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 0dff8123da04..ae0ed2aa6eca 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -286,10 +286,22 @@ static int efx_ef10_probe(struct efx_nic *efx) goto fail3; efx->timer_quantum_ns = 1536000 / rc; /* 1536 cycles */ - /* Check whether firmware supports bug 35388 workaround */ + /* Check whether firmware supports bug 35388 workaround. + * First try to enable it, then if we get EPERM, just + * ask if it's already enabled + */ rc = efx_mcdi_set_workaround(efx, MC_CMD_WORKAROUND_BUG35388, true); if (rc == 0) nic_data->workaround_35388 = true; + else if (rc == -EPERM) { + unsigned int enabled; + + rc = efx_mcdi_get_workarounds(efx, NULL, &enabled); + if (rc) + goto fail3; + nic_data->workaround_35388 = enabled & + MC_CMD_GET_WORKAROUNDS_OUT_BUG35388; + } else if (rc != -ENOSYS && rc != -ENOENT) goto fail3; netif_dbg(efx, probe, efx->net_dev, @@ -297,7 +309,7 @@ static int efx_ef10_probe(struct efx_nic *efx) nic_data->workaround_35388 ? "en" : "dis"); rc = efx_mcdi_mon_probe(efx); - if (rc) + if (rc && rc != -EPERM) goto fail3; efx_ptp_probe(efx, NULL); Reading git-diff-tree failed