summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorSudarsana Reddy Kalluru <sudarsana.kalluru@qlogic.com>2016-03-09 10:16:23 +0300
committerDavid S. Miller <davem@davemloft.net>2016-03-11 23:20:19 +0300
commitfc916ff2027760900f3b373c388a2098253f3c2a (patch)
tree3c6bcfd005285f06f2397c655122d11679f5a211 /drivers/net
parent627caa9d319d2402f3d41ebd8dd0fde9d41a33a7 (diff)
downloadlinux-fc916ff2027760900f3b373c388a2098253f3c2a.tar.xz
qed: Prevent MF link notifications
When device is configured for Multi-function mode, some older management firmware might incorrectly notify interfaces of link changes while they haven't requested the physical link configuration to be set. This can create bizzare race conditions where unloading interfaces are getting notified that the link is up. Let the driver compensate - store the logical requested state of the link and don't propagate notifications after protocol driver explicitly requires the link to be unset. Signed-off-by: Sudarsana Reddy Kalluru <sudarsana.kalluru@qlogic.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed.h3
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c7
2 files changed, 9 insertions, 1 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index e5604eec81bf..fcb8e9ba51d9 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -303,6 +303,9 @@ struct qed_hwfn {
bool b_int_enabled;
bool b_int_requested;
+ /* True if the driver requests for the link */
+ bool b_drv_link_init;
+
struct qed_mcp_info *mcp_info;
struct qed_hw_cid_data *p_tx_cids;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index f23ce734ab63..2bf98248c29e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -390,7 +390,10 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
return;
}
- p_link->link_up = !!(status & LINK_STATUS_LINK_UP);
+ if (p_hwfn->b_drv_link_init)
+ p_link->link_up = !!(status & LINK_STATUS_LINK_UP);
+ else
+ p_link->link_up = false;
p_link->full_duplex = true;
switch ((status & LINK_STATUS_SPEED_AND_DUPLEX_MASK)) {
@@ -520,6 +523,8 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn,
offsetof(struct public_drv_mb, union_data) + i,
((u32 *)&phy_cfg)[i >> 2]);
+ p_hwfn->b_drv_link_init = b_up;
+
if (b_up) {
DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
"Configuring Link: Speed 0x%08x, Pause 0x%08x, adv_speed 0x%08x, loopback 0x%08x, features 0x%08x\n",