diff options
author | Michal Kalderon <Michal.Kalderon@cavium.com> | 2017-06-20 16:00:06 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-20 12:34:09 -0400 |
commit | 6c9e80ea571db545a0baff1e0f48ae75a7ed127d (patch) | |
tree | ade832593cfe1483048945a37ddbcd3df4445f60 /drivers/net/ethernet/qlogic/qed/qed_spq.c | |
parent | 898fff120d9e73c2432432d4e457bf584b2a9df7 (diff) | |
download | linux-6c9e80ea571db545a0baff1e0f48ae75a7ed127d.tar.bz2 |
qed: SPQ async callback registration
Whenever firmware indicates that there's an async indication it needs
to handle, there's a switch-case where the right functionality is called
based on function's personality and information.
Before iWARP is added [as yet another client], switch over the SPQ into
a callback-registered mechanism, allowing registration of the relevant
event-processing logic based on the function's personality. This allows
us to tidy the code by removing protocol-specifics from a common file.
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qed/qed_spq.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_spq.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c index a971916af7cc..78954d2c596e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c @@ -302,32 +302,16 @@ static int qed_async_event_completion(struct qed_hwfn *p_hwfn, struct event_ring_entry *p_eqe) { - switch (p_eqe->protocol_id) { -#if IS_ENABLED(CONFIG_QED_RDMA) - case PROTOCOLID_ROCE: - qed_roce_async_event(p_hwfn, p_eqe->opcode, - &p_eqe->data.rdma_data); - return 0; -#endif - case PROTOCOLID_COMMON: - return qed_sriov_eqe_event(p_hwfn, - p_eqe->opcode, - p_eqe->echo, &p_eqe->data); - case PROTOCOLID_ISCSI: - if (!IS_ENABLED(CONFIG_QED_ISCSI)) - return -EINVAL; + qed_spq_async_comp_cb cb; - if (p_hwfn->p_iscsi_info->event_cb) { - struct qed_iscsi_info *p_iscsi = p_hwfn->p_iscsi_info; + if (!p_hwfn->p_spq || (p_eqe->protocol_id >= MAX_PROTOCOL_TYPE)) + return -EINVAL; - return p_iscsi->event_cb(p_iscsi->event_context, - p_eqe->opcode, &p_eqe->data); - } else { - DP_NOTICE(p_hwfn, - "iSCSI async completion is not set\n"); - return -EINVAL; - } - default: + cb = p_hwfn->p_spq->async_comp_cb[p_eqe->protocol_id]; + if (cb) { + return cb(p_hwfn, p_eqe->opcode, p_eqe->echo, + &p_eqe->data, p_eqe->fw_return_code); + } else { DP_NOTICE(p_hwfn, "Unknown Async completion for protocol: %d\n", p_eqe->protocol_id); @@ -335,6 +319,28 @@ qed_async_event_completion(struct qed_hwfn *p_hwfn, } } +int +qed_spq_register_async_cb(struct qed_hwfn *p_hwfn, + enum protocol_type protocol_id, + qed_spq_async_comp_cb cb) +{ + if (!p_hwfn->p_spq || (protocol_id >= MAX_PROTOCOL_TYPE)) + return -EINVAL; + + p_hwfn->p_spq->async_comp_cb[protocol_id] = cb; + return 0; +} + +void +qed_spq_unregister_async_cb(struct qed_hwfn *p_hwfn, + enum protocol_type protocol_id) +{ + if (!p_hwfn->p_spq || (protocol_id >= MAX_PROTOCOL_TYPE)) + return; + + p_hwfn->p_spq->async_comp_cb[protocol_id] = NULL; +} + /*************************************************************************** * EQ API ***************************************************************************/ |