All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shradha Shah <sshah@solarflare.com>
To: David Miller <davem@davemloft.net>
Cc: <netdev@vger.kernel.org>, <linux-net-drivers@solarflare.com>
Subject: [PATCH net-next 05/16] sfc: save old MAC address in case sriov_mac_address_changed fails
Date: Mon, 18 May 2015 16:28:34 +0100	[thread overview]
Message-ID: <555A0522.3050502@solarflare.com> (raw)
In-Reply-To: <555A044A.4060202@solarflare.com>

Otherwise the PF and VF can disagree on the VF's MAC address and
this leads to strange behaviour, up to and including kernel panics.

Signed-off-by: Shradha Shah <sshah@solarflare.com>
---
 drivers/net/ethernet/sfc/ef10_sriov.h  |  5 ++++-
 drivers/net/ethernet/sfc/efx.c         | 13 +++++++++++--
 drivers/net/ethernet/sfc/net_driver.h  |  2 +-
 drivers/net/ethernet/sfc/siena_sriov.c |  6 ++++--
 drivers/net/ethernet/sfc/siena_sriov.h |  2 +-
 5 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/sfc/ef10_sriov.h b/drivers/net/ethernet/sfc/ef10_sriov.h
index 86bac7eb..8b67163 100644
--- a/drivers/net/ethernet/sfc/ef10_sriov.h
+++ b/drivers/net/ethernet/sfc/ef10_sriov.h
@@ -31,7 +31,10 @@ static inline bool efx_ef10_sriov_wanted(struct efx_nic *efx)
 
 int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs);
 int efx_ef10_sriov_init(struct efx_nic *efx);
-static inline void efx_ef10_sriov_mac_address_changed(struct efx_nic *efx) {}
+static inline int efx_ef10_sriov_mac_address_changed(struct efx_nic *efx)
+{
+	return -EOPNOTSUPP;
+}
 static inline void efx_ef10_sriov_reset(struct efx_nic *efx) {}
 void efx_ef10_sriov_fini(struct efx_nic *efx);
 static inline void efx_ef10_sriov_flr(struct efx_nic *efx, unsigned vf_i) {}
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 0f127a0..864c337 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2196,6 +2196,8 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct sockaddr *addr = data;
 	u8 *new_addr = addr->sa_data;
+	u8 old_addr[6];
+	int rc;
 
 	if (!is_valid_ether_addr(new_addr)) {
 		netif_err(efx, drv, efx->net_dev,
@@ -2204,9 +2206,16 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
 		return -EADDRNOTAVAIL;
 	}
 
+	/* save old address */
+	ether_addr_copy(old_addr, net_dev->dev_addr);
 	ether_addr_copy(net_dev->dev_addr, new_addr);
-	if (efx->type->sriov_mac_address_changed)
-		efx->type->sriov_mac_address_changed(efx);
+	if (efx->type->sriov_mac_address_changed) {
+		rc = efx->type->sriov_mac_address_changed(efx);
+		if (rc) {
+			ether_addr_copy(net_dev->dev_addr, old_addr);
+			return rc;
+		}
+	}
 
 	/* Reconfigure the MAC */
 	mutex_lock(&efx->mac_lock);
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 031a338..55a5f48 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1334,7 +1334,7 @@ struct efx_nic_type {
 	int (*sriov_configure)(struct efx_nic *efx, int num_vfs);
 	int (*sriov_init)(struct efx_nic *efx);
 	void (*sriov_fini)(struct efx_nic *efx);
-	void (*sriov_mac_address_changed)(struct efx_nic *efx);
+	int (*sriov_mac_address_changed)(struct efx_nic *efx);
 	bool (*sriov_wanted)(struct efx_nic *efx);
 	void (*sriov_reset)(struct efx_nic *efx);
 	void (*sriov_flr)(struct efx_nic *efx, unsigned vf_i);
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
index caf701a..9d1c1aa 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -1474,16 +1474,18 @@ void efx_siena_sriov_flr(struct efx_nic *efx, unsigned vf_i)
 	vf->evq0_count = 0;
 }
 
-void efx_siena_sriov_mac_address_changed(struct efx_nic *efx)
+int efx_siena_sriov_mac_address_changed(struct efx_nic *efx)
 {
 	struct siena_nic_data *nic_data = efx->nic_data;
 	struct vfdi_status *vfdi_status = nic_data->vfdi_status.addr;
 
 	if (!efx->vf_init_count)
-		return;
+		return 0;
 	ether_addr_copy(vfdi_status->peers[0].mac_addr,
 			efx->net_dev->dev_addr);
 	queue_work(vfdi_workqueue, &nic_data->peer_work);
+
+	return 0;
 }
 
 void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
diff --git a/drivers/net/ethernet/sfc/siena_sriov.h b/drivers/net/ethernet/sfc/siena_sriov.h
index 64e3e01..d88d4da 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.h
+++ b/drivers/net/ethernet/sfc/siena_sriov.h
@@ -44,7 +44,7 @@
 int efx_siena_sriov_configure(struct efx_nic *efx, int num_vfs);
 int efx_siena_sriov_init(struct efx_nic *efx);
 void efx_siena_sriov_fini(struct efx_nic *efx);
-void efx_siena_sriov_mac_address_changed(struct efx_nic *efx);
+int efx_siena_sriov_mac_address_changed(struct efx_nic *efx);
 bool efx_siena_sriov_wanted(struct efx_nic *efx);
 void efx_siena_sriov_reset(struct efx_nic *efx);
 void efx_siena_sriov_flr(struct efx_nic *efx, unsigned flr);

  parent reply	other threads:[~2015-05-18 15:28 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-18 15:24 [PATCH net-next 00/16] sfc: Get/Set MAC address and ndo_[set/get]_vf_* entrypoint functions Shradha Shah
2015-05-18 15:27 ` [PATCH net-next 01/16] sfc: Add permissions to MCDI commands Shradha Shah
2015-05-18 16:21   ` David Miller
2015-05-18 15:27 ` [PATCH net-next 02/16] sfc: change definition of MC_CMD_VADAPTOR_ALLOC Shradha Shah
2015-05-18 15:27 ` [PATCH net-next 03/16] sfc: MC_CMD_SET_MAC can only be called by the link control Function Shradha Shah
2015-05-18 15:28 ` [PATCH net-next 04/16] sfc: Store vf_index in nic_data for Ef10 Shradha Shah
2015-05-18 15:28 ` Shradha Shah [this message]
2015-05-18 15:28 ` [PATCH net-next 06/16] sfc: Store the efx_nic struct of the current VF in the VF data struct Shradha Shah
2015-05-18 15:29 ` [PATCH net-next 07/16] sfc: protect filter table against use-after-free Shradha Shah
2015-05-18 15:29 ` [PATCH net-next 08/16] sfc: Enable a VF to get its own MAC address Shradha Shah
2015-05-18 15:29 ` [PATCH net-next 09/16] sfc: Initialise MCDI buffers to 0 on declaration Shradha Shah
2015-05-18 15:30 ` [PATCH net-next 10/16] sfc: add ndo_set_vf_mac() function for EF10 Shradha Shah
2015-05-18 15:30 ` [PATCH net-next 11/16] sfc: Add ndo_get_vf_config() " Shradha Shah
2015-05-18 15:30 ` [PATCH net-next 12/16] sfc: Change entity reset on MC reboot to a new datapath-only reset Shradha Shah
2015-05-18 15:31 ` [PATCH net-next 13/16] sfc: add ndo_set_vf_vlan() function for EF10 Shradha Shah
2015-05-18 15:31 ` [PATCH net-next 14/16] sfc: add ndo_set_vf_link_state() " Shradha Shah
2015-05-18 15:31 ` [PATCH net-next 15/16] sfc: Implement dummy disable of VF spoof check " Shradha Shah
2015-05-18 15:31 ` [PATCH net-next 16/16] sfc: set the MAC address using MC_CMD_VADAPTOR_SET_MAC Shradha Shah

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=555A0522.3050502@solarflare.com \
    --to=sshah@solarflare.com \
    --cc=davem@davemloft.net \
    --cc=linux-net-drivers@solarflare.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.