diff options
author | Ajay Singh <ajay.kathat@microchip.com> | 2020-11-25 11:41:08 +0000 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2020-12-02 21:38:07 +0200 |
commit | c04fabacb780b6d8dbc2e7258b383d7a91f69ad9 (patch) | |
tree | bcf385954f3b3baaef5e0c4be4a546a63588d7f7 /drivers/net/wireless/microchip/wilc1000/netdev.c | |
parent | 75729e110e680687668fd5b4bdd7b25c92e9c00d (diff) |
wilc1000: added 'ndo_set_mac_address' callback support
Added support for 'ndo_set_mac_address call' callback to allow change of
interface MAC address.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20201125114059.10006-2-ajay.kathat@microchip.com
Diffstat (limited to 'drivers/net/wireless/microchip/wilc1000/netdev.c')
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/netdev.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 20615c7ec168..2a1fbbdd6a4b 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -628,6 +628,43 @@ static struct net_device_stats *mac_stats(struct net_device *dev) return &vif->netstats; } +static int wilc_set_mac_addr(struct net_device *dev, void *p) +{ + int result; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; + struct sockaddr *addr = (struct sockaddr *)p; + unsigned char mac_addr[ETH_ALEN]; + struct wilc_vif *tmp_vif; + int srcu_idx; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + + srcu_idx = srcu_read_lock(&wilc->srcu); + list_for_each_entry_rcu(tmp_vif, &wilc->vif_list, list) { + wilc_get_mac_address(tmp_vif, mac_addr); + if (ether_addr_equal(addr->sa_data, mac_addr)) { + if (vif != tmp_vif) { + srcu_read_unlock(&wilc->srcu, srcu_idx); + return -EINVAL; + } + srcu_read_unlock(&wilc->srcu, srcu_idx); + return 0; + } + } + srcu_read_unlock(&wilc->srcu, srcu_idx); + + result = wilc_set_mac_address(vif, (u8 *)addr->sa_data); + if (result) + return result; + + ether_addr_copy(vif->bssid, addr->sa_data); + ether_addr_copy(vif->ndev->dev_addr, addr->sa_data); + + return result; +} + static void wilc_set_multicast_list(struct net_device *dev) { struct netdev_hw_addr *ha; @@ -813,6 +850,7 @@ static const struct net_device_ops wilc_netdev_ops = { .ndo_init = mac_init_fn, .ndo_open = wilc_mac_open, .ndo_stop = wilc_mac_close, + .ndo_set_mac_address = wilc_set_mac_addr, .ndo_start_xmit = wilc_mac_xmit, .ndo_get_stats = mac_stats, .ndo_set_rx_mode = wilc_set_multicast_list, |