diff options
author | Sathya Perla <sathyap@serverengines.com> | 2009-06-18 00:10:27 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-19 00:18:42 -0700 |
commit | a8f447bda3ee00e3a3ab080c48db40078ea65221 (patch) | |
tree | 7b164e3dd0dee5da5229462c668c98a6297517a3 /drivers/net/benet/be_cmds.c | |
parent | 24307eef74bd38e3fc6a6df8f8a1bfc48967f9f6 (diff) |
be2net: receive asynchronous link status notifications from BE
Rcv and process ansync link status notifications from BE instead of polling
for link status in the be_worker thread.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be_cmds.c')
-rw-r--r-- | drivers/net/benet/be_cmds.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 4a2e1f518f7..583517ed56f 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -69,6 +69,20 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, return 0; } +/* Link state evt is a string of bytes; no need for endian swapping */ +static void be_async_link_state_process(struct be_ctrl_info *ctrl, + struct be_async_event_link_state *evt) +{ + ctrl->async_cb(ctrl->adapter_ctxt, + evt->port_link_status == ASYNC_EVENT_LINK_UP ? true : false); +} + +static inline bool is_link_state_evt(u32 trailer) +{ + return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & + ASYNC_TRAILER_EVENT_CODE_MASK) == + ASYNC_EVENT_CODE_LINK_STATE); +} static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl) { @@ -89,7 +103,14 @@ void be_process_mcc(struct be_ctrl_info *ctrl) spin_lock_bh(&ctrl->mcc_cq_lock); while ((compl = be_mcc_compl_get(ctrl))) { - if (!(compl->flags & CQE_FLAGS_ASYNC_MASK)) { + if (compl->flags & CQE_FLAGS_ASYNC_MASK) { + /* Interpret flags as an async trailer */ + BUG_ON(!is_link_state_evt(compl->flags)); + + /* Interpret compl as a async link evt */ + be_async_link_state_process(ctrl, + (struct be_async_event_link_state *) compl); + } else { be_mcc_compl_process(ctrl, compl); atomic_dec(&ctrl->mcc_obj.q.used); } @@ -786,13 +807,15 @@ int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd) } int be_cmd_link_status_query(struct be_ctrl_info *ctrl, - struct be_link_info *link) + bool *link_up) { struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); struct be_cmd_req_link_status *req = embedded_payload(wrb); int status; spin_lock(&ctrl->mbox_lock); + + *link_up = false; memset(wrb, 0, sizeof(*wrb)); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -803,11 +826,8 @@ int be_cmd_link_status_query(struct be_ctrl_info *ctrl, status = be_mbox_db_ring(ctrl); if (!status) { struct be_cmd_resp_link_status *resp = embedded_payload(wrb); - link->speed = resp->mac_speed; - link->duplex = resp->mac_duplex; - link->fault = resp->mac_fault; - } else { - link->speed = PHY_LINK_SPEED_ZERO; + if (resp->mac_speed != PHY_LINK_SPEED_ZERO) + *link_up = true; } spin_unlock(&ctrl->mbox_lock); |