Skip to content

Commit

Permalink
net: Cavium: Fix MAC address setting in shutdown state
Browse files Browse the repository at this point in the history
This bug pops up with NetworkManager on Fedora 21. NetworkManager tends to
stop the interface (nicvf_stop() is called) before changing settings. In
stopped state MAC cannot be sent to a PF. However, when the interface is
restarted (nicvf_open() is called), we ping the PF using NIC_MBOX_MSG_READY
message, and the PF replies back with old MAC address, overriding what we
had after MAC setting from userspace. As a result, we cannot set MAC
address using NetworkManager.

This patch introduces special tracking of MAC change in stopped state so
that the correct new MAC address is sent to a PF when interface is reopen.

Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Pavel Fedin authored and David S. Miller committed Jun 24, 2015
1 parent 8beeef8 commit bd049a9
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/cavium/thunder/nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ struct nicvf {
bool pf_acked;
bool pf_nacked;
bool bgx_stats_acked;
bool set_mac_pending;
} ____cacheline_aligned_in_smp;

/* PF <--> VF Mailbox communication
Expand Down
14 changes: 12 additions & 2 deletions drivers/net/ethernet/cavium/thunder/nicvf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ static void nicvf_handle_mbx_intr(struct nicvf *nic)
nic->vf_id = mbx.nic_cfg.vf_id & 0x7F;
nic->tns_mode = mbx.nic_cfg.tns_mode & 0x7F;
nic->node = mbx.nic_cfg.node_id;
ether_addr_copy(nic->netdev->dev_addr, mbx.nic_cfg.mac_addr);
if (!nic->set_mac_pending)
ether_addr_copy(nic->netdev->dev_addr,
mbx.nic_cfg.mac_addr);
nic->link_up = false;
nic->duplex = 0;
nic->speed = 0;
Expand Down Expand Up @@ -941,6 +943,11 @@ int nicvf_open(struct net_device *netdev)
nicvf_hw_set_mac_addr(nic, netdev);
}

if (nic->set_mac_pending) {
nic->set_mac_pending = false;
nicvf_hw_set_mac_addr(nic, netdev);
}

/* Init tasklet for handling Qset err interrupt */
tasklet_init(&nic->qs_err_task, nicvf_handle_qs_err,
(unsigned long)nic);
Expand Down Expand Up @@ -1040,9 +1047,12 @@ static int nicvf_set_mac_address(struct net_device *netdev, void *p)

memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);

if (nic->msix_enabled)
if (nic->msix_enabled) {
if (nicvf_hw_set_mac_addr(nic, netdev))
return -EBUSY;
} else {
nic->set_mac_pending = true;
}

return 0;
}
Expand Down

0 comments on commit bd049a9

Please sign in to comment.