aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qed/qed_spq.c
diff options
context:
space:
mode:
authorRahul Verma <Rahul.Verma@cavium.com>2017-04-06 15:58:29 +0300
committerDavid S. Miller <davem@davemloft.net>2017-04-06 14:26:31 -0700
commit1558296251207bb0def2ae7cc045f8159ee0c204 (patch)
tree78dfe47aa021d543d3e12b5fb4df12796a8dee87 /drivers/net/ethernet/qlogic/qed/qed_spq.c
parentqed: Warn PTT usage by wrong hw-function (diff)
downloadlinux-dev-1558296251207bb0def2ae7cc045f8159ee0c204.tar.xz
linux-dev-1558296251207bb0def2ae7cc045f8159ee0c204.zip
qed: Don't use main-ptt in unrelated flows
In order to access HW registers driver needs to acquire a PTT entry [mapping between bar memory and internal chip address]. Since acquiring PTT entries could fail [at least in theory] as their number is finite and other flows can hold them, we reserve special PTT entries for 'important' enough flows - ones we want to guarantee that would not be susceptible to such issues. One such special entry is the 'main' PTT which is meant to be used in flows such as chip initialization and de-initialization. However, there are other flows that are also using that same entry for their own purpose, and might run concurrently with the original flows [notice that for most cases using the main-ptt by mistake, such a race is still impossible, at least today]. This patch re-organizes the various functions that currently use the main_ptt in one of two ways: - If a function shouldn't use the main_ptt it starts acquiring and releasing it's own PTT entry and use it instead. Notice if those functions previously couldn't fail, they now can [as acquisition might fail]. - Change the prototypes so that the main_ptt would be received as a parameter [instead of explicitly accessing it]. This prevents the future risk of adding codes that introduces new use-cases for flows using the main_ptt, ones that might be in race with the actual 'main' flows. Signed-off-by: Rahul Verma <Rahul.Verma@cavium.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_spq.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
index 13f715569253..f6423a139ca0 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -119,6 +119,7 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
u8 *p_fw_ret, bool skip_quick_poll)
{
struct qed_spq_comp_done *comp_done;
+ struct qed_ptt *p_ptt;
int rc;
/* A relatively short polling period w/o sleeping, to allow the FW to
@@ -135,8 +136,14 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
if (!rc)
return 0;
+ p_ptt = qed_ptt_acquire(p_hwfn);
+ if (!p_ptt) {
+ DP_NOTICE(p_hwfn, "ptt, failed to acquire\n");
+ return -EAGAIN;
+ }
+
DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n");
- rc = qed_mcp_drain(p_hwfn, p_hwfn->p_main_ptt);
+ rc = qed_mcp_drain(p_hwfn, p_ptt);
if (rc) {
DP_NOTICE(p_hwfn, "MCP drain failed\n");
goto err;
@@ -145,15 +152,18 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
/* Retry after drain */
rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
if (!rc)
- return 0;
+ goto out;
comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie;
- if (comp_done->done == 1) {
+ if (comp_done->done == 1)
if (p_fw_ret)
*p_fw_ret = comp_done->fw_return_code;
- return 0;
- }
+out:
+ qed_ptt_release(p_hwfn, p_ptt);
+ return 0;
+
err:
+ qed_ptt_release(p_hwfn, p_ptt);
DP_NOTICE(p_hwfn,
"Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n",
le32_to_cpu(p_ent->elem.hdr.cid),