diff options
author | Alex Elder <elder@linaro.org> | 2021-01-26 12:57:01 -0600 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-01-28 20:23:26 -0800 |
commit | 51c48ce264f85919b263a38e4defa50b80928877 (patch) | |
tree | ac49e225ff6bf8d415c2aeab331f00e8b19c1fcf /drivers/net/ipa/ipa_cmd.c | |
parent | f6aba7b5199ad2a73a3deb6c042dee770650719c (diff) | |
download | lwn-51c48ce264f85919b263a38e4defa50b80928877.tar.gz lwn-51c48ce264f85919b263a38e4defa50b80928877.zip |
net: ipa: signal when tag transfer completes
There are times, such as when the modem crashes, when we issue
commands to clear the IPA hardware pipeline. These commands include
a data transfer command that delivers a small packet directly to the
default (AP<-LAN RX) endpoint.
The places that do this wait for the transactions that contain these
commands to complete, but the pipeline can't be assumed clear until
the sent packet has been *received*.
The small transfer will be delivered with a status structure, and
that status will indicate its tag is valid. This is the only place
we send a tagged packet, so we use the tag to determine when the
pipeline clear packet has arrived.
Add a completion to the IPA structure to to be used to signal
the receipt of a pipeline clear packet. Create a new function
ipa_cmd_pipeline_clear_wait() that will wait for that completion.
Reinitialize the completion whenever pipeline clear commands are
added to a transaction. Extend ipa_endpoint_status_tag() to check
whether a packet whose status contains a valid tag was sent from the
AP->command TX endpoint, and if so, signal the new IPA completion.
Have all callers of ipa_cmd_pipeline_clear_add() wait for the
pipeline clear indication after the transaction that clears the
pipeline has completed.
Signed-off-by: Alex Elder <elder@linaro.org>
Acked-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ipa/ipa_cmd.c')
-rw-r--r-- | drivers/net/ipa/ipa_cmd.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c index 27630244512d..7df0072bddcc 100644 --- a/drivers/net/ipa/ipa_cmd.c +++ b/drivers/net/ipa/ipa_cmd.c @@ -573,6 +573,9 @@ void ipa_cmd_pipeline_clear_add(struct gsi_trans *trans) struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi); struct ipa_endpoint *endpoint; + /* This will complete when the transfer is received */ + reinit_completion(&ipa->completion); + /* Issue a no-op register write command (mask 0 means no write) */ ipa_cmd_register_write_add(trans, 0, 0, 0, true); @@ -596,6 +599,11 @@ u32 ipa_cmd_pipeline_clear_count(void) return 4; } +void ipa_cmd_pipeline_clear_wait(struct ipa *ipa) +{ + wait_for_completion(&ipa->completion); +} + void ipa_cmd_pipeline_clear(struct ipa *ipa) { u32 count = ipa_cmd_pipeline_clear_count(); @@ -605,6 +613,7 @@ void ipa_cmd_pipeline_clear(struct ipa *ipa) if (trans) { ipa_cmd_pipeline_clear_add(trans); gsi_trans_commit_wait(trans); + ipa_cmd_pipeline_clear_wait(ipa); } else { dev_err(&ipa->pdev->dev, "error allocating %u entry tag transaction\n", count); |