aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet/be_cmds.c
diff options
context:
space:
mode:
authorSathya Perla <sathyap@serverengines.com>2009-06-17 20:10:27 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-19 03:18:42 -0400
commita8f447bda3ee00e3a3ab080c48db40078ea65221 (patch)
tree7b164e3dd0dee5da5229462c668c98a6297517a3 /drivers/net/benet/be_cmds.c
parent24307eef74bd38e3fc6a6df8f8a1bfc48967f9f6 (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.c34
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 */
73static 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
80static 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
73static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl) 87static 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
788int be_cmd_link_status_query(struct be_ctrl_info *ctrl, 809int 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);