All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes
@ 2021-01-25 21:29 Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 1/6] net: ipa: rename "tag status" symbols Alex Elder
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

There is a procedure currently referred to as a "tag process" that
is performed to clear the IPA hardware pipeline--either at the time
of a modem crash, or when suspending modem GSI channels.

One thing done in this procedure is issuing a command that sends a
data packet originating from the AP->command TX endpoint, destined
for the AP<-LAN RX (default) endpoint.  And although we currently
wait for the send to complete, we do *not* wait for the packet to be
received.  But the pipeline can't be assumed clear until we have
actually received this packet.

This series addresses this by detecting when the pipeline-clearing
packet has been received, and using a completion to allow a waiter
to know when that has happened.  This uses the IPA status capability
(which sends an extra status buffer for certain packets).  It also
uses the ability to supply a "tag" with a packet, which will be
delivered with the packet's status buffer.  We tag the data packet
that's sent to clear the pipeline, and use the receipt of a status
buffer associated with a tagged packet to determine when that packet
has arrived.

"Tag status" just desribes one aspect of this procedure, so some
symbols are renamed to be more like "pipeline clear" so they better
describe the larger purpose.  Finally, two functions used in this
code don't use their arguments, so those arguments are removed.

					-Alex

Alex Elder (6):
  net: ipa: rename "tag status" symbols
  net: ipa: minor update to handling of packet with status
  net: ipa: drop packet if status has valid tag
  net: ipa: signal when tag transfer completes
  net: ipa: don't pass tag value to ipa_cmd_ip_tag_status_add()
  net: ipa: don't pass size to ipa_cmd_transfer_add()

 drivers/net/ipa/ipa.h          |  2 +
 drivers/net/ipa/ipa_cmd.c      | 45 +++++++++++++------
 drivers/net/ipa/ipa_cmd.h      | 24 ++++++-----
 drivers/net/ipa/ipa_endpoint.c | 79 ++++++++++++++++++++++++++--------
 drivers/net/ipa/ipa_main.c     |  1 +
 5 files changed, 109 insertions(+), 42 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net-next 1/6] net: ipa: rename "tag status" symbols
  2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
@ 2021-01-25 21:29 ` Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 2/6] net: ipa: minor update to handling of packet with status Alex Elder
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

There is a set of functions and symbols related to performing
"tag_process" immediate commands to clear the IPA pipeline.  The
name is related to one of the commands issued when doing this, but
it doesn't really convey the overall purpose of taking this action.

The purpose is to take some steps to "clear out" the hardware
pipeline, and to wait until that process completes, to ensure the
IPA hardware is in a well-defined state.

Rename these symbols to use "pipeline_clear" in their names instead.
Add some comments to explain a bit more about what's going on.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa_cmd.c      | 26 ++++++++++++++++++--------
 drivers/net/ipa/ipa_cmd.h      | 17 +++++++----------
 drivers/net/ipa/ipa_endpoint.c |  6 +++---
 3 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 002e514485100..27630244512d8 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -567,33 +567,43 @@ static void ipa_cmd_transfer_add(struct gsi_trans *trans, u16 size)
 			  direction, opcode);
 }
 
-void ipa_cmd_tag_process_add(struct gsi_trans *trans)
+/* Add immediate commands to a transaction to clear the hardware pipeline */
+void ipa_cmd_pipeline_clear_add(struct gsi_trans *trans)
 {
 	struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi);
 	struct ipa_endpoint *endpoint;
 
-	endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
-
+	/* Issue a no-op register write command (mask 0 means no write) */
 	ipa_cmd_register_write_add(trans, 0, 0, 0, true);
+
+	/* Send a data packet through the IPA pipeline.  The packet_init
+	 * command says to send the next packet directly to the exception
+	 * endpoint without any other IPA processing.  The tag_status
+	 * command requests that status be generated on completion of
+	 * that transfer, and that it will contain the given tag value.
+	 * Finally, the transfer command sends a small packet of data
+	 * (instead of a command) using the command endpoint.
+	 */
+	endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
 	ipa_cmd_ip_packet_init_add(trans, endpoint->endpoint_id);
 	ipa_cmd_ip_tag_status_add(trans, 0xcba987654321);
 	ipa_cmd_transfer_add(trans, 4);
 }
 
-/* Returns the number of commands required for the tag process */
-u32 ipa_cmd_tag_process_count(void)
+/* Returns the number of commands required to clear the pipeline */
+u32 ipa_cmd_pipeline_clear_count(void)
 {
 	return 4;
 }
 
-void ipa_cmd_tag_process(struct ipa *ipa)
+void ipa_cmd_pipeline_clear(struct ipa *ipa)
 {
-	u32 count = ipa_cmd_tag_process_count();
+	u32 count = ipa_cmd_pipeline_clear_count();
 	struct gsi_trans *trans;
 
 	trans = ipa_cmd_trans_alloc(ipa, count);
 	if (trans) {
-		ipa_cmd_tag_process_add(trans);
+		ipa_cmd_pipeline_clear_add(trans);
 		gsi_trans_commit_wait(trans);
 	} else {
 		dev_err(&ipa->pdev->dev,
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index 4ed09c486abc1..a41a58cc2c5ac 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -157,26 +157,23 @@ void ipa_cmd_dma_shared_mem_add(struct gsi_trans *trans, u32 offset,
 				u16 size, dma_addr_t addr, bool toward_ipa);
 
 /**
- * ipa_cmd_tag_process_add() - Add IPA tag process commands to a transaction
+ * ipa_cmd_pipeline_clear_add() - Add pipeline clear commands to a transaction
  * @trans:	GSI transaction
  */
-void ipa_cmd_tag_process_add(struct gsi_trans *trans);
+void ipa_cmd_pipeline_clear_add(struct gsi_trans *trans);
 
 /**
- * ipa_cmd_tag_process_add_count() - Number of commands in a tag process
+ * ipa_cmd_pipeline_clear_count() - # commands required to clear pipeline
  *
  * Return:	The number of elements to allocate in a transaction
- *		to hold tag process commands
+ *		to hold commands to clear the pipeline
  */
-u32 ipa_cmd_tag_process_count(void);
+u32 ipa_cmd_pipeline_clear_count(void);
 
 /**
- * ipa_cmd_tag_process() - Perform a tag process
- *
- * @Return:	The number of elements to allocate in a transaction
- *		to hold tag process commands
+ * ipa_cmd_pipeline_clear() - Clear the hardware pipeline
  */
-void ipa_cmd_tag_process(struct ipa *ipa);
+void ipa_cmd_pipeline_clear(struct ipa *ipa);
 
 /**
  * ipa_cmd_trans_alloc() - Allocate a transaction for the command TX endpoint
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 688a3dd40510a..39ae0dd4e0471 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -399,7 +399,7 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
 	 * That won't happen, and we could be more precise, but this is fine
 	 * for now.  We need to end the transaction with a "tag process."
 	 */
-	count = hweight32(initialized) + ipa_cmd_tag_process_count();
+	count = hweight32(initialized) + ipa_cmd_pipeline_clear_count();
 	trans = ipa_cmd_trans_alloc(ipa, count);
 	if (!trans) {
 		dev_err(&ipa->pdev->dev,
@@ -428,7 +428,7 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
 		ipa_cmd_register_write_add(trans, offset, 0, ~0, false);
 	}
 
-	ipa_cmd_tag_process_add(trans);
+	ipa_cmd_pipeline_clear_add(trans);
 
 	/* XXX This should have a 1 second timeout */
 	gsi_trans_commit_wait(trans);
@@ -1564,7 +1564,7 @@ void ipa_endpoint_suspend(struct ipa *ipa)
 	if (ipa->modem_netdev)
 		ipa_modem_suspend(ipa->modem_netdev);
 
-	ipa_cmd_tag_process(ipa);
+	ipa_cmd_pipeline_clear(ipa);
 
 	ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]);
 	ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 2/6] net: ipa: minor update to handling of packet with status
  2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 1/6] net: ipa: rename "tag status" symbols Alex Elder
@ 2021-01-25 21:29 ` Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag Alex Elder
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

Rearrange some comments and assignments made when handling a packet
that is received with status, aiming to improve understandability.

Use DIV_ROUND_CLOSEST() to get a better per-packet true size estimate.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa_endpoint.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 39ae0dd4e0471..c5524215054c8 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -1213,12 +1213,11 @@ static void ipa_endpoint_status_parse(struct ipa_endpoint *endpoint,
 			continue;
 		}
 
-		/* Compute the amount of buffer space consumed by the
-		 * packet, including the status element.  If the hardware
-		 * is configured to pad packet data to an aligned boundary,
-		 * account for that.  And if checksum offload is is enabled
-		 * a trailer containing computed checksum information will
-		 * be appended.
+		/* Compute the amount of buffer space consumed by the packet,
+		 * including the status element.  If the hardware is configured
+		 * to pad packet data to an aligned boundary, account for that.
+		 * And if checksum offload is enabled a trailer containing
+		 * computed checksum information will be appended.
 		 */
 		align = endpoint->data->rx.pad_align ? : 1;
 		len = le16_to_cpu(status->pkt_len);
@@ -1226,16 +1225,21 @@ static void ipa_endpoint_status_parse(struct ipa_endpoint *endpoint,
 		if (endpoint->data->checksum)
 			len += sizeof(struct rmnet_map_dl_csum_trailer);
 
-		/* Charge the new packet with a proportional fraction of
-		 * the unused space in the original receive buffer.
-		 * XXX Charge a proportion of the *whole* receive buffer?
-		 */
 		if (!ipa_status_drop_packet(status)) {
-			u32 extra = unused * len / total_len;
-			void *data2 = data + sizeof(*status);
-			u32 len2 = le16_to_cpu(status->pkt_len);
+			void *data2;
+			u32 extra;
+			u32 len2;
 
 			/* Client receives only packet data (no status) */
+			data2 = data + sizeof(*status);
+			len2 = le16_to_cpu(status->pkt_len);
+
+			/* Have the true size reflect the extra unused space in
+			 * the original receive buffer.  Distribute the "cost"
+			 * proportionately across all aggregated packets in the
+			 * buffer.
+			 */
+			extra = DIV_ROUND_CLOSEST(unused * len, total_len);
 			ipa_endpoint_skb_copy(endpoint, data2, len2, extra);
 		}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag
  2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 1/6] net: ipa: rename "tag status" symbols Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 2/6] net: ipa: minor update to handling of packet with status Alex Elder
@ 2021-01-25 21:29 ` Alex Elder
  2021-01-26  3:27   ` Jakub Kicinski
  2021-01-25 21:29 ` [PATCH net-next 4/6] net: ipa: signal when tag transfer completes Alex Elder
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

Introduce ipa_endpoint_status_tag(), which returns true if received
status indicates its tag field is valid.  The endpoint parameter is
not yet used.

Call this from ipa_status_drop_packet(), and drop the packet if the
status indicates the tag was valid.  Pass the endpoint pointer to
ipa_status_drop_packet(), and rename it ipa_endpoint_status_drop().
The endpoint will be used in the next patch.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa_endpoint.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index c5524215054c8..f1764768f0602 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -69,8 +69,11 @@ struct ipa_status {
 };
 
 /* Field masks for struct ipa_status structure fields */
+#define IPA_STATUS_MASK_TAG_VALID_FMASK		GENMASK(4, 4)
+#define IPA_STATUS_SRC_IDX_FMASK		GENMASK(4, 0)
 #define IPA_STATUS_DST_IDX_FMASK		GENMASK(4, 0)
 #define IPA_STATUS_FLAGS1_RT_RULE_ID_FMASK	GENMASK(31, 22)
+#define IPA_STATUS_FLAGS2_TAG_FMASK		GENMASK_ULL(63, 16)
 
 #ifdef IPA_VALIDATE
 
@@ -1172,11 +1175,22 @@ static bool ipa_endpoint_status_skip(struct ipa_endpoint *endpoint,
 	return false;	/* Don't skip this packet, process it */
 }
 
+static bool ipa_endpoint_status_tag(struct ipa_endpoint *endpoint,
+				    const struct ipa_status *status)
+{
+	return !!(status->mask & IPA_STATUS_MASK_TAG_VALID_FMASK);
+}
+
 /* Return whether the status indicates the packet should be dropped */
-static bool ipa_status_drop_packet(const struct ipa_status *status)
+static bool ipa_endpoint_status_drop(struct ipa_endpoint *endpoint,
+				     const struct ipa_status *status)
 {
 	u32 val;
 
+	/* If the status indicates a tagged transfer, we'll drop the packet */
+	if (ipa_endpoint_status_tag(endpoint, status))
+		return true;
+
 	/* Deaggregation exceptions we drop; all other types we consume */
 	if (status->exception)
 		return status->exception == IPA_STATUS_EXCEPTION_DEAGGR;
@@ -1225,7 +1239,7 @@ static void ipa_endpoint_status_parse(struct ipa_endpoint *endpoint,
 		if (endpoint->data->checksum)
 			len += sizeof(struct rmnet_map_dl_csum_trailer);
 
-		if (!ipa_status_drop_packet(status)) {
+		if (!ipa_endpoint_status_drop(endpoint, status)) {
 			void *data2;
 			u32 extra;
 			u32 len2;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 4/6] net: ipa: signal when tag transfer completes
  2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
                   ` (2 preceding siblings ...)
  2021-01-25 21:29 ` [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag Alex Elder
@ 2021-01-25 21:29 ` Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 5/6] net: ipa: don't pass tag value to ipa_cmd_ip_tag_status_add() Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 6/6] net: ipa: don't pass size to ipa_cmd_transfer_add() Alex Elder
  5 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

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>
---
 drivers/net/ipa/ipa.h          |  2 ++
 drivers/net/ipa/ipa_cmd.c      |  9 +++++++++
 drivers/net/ipa/ipa_cmd.h      |  7 +++++++
 drivers/net/ipa/ipa_endpoint.c | 27 ++++++++++++++++++++++++++-
 drivers/net/ipa/ipa_main.c     |  1 +
 5 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index c6c6a7f6909c1..8020776313716 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -43,6 +43,7 @@ enum ipa_flag {
  * @flags:		Boolean state flags
  * @version:		IPA hardware version
  * @pdev:		Platform device
+ * @completion:		Used to signal pipeline clear transfer complete
  * @smp2p:		SMP2P information
  * @clock:		IPA clocking information
  * @table_addr:		DMA address of filter/route table content
@@ -82,6 +83,7 @@ struct ipa {
 	DECLARE_BITMAP(flags, IPA_FLAG_COUNT);
 	enum ipa_version version;
 	struct platform_device *pdev;
+	struct completion completion;
 	struct notifier_block nb;
 	void *notifier;
 	struct ipa_smp2p *smp2p;
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 27630244512d8..7df0072bddcce 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);
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index a41a58cc2c5ac..6dd3d35cf315d 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -170,8 +170,15 @@ void ipa_cmd_pipeline_clear_add(struct gsi_trans *trans);
  */
 u32 ipa_cmd_pipeline_clear_count(void);
 
+/**
+ * ipa_cmd_pipeline_clear_wait() - Wait pipeline clear to complete
+ * @ipa:	- IPA pointer
+ */
+void ipa_cmd_pipeline_clear_wait(struct ipa *ipa);
+
 /**
  * ipa_cmd_pipeline_clear() - Clear the hardware pipeline
+ * @ipa:	- IPA pointer
  */
 void ipa_cmd_pipeline_clear(struct ipa *ipa);
 
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index f1764768f0602..cef89325a3bb0 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -436,6 +436,8 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
 	/* XXX This should have a 1 second timeout */
 	gsi_trans_commit_wait(trans);
 
+	ipa_cmd_pipeline_clear_wait(ipa);
+
 	return 0;
 }
 
@@ -1178,7 +1180,30 @@ static bool ipa_endpoint_status_skip(struct ipa_endpoint *endpoint,
 static bool ipa_endpoint_status_tag(struct ipa_endpoint *endpoint,
 				    const struct ipa_status *status)
 {
-	return !!(status->mask & IPA_STATUS_MASK_TAG_VALID_FMASK);
+	struct ipa_endpoint *command_endpoint;
+	struct ipa *ipa = endpoint->ipa;
+	u32 endpoint_id;
+
+	if (!(status->mask & IPA_STATUS_MASK_TAG_VALID_FMASK))
+		return false;	/* No valid tag */
+
+	/* The status contains a valid tag.  We know the packet was sent to
+	 * this endpoint (already verified by ipa_endpoint_status_skip()).
+	 * If the packet came from the AP->command TX endpoint we know
+	 * this packet was sent as part of the pipeline clear process.
+	 */
+	endpoint_id = u8_get_bits(status->endp_src_idx,
+				  IPA_STATUS_SRC_IDX_FMASK);
+	command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX];
+	if (endpoint_id == command_endpoint->endpoint_id) {
+		complete(&ipa->completion);
+	} else {
+		dev_err(&ipa->pdev->dev,
+			"unexpected tagged packet from endpoint %u\n",
+			endpoint_id);
+	}
+
+	return true;
 }
 
 /* Return whether the status indicates the packet should be dropped */
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index ab0fd5cb49277..c10e7340b0318 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -831,6 +831,7 @@ static int ipa_probe(struct platform_device *pdev)
 	dev_set_drvdata(dev, ipa);
 	ipa->clock = clock;
 	ipa->version = data->version;
+	init_completion(&ipa->completion);
 
 	ret = ipa_reg_init(ipa);
 	if (ret)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 5/6] net: ipa: don't pass tag value to ipa_cmd_ip_tag_status_add()
  2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
                   ` (3 preceding siblings ...)
  2021-01-25 21:29 ` [PATCH net-next 4/6] net: ipa: signal when tag transfer completes Alex Elder
@ 2021-01-25 21:29 ` Alex Elder
  2021-01-25 21:29 ` [PATCH net-next 6/6] net: ipa: don't pass size to ipa_cmd_transfer_add() Alex Elder
  5 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

We only send a tagged packet from the AP->command TX endpoint when
we're clearing the hardware pipeline.  And when we receive the
tagged packet we don't care what the actual tag value is.

Stop passing a tag value to ipa_cmd_ip_tag_status_add(), and just
encode 0 as the tag sent.  Fix the function that encodes the tag so
it uses the proper byte ordering.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa_cmd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 7df0072bddcce..eb50e7437359a 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -529,7 +529,7 @@ void ipa_cmd_dma_shared_mem_add(struct gsi_trans *trans, u32 offset, u16 size,
 			  direction, opcode);
 }
 
-static void ipa_cmd_ip_tag_status_add(struct gsi_trans *trans, u64 tag)
+static void ipa_cmd_ip_tag_status_add(struct gsi_trans *trans)
 {
 	struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi);
 	enum ipa_cmd_opcode opcode = IPA_CMD_IP_PACKET_TAG_STATUS;
@@ -543,7 +543,7 @@ static void ipa_cmd_ip_tag_status_add(struct gsi_trans *trans, u64 tag)
 	cmd_payload = ipa_cmd_payload_alloc(ipa, &payload_addr);
 	payload = &cmd_payload->ip_packet_tag_status;
 
-	payload->tag = u64_encode_bits(tag, IP_PACKET_TAG_STATUS_TAG_FMASK);
+	payload->tag = le64_encode_bits(0, IP_PACKET_TAG_STATUS_TAG_FMASK);
 
 	gsi_trans_cmd_add(trans, payload, sizeof(*payload), payload_addr,
 			  direction, opcode);
@@ -583,13 +583,13 @@ void ipa_cmd_pipeline_clear_add(struct gsi_trans *trans)
 	 * command says to send the next packet directly to the exception
 	 * endpoint without any other IPA processing.  The tag_status
 	 * command requests that status be generated on completion of
-	 * that transfer, and that it will contain the given tag value.
+	 * that transfer, and that it will be tagged with a value.
 	 * Finally, the transfer command sends a small packet of data
 	 * (instead of a command) using the command endpoint.
 	 */
 	endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
 	ipa_cmd_ip_packet_init_add(trans, endpoint->endpoint_id);
-	ipa_cmd_ip_tag_status_add(trans, 0xcba987654321);
+	ipa_cmd_ip_tag_status_add(trans);
 	ipa_cmd_transfer_add(trans, 4);
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 6/6] net: ipa: don't pass size to ipa_cmd_transfer_add()
  2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
                   ` (4 preceding siblings ...)
  2021-01-25 21:29 ` [PATCH net-next 5/6] net: ipa: don't pass tag value to ipa_cmd_ip_tag_status_add() Alex Elder
@ 2021-01-25 21:29 ` Alex Elder
  5 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-25 21:29 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

The only time we transfer data (rather than issuing a command) out
of the AP->command TX endpoint is when we're clearing the hardware
pipeline.  All that's needed is a "small" data buffer, and its
contents aren't even important.

For convenience, we just transfer a command structure in this case
(it's already mapped for DMA).  The TRE is added to a transaction
using ipa_cmd_ip_tag_status_add(), but we ignore the size value
provided to that function.  So just get rid of the size argument.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa_cmd.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index eb50e7437359a..97b50fee60089 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -550,7 +550,7 @@ static void ipa_cmd_ip_tag_status_add(struct gsi_trans *trans)
 }
 
 /* Issue a small command TX data transfer */
-static void ipa_cmd_transfer_add(struct gsi_trans *trans, u16 size)
+static void ipa_cmd_transfer_add(struct gsi_trans *trans)
 {
 	struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi);
 	enum dma_data_direction direction = DMA_TO_DEVICE;
@@ -558,8 +558,6 @@ static void ipa_cmd_transfer_add(struct gsi_trans *trans, u16 size)
 	union ipa_cmd_payload *payload;
 	dma_addr_t payload_addr;
 
-	/* assert(size <= sizeof(*payload)); */
-
 	/* Just transfer a zero-filled payload structure */
 	payload = ipa_cmd_payload_alloc(ipa, &payload_addr);
 
@@ -590,7 +588,7 @@ void ipa_cmd_pipeline_clear_add(struct gsi_trans *trans)
 	endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
 	ipa_cmd_ip_packet_init_add(trans, endpoint->endpoint_id);
 	ipa_cmd_ip_tag_status_add(trans);
-	ipa_cmd_transfer_add(trans, 4);
+	ipa_cmd_transfer_add(trans);
 }
 
 /* Returns the number of commands required to clear the pipeline */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag
  2021-01-25 21:29 ` [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag Alex Elder
@ 2021-01-26  3:27   ` Jakub Kicinski
  2021-01-26  4:24     ` Alex Elder
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2021-01-26  3:27 UTC (permalink / raw)
  To: Alex Elder
  Cc: davem, elder, evgreen, bjorn.andersson, cpratapa, subashab,
	netdev, linux-kernel

On Mon, 25 Jan 2021 15:29:44 -0600 Alex Elder wrote:
> Introduce ipa_endpoint_status_tag(), which returns true if received
> status indicates its tag field is valid.  The endpoint parameter is
> not yet used.
> 
> Call this from ipa_status_drop_packet(), and drop the packet if the
> status indicates the tag was valid.  Pass the endpoint pointer to
> ipa_status_drop_packet(), and rename it ipa_endpoint_status_drop().
> The endpoint will be used in the next patch.
> 
> Signed-off-by: Alex Elder <elder@linaro.org>

> @@ -1172,11 +1175,22 @@ static bool ipa_endpoint_status_skip(struct ipa_endpoint *endpoint,
>  	return false;	/* Don't skip this packet, process it */
>  }
>  
> +static bool ipa_endpoint_status_tag(struct ipa_endpoint *endpoint,
> +				    const struct ipa_status *status)
> +{
> +	return !!(status->mask & IPA_STATUS_MASK_TAG_VALID_FMASK);

drivers/net/ipa/ipa_endpoint.c:1181:25: warning: restricted __le16 degrades to integer

> +}
> +

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag
  2021-01-26  3:27   ` Jakub Kicinski
@ 2021-01-26  4:24     ` Alex Elder
  0 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-01-26  4:24 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, elder, evgreen, bjorn.andersson, cpratapa, subashab,
	netdev, linux-kernel

On 1/25/21 9:27 PM, Jakub Kicinski wrote:
> On Mon, 25 Jan 2021 15:29:44 -0600 Alex Elder wrote:
>> Introduce ipa_endpoint_status_tag(), which returns true if received
>> status indicates its tag field is valid.  The endpoint parameter is
>> not yet used.
>>
>> Call this from ipa_status_drop_packet(), and drop the packet if the
>> status indicates the tag was valid.  Pass the endpoint pointer to
>> ipa_status_drop_packet(), and rename it ipa_endpoint_status_drop().
>> The endpoint will be used in the next patch.
>>
>> Signed-off-by: Alex Elder <elder@linaro.org>
> 
>> @@ -1172,11 +1175,22 @@ static bool ipa_endpoint_status_skip(struct ipa_endpoint *endpoint,
>>   	return false;	/* Don't skip this packet, process it */
>>   }
>>   
>> +static bool ipa_endpoint_status_tag(struct ipa_endpoint *endpoint,
>> +				    const struct ipa_status *status)
>> +{
>> +	return !!(status->mask & IPA_STATUS_MASK_TAG_VALID_FMASK);
> 
> drivers/net/ipa/ipa_endpoint.c:1181:25: warning: restricted __le16 degrades to integer

Wow, that's an important one.

Sparse is spewing errors for me.  I guess I'm finally going to have
to figure out what's wrong.

I'll send an update tomorrow.  I know how to fix it but I want to
verify it works before I send it out.

Thank you.

					-Alex

>> +}
>> +


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-01-26 11:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-25 21:29 [PATCH net-next 0/6] net: ipa: hardware pipeline cleanup fixes Alex Elder
2021-01-25 21:29 ` [PATCH net-next 1/6] net: ipa: rename "tag status" symbols Alex Elder
2021-01-25 21:29 ` [PATCH net-next 2/6] net: ipa: minor update to handling of packet with status Alex Elder
2021-01-25 21:29 ` [PATCH net-next 3/6] net: ipa: drop packet if status has valid tag Alex Elder
2021-01-26  3:27   ` Jakub Kicinski
2021-01-26  4:24     ` Alex Elder
2021-01-25 21:29 ` [PATCH net-next 4/6] net: ipa: signal when tag transfer completes Alex Elder
2021-01-25 21:29 ` [PATCH net-next 5/6] net: ipa: don't pass tag value to ipa_cmd_ip_tag_status_add() Alex Elder
2021-01-25 21:29 ` [PATCH net-next 6/6] net: ipa: don't pass size to ipa_cmd_transfer_add() Alex Elder

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.