diff options
author | Sathya Perla <sathyap@serverengines.com> | 2009-06-17 20:10:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-19 03:18:42 -0400 |
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 4a2e1f518f78..583517ed56f0 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, | |||
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
72 | /* Link state evt is a string of bytes; no need for endian swapping */ | ||
73 | static void be_async_link_state_process(struct be_ctrl_info *ctrl, | ||
74 | struct be_async_event_link_state *evt) | ||
75 | { | ||
76 | ctrl->async_cb(ctrl->adapter_ctxt, | ||
77 | evt->port_link_status == ASYNC_EVENT_LINK_UP ? true : false); | ||
78 | } | ||
79 | |||
80 | static inline bool is_link_state_evt(u32 trailer) | ||
81 | { | ||
82 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | ||
83 | ASYNC_TRAILER_EVENT_CODE_MASK) == | ||
84 | ASYNC_EVENT_CODE_LINK_STATE); | ||
85 | } | ||
72 | 86 | ||
73 | static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl) | 87 | static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl) |
74 | { | 88 | { |
@@ -89,7 +103,14 @@ void be_process_mcc(struct be_ctrl_info *ctrl) | |||
89 | 103 | ||
90 | spin_lock_bh(&ctrl->mcc_cq_lock); | 104 | spin_lock_bh(&ctrl->mcc_cq_lock); |
91 | while ((compl = be_mcc_compl_get(ctrl))) { | 105 | while ((compl = be_mcc_compl_get(ctrl))) { |
92 | if (!(compl->flags & CQE_FLAGS_ASYNC_MASK)) { | 106 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { |
107 | /* Interpret flags as an async trailer */ | ||
108 | BUG_ON(!is_link_state_evt(compl->flags)); | ||
109 | |||
110 | /* Interpret compl as a async link evt */ | ||
111 | be_async_link_state_process(ctrl, | ||
112 | (struct be_async_event_link_state *) compl); | ||
113 | } else { | ||
93 | be_mcc_compl_process(ctrl, compl); | 114 | be_mcc_compl_process(ctrl, compl); |
94 | atomic_dec(&ctrl->mcc_obj.q.used); | 115 | atomic_dec(&ctrl->mcc_obj.q.used); |
95 | } | 116 | } |
@@ -786,13 +807,15 @@ int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd) | |||
786 | } | 807 | } |
787 | 808 | ||
788 | int be_cmd_link_status_query(struct be_ctrl_info *ctrl, | 809 | int be_cmd_link_status_query(struct be_ctrl_info *ctrl, |
789 | struct be_link_info *link) | 810 | bool *link_up) |
790 | { | 811 | { |
791 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 812 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); |
792 | struct be_cmd_req_link_status *req = embedded_payload(wrb); | 813 | struct be_cmd_req_link_status *req = embedded_payload(wrb); |
793 | int status; | 814 | int status; |
794 | 815 | ||
795 | spin_lock(&ctrl->mbox_lock); | 816 | spin_lock(&ctrl->mbox_lock); |
817 | |||
818 | *link_up = false; | ||
796 | memset(wrb, 0, sizeof(*wrb)); | 819 | memset(wrb, 0, sizeof(*wrb)); |
797 | 820 | ||
798 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 821 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -803,11 +826,8 @@ int be_cmd_link_status_query(struct be_ctrl_info *ctrl, | |||
803 | status = be_mbox_db_ring(ctrl); | 826 | status = be_mbox_db_ring(ctrl); |
804 | if (!status) { | 827 | if (!status) { |
805 | struct be_cmd_resp_link_status *resp = embedded_payload(wrb); | 828 | struct be_cmd_resp_link_status *resp = embedded_payload(wrb); |
806 | link->speed = resp->mac_speed; | 829 | if (resp->mac_speed != PHY_LINK_SPEED_ZERO) |
807 | link->duplex = resp->mac_duplex; | 830 | *link_up = true; |
808 | link->fault = resp->mac_fault; | ||
809 | } else { | ||
810 | link->speed = PHY_LINK_SPEED_ZERO; | ||
811 | } | 831 | } |
812 | 832 | ||
813 | spin_unlock(&ctrl->mbox_lock); | 833 | spin_unlock(&ctrl->mbox_lock); |