]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wilc1000: Bring MAC address setting in line with typical Linux behavior
authorDavid Mosberger-Tang <davidm@egauge.net>
Wed, 3 Mar 2021 19:50:07 +0000 (19:50 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 May 2021 08:29:34 +0000 (10:29 +0200)
[ Upstream commit a381b78a1598dde34a6e40dae2842024308a6ef2 ]

Linux network drivers normally disallow changing the MAC address when
the interface is up.  This driver has been different in that it allows
to change the MAC address *only* when it's up.  This patch brings
wilc1000 behavior more in line with other network drivers.  We could
have replaced wilc_set_mac_addr() with eth_mac_addr() but that would
break existing documentation on how to change the MAC address.
Likewise, return -EADDRNOTAVAIL (not -EINVAL) when the specified MAC
address is invalid or unavailable.

Signed-off-by: David Mosberger-Tang <davidm@egauge.net>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210303194846.1823596-1-davidm@egauge.net
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/microchip/wilc1000/netdev.c

index 0c188310919e1379546c8bf0430ebc0a714c7366..acf7ed4bfe57b1b71d3ff5dacd593f01e971f32e 100644 (file)
@@ -575,7 +575,6 @@ static int wilc_mac_open(struct net_device *ndev)
 {
        struct wilc_vif *vif = netdev_priv(ndev);
        struct wilc *wl = vif->wilc;
-       unsigned char mac_add[ETH_ALEN] = {0};
        int ret = 0;
        struct mgmt_frame_regs mgmt_regs = {};
 
@@ -598,9 +597,12 @@ static int wilc_mac_open(struct net_device *ndev)
 
        wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
                                vif->idx);
-       wilc_get_mac_address(vif, mac_add);
-       netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
-       ether_addr_copy(ndev->dev_addr, mac_add);
+
+       if (is_valid_ether_addr(ndev->dev_addr))
+               wilc_set_mac_address(vif, ndev->dev_addr);
+       else
+               wilc_get_mac_address(vif, ndev->dev_addr);
+       netdev_dbg(ndev, "Mac address: %pM\n", ndev->dev_addr);
 
        if (!is_valid_ether_addr(ndev->dev_addr)) {
                netdev_err(ndev, "Wrong MAC address\n");
@@ -639,7 +641,14 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p)
        int srcu_idx;
 
        if (!is_valid_ether_addr(addr->sa_data))
-               return -EINVAL;
+               return -EADDRNOTAVAIL;
+
+       if (!vif->mac_opened) {
+               eth_commit_mac_addr_change(dev, p);
+               return 0;
+       }
+
+       /* Verify MAC Address is not already in use: */
 
        srcu_idx = srcu_read_lock(&wilc->srcu);
        list_for_each_entry_rcu(tmp_vif, &wilc->vif_list, list) {
@@ -647,7 +656,7 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p)
                if (ether_addr_equal(addr->sa_data, mac_addr)) {
                        if (vif != tmp_vif) {
                                srcu_read_unlock(&wilc->srcu, srcu_idx);
-                               return -EINVAL;
+                               return -EADDRNOTAVAIL;
                        }
                        srcu_read_unlock(&wilc->srcu, srcu_idx);
                        return 0;
@@ -659,9 +668,7 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p)
        if (result)
                return result;
 
-       ether_addr_copy(vif->bssid, addr->sa_data);
-       ether_addr_copy(vif->ndev->dev_addr, addr->sa_data);
-
+       eth_commit_mac_addr_change(dev, p);
        return result;
 }