This series consists of three small sets of changes. Version 2 adds
a patch that avoids a warning that occurs when handling a modem
crash (I unfortunately didn't notice it earlier). All other patches
are the same--just rebased.
The first three patches allow a few endpoint features to be
specified. At this time, currently-defined endpoints retain the
same configuration, but when the monitor functionality is added in
the next cycle these options will be required.
The fourth patch simply removes an unused function, explaining also
why it would likely never be used.
The fifth patch is new. It counts the number of modem TX endpoints
and uses it to determine how many TREs a transaction needs when
when handling a modem crash. It is needed to avoid exceeding the
limited number of commands imposed by the last four patches.
And the last four patches refactor code related to IPA immediate
commands, eliminating an unused field and then simplifying and
removing some unneeded code.
-Alex
Alex Elder (9):
net: ipa: make endpoint HOLB drop configurable
net: ipa: support hard aggregation limits
net: ipa: specify RX aggregation time limit in config data
net: ipa: kill gsi_trans_commit_wait_timeout()
net: ipa: count the number of modem TX endpoints
net: ipa: get rid of ipa_cmd_info->direction
net: ipa: remove command direction argument
net: ipa: remove command info pool
net: ipa: use data space for command opcodes
drivers/net/ipa/gsi.h | 1 -
drivers/net/ipa/gsi_trans.c | 38 ++-------
drivers/net/ipa/gsi_trans.h | 24 +++---
drivers/net/ipa/ipa.h | 2 +
drivers/net/ipa/ipa_cmd.c | 78 +++++-------------
drivers/net/ipa/ipa_cmd.h | 11 ---
drivers/net/ipa/ipa_data-v3.1.c | 2 +
drivers/net/ipa/ipa_data-v3.5.1.c | 2 +
drivers/net/ipa/ipa_data-v4.11.c | 2 +
drivers/net/ipa/ipa_data-v4.2.c | 2 +
drivers/net/ipa/ipa_data-v4.5.c | 2 +
drivers/net/ipa/ipa_data-v4.9.c | 2 +
drivers/net/ipa/ipa_endpoint.c | 129 +++++++++++++++++++-----------
drivers/net/ipa/ipa_endpoint.h | 23 +++++-
14 files changed, 156 insertions(+), 162 deletions(-)
--
2.32.0
The direction field of the ipa_cmd_info structure is set, but never
used. It seems it might have been used for the DMA_SHARED_MEM
immediate command, but the DIRECTION flag is set based on the value
of the passed-in direction flag there.
Anyway, remove this unused field from the ipa_cmd_info structure.
This is done as a separate patch to make it very obvious that it's
not required.
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/gsi_trans.c | 5 +----
drivers/net/ipa/ipa_cmd.h | 2 --
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c
index bf31ef3d56adc..cf8ee42373547 100644
--- a/drivers/net/ipa/gsi_trans.c
+++ b/drivers/net/ipa/gsi_trans.c
@@ -413,7 +413,6 @@ void gsi_trans_cmd_add(struct gsi_trans *trans, void *buf, u32 size,
dma_addr_t addr, enum dma_data_direction direction,
enum ipa_cmd_opcode opcode)
{
- struct ipa_cmd_info *info;
u32 which = trans->used++;
struct scatterlist *sg;
@@ -438,9 +437,7 @@ void gsi_trans_cmd_add(struct gsi_trans *trans, void *buf, u32 size,
sg_dma_address(sg) = addr;
sg_dma_len(sg) = size;
- info = &trans->info[which];
- info->opcode = opcode;
- info->direction = direction;
+ trans->info[which].opcode = opcode;
}
/* Add a page transfer to a transaction. It will fill the only TRE. */
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index 05ed7e42e1842..d4dbe2ce96dcd 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -50,11 +50,9 @@ enum ipa_cmd_opcode {
* struct ipa_cmd_info - information needed for an IPA immediate command
*
* @opcode: The command opcode.
- * @direction: Direction of data transfer for DMA commands
*/
struct ipa_cmd_info {
enum ipa_cmd_opcode opcode;
- enum dma_data_direction direction;
};
/**
--
2.32.0
In ipa_endpoint_modem_exception_reset_all(), a high estimate was
made of the number of endpoints that need their status register
updated. We only used what was needed, so the high estimate didn't
matter much.
However the next few patches are going to limit the number of
commands in a single transaction, and the overestimate would exceed
that. So count the number of modem TX endpoints at initialization
time, and use it in ipa_endpoint_modem_exception_reset_all().
Signed-off-by: Alex Elder <[email protected]>
---
v2: This is a new patch added to the series.
drivers/net/ipa/ipa.h | 2 ++
drivers/net/ipa/ipa_endpoint.c | 10 +++++-----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index 9fc880eb7e3a6..4fc3c72359f5e 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -62,6 +62,7 @@ struct ipa_interrupt;
* @initialized: Bit mask indicating endpoints initialized
* @set_up: Bit mask indicating endpoints set up
* @enabled: Bit mask indicating endpoints enabled
+ * @modem_tx_count: Number of defined modem TX endoints
* @endpoint: Array of endpoint information
* @channel_map: Mapping of GSI channel to IPA endpoint
* @name_map: Mapping of IPA endpoint name to IPA endpoint
@@ -114,6 +115,7 @@ struct ipa {
u32 set_up;
u32 enabled;
+ u32 modem_tx_count;
struct ipa_endpoint endpoint[IPA_ENDPOINT_MAX];
struct ipa_endpoint *channel_map[GSI_CHANNEL_COUNT_MAX];
struct ipa_endpoint *name_map[IPA_ENDPOINT_COUNT];
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 5ed5b8fd3ea36..385aa63ab4bbc 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -442,12 +442,10 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
struct gsi_trans *trans;
u32 count;
- /* We need one command per modem TX endpoint. We can get an upper
- * bound on that by assuming all initialized endpoints are modem->IPA.
- * That won't happen, and we could be more precise, but this is fine
- * for now. End the transaction with commands to clear the pipeline.
+ /* We need one command per modem TX endpoint, plus the commands
+ * that clear the pipeline.
*/
- count = hweight32(initialized) + ipa_cmd_pipeline_clear_count();
+ count = ipa->modem_tx_count + ipa_cmd_pipeline_clear_count();
trans = ipa_cmd_trans_alloc(ipa, count);
if (!trans) {
dev_err(&ipa->pdev->dev,
@@ -1924,6 +1922,8 @@ u32 ipa_endpoint_init(struct ipa *ipa, u32 count,
if (data->endpoint.filter_support)
filter_map |= BIT(data->endpoint_id);
+ if (data->ee_id == GSI_EE_MODEM && data->toward_ipa)
+ ipa->modem_tx_count++;
}
if (!ipa_filter_map_valid(ipa, filter_map))
--
2.32.0
Since the beginning gsi_trans_commit_wait_timeout() has existed to
provide a way to allow waiting a limited time for a transaction
to complete. But that function has never been used.
In fact, there is no use for this function, because a transaction
committed to hardware should *always* complete. The only reason it
might not complete is if there were a hardware failure, or perhaps a
system configuration error.
Furthermore, if a timeout ever did occur, the IPA hardware would be
in an indeterminate state, from which there is no recovery. It
would require some sort of complete IPA reset, and would require the
participation of the modem, and at this time there is no such
sequence defined.
So get rid of the definition of gsi_trans_commit_wait_timeout(), and
update a few comments accordingly.
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/gsi_trans.c | 22 ----------------------
drivers/net/ipa/gsi_trans.h | 9 ---------
drivers/net/ipa/ipa_cmd.c | 15 +++++++--------
drivers/net/ipa/ipa_endpoint.c | 1 -
4 files changed, 7 insertions(+), 40 deletions(-)
diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c
index 87e1d43c118c1..bf31ef3d56adc 100644
--- a/drivers/net/ipa/gsi_trans.c
+++ b/drivers/net/ipa/gsi_trans.c
@@ -637,28 +637,6 @@ void gsi_trans_commit_wait(struct gsi_trans *trans)
gsi_trans_free(trans);
}
-/* Commit a GSI transaction and wait for it to complete, with timeout */
-int gsi_trans_commit_wait_timeout(struct gsi_trans *trans,
- unsigned long timeout)
-{
- unsigned long timeout_jiffies = msecs_to_jiffies(timeout);
- unsigned long remaining = 1; /* In case of empty transaction */
-
- if (!trans->used)
- goto out_trans_free;
-
- refcount_inc(&trans->refcount);
-
- __gsi_trans_commit(trans, true);
-
- remaining = wait_for_completion_timeout(&trans->completion,
- timeout_jiffies);
-out_trans_free:
- gsi_trans_free(trans);
-
- return remaining ? 0 : -ETIMEDOUT;
-}
-
/* Process the completion of a transaction; called while polling */
void gsi_trans_complete(struct gsi_trans *trans)
{
diff --git a/drivers/net/ipa/gsi_trans.h b/drivers/net/ipa/gsi_trans.h
index af379b49299ee..387ea50dd039e 100644
--- a/drivers/net/ipa/gsi_trans.h
+++ b/drivers/net/ipa/gsi_trans.h
@@ -205,15 +205,6 @@ void gsi_trans_commit(struct gsi_trans *trans, bool ring_db);
*/
void gsi_trans_commit_wait(struct gsi_trans *trans);
-/**
- * gsi_trans_commit_wait_timeout() - Commit a GSI transaction and wait for
- * it to complete, with timeout
- * @trans: Transaction to commit
- * @timeout: Timeout period (in milliseconds)
- */
-int gsi_trans_commit_wait_timeout(struct gsi_trans *trans,
- unsigned long timeout);
-
/**
* gsi_trans_read_byte() - Issue a single byte read TRE on a channel
* @gsi: GSI pointer
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index d57472ea077f2..77b84cea6e68f 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -26,14 +26,13 @@
* other than data transfer to another endpoint.
*
* Immediate commands are represented by GSI transactions just like other
- * transfer requests, represented by a single GSI TRE. Each immediate
- * command has a well-defined format, having a payload of a known length.
- * This allows the transfer element's length field to be used to hold an
- * immediate command's opcode. The payload for a command resides in DRAM
- * and is described by a single scatterlist entry in its transaction.
- * Commands do not require a transaction completion callback. To commit
- * an immediate command transaction, either gsi_trans_commit_wait() or
- * gsi_trans_commit_wait_timeout() is used.
+ * transfer requests, and use a single GSI TRE. Each immediate command
+ * has a well-defined format, having a payload of a known length. This
+ * allows the transfer element's length field to be used to hold an
+ * immediate command's opcode. The payload for a command resides in AP
+ * memory and is described by a single scatterlist entry in its transaction.
+ * Commands do not require a transaction completion callback, and are
+ * (currently) always issued using gsi_trans_commit_wait().
*/
/* Some commands can wait until indicated pipeline stages are clear */
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 586529511cf6b..5ed5b8fd3ea36 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -478,7 +478,6 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
ipa_cmd_pipeline_clear_add(trans);
- /* XXX This should have a 1 second timeout */
gsi_trans_commit_wait(trans);
ipa_cmd_pipeline_clear_wait(ipa);
--
2.32.0
The ipa_cmd_info structure now contains only one field, and it's an
enumerated type whose values all fit in 8 bits. Currently we'll
never use more than 8 TREs in a command transaction, and we can
represent that number of command opcodes in the same space as a 64
bit pointer to an ipa_cmd_info structure.
Define IPA_COMMAND_TRANS_TRE_MAX as the maximum number of TREs that
can be in a command transaction. Replace the info pointer in a
transaction with a fixed-size array named cmd_opcode[] of that many
bytes. Store the opcode in this array when adding a command TRE to
a transaction, as was done previously for the info array. This
makes the ipa_cmd_info unused, so get rid of it.
When committing an immediate command transaction, use the channel's
Boolean command flag to determine whether to fill in the opcode,
which will be taken (as before) from the array in the transaction.
This makes the command info pool unnecessary, so get rid of it.
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/gsi.h | 1 -
drivers/net/ipa/gsi_trans.c | 10 ++++-----
drivers/net/ipa/gsi_trans.h | 7 +++++--
drivers/net/ipa/ipa_cmd.c | 41 ++++++++-----------------------------
drivers/net/ipa/ipa_cmd.h | 9 --------
5 files changed, 18 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ipa/gsi.h b/drivers/net/ipa/gsi.h
index 9cc6576588116..5d66116b46b03 100644
--- a/drivers/net/ipa/gsi.h
+++ b/drivers/net/ipa/gsi.h
@@ -84,7 +84,6 @@ struct gsi_trans_info {
struct gsi_trans_pool pool; /* transaction pool */
struct gsi_trans_pool sg_pool; /* scatterlist pool */
struct gsi_trans_pool cmd_pool; /* command payload DMA pool */
- struct gsi_trans_pool info_pool;/* command information pool */
struct gsi_trans **map; /* TRE -> transaction map */
spinlock_t spinlock; /* protects updates to the lists */
diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c
index 472792992f866..55f8fe7d2668e 100644
--- a/drivers/net/ipa/gsi_trans.c
+++ b/drivers/net/ipa/gsi_trans.c
@@ -436,7 +436,7 @@ void gsi_trans_cmd_add(struct gsi_trans *trans, void *buf, u32 size,
sg_dma_address(sg) = addr;
sg_dma_len(sg) = size;
- trans->info[which].opcode = opcode;
+ trans->cmd_opcode[which] = opcode;
}
/* Add a page transfer to a transaction. It will fill the only TRE. */
@@ -552,10 +552,10 @@ static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db)
struct gsi_ring *ring = &channel->tre_ring;
enum ipa_cmd_opcode opcode = IPA_CMD_NONE;
bool bei = channel->toward_ipa;
- struct ipa_cmd_info *info;
struct gsi_tre *dest_tre;
struct scatterlist *sg;
u32 byte_count = 0;
+ u8 *cmd_opcode;
u32 avail;
u32 i;
@@ -566,7 +566,7 @@ static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db)
* If there is no info array we're doing a simple data
* transfer request, whose opcode is IPA_CMD_NONE.
*/
- info = trans->info ? &trans->info[0] : NULL;
+ cmd_opcode = channel->command ? &trans->cmd_opcode[0] : NULL;
avail = ring->count - ring->index % ring->count;
dest_tre = gsi_ring_virt(ring, ring->index);
for_each_sg(trans->sgl, sg, trans->used, i) {
@@ -577,8 +577,8 @@ static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db)
byte_count += len;
if (!avail--)
dest_tre = gsi_ring_virt(ring, 0);
- if (info)
- opcode = info++->opcode;
+ if (cmd_opcode)
+ opcode = *cmd_opcode++;
gsi_trans_tre_fill(dest_tre, addr, len, last_tre, bei, opcode);
dest_tre++;
diff --git a/drivers/net/ipa/gsi_trans.h b/drivers/net/ipa/gsi_trans.h
index 9a39909915ef5..99ce2cba0dc3c 100644
--- a/drivers/net/ipa/gsi_trans.h
+++ b/drivers/net/ipa/gsi_trans.h
@@ -22,6 +22,9 @@ struct gsi;
struct gsi_trans;
struct gsi_trans_pool;
+/* Maximum number of TREs in an IPA immediate command transaction */
+#define IPA_COMMAND_TRANS_TRE_MAX 8
+
/**
* struct gsi_trans - a GSI transaction
*
@@ -34,8 +37,8 @@ struct gsi_trans_pool;
* @used: Number of TREs *used* (could be less than tre_count)
* @len: Total # of transfer bytes represented in sgl[] (set by core)
* @data: Preserved but not touched by the core transaction code
+ * @cmd_opcode: Array of command opcodes (command channel only)
* @sgl: An array of scatter/gather entries managed by core code
- * @info: Array of command information structures (command channel)
* @direction: DMA transfer direction (DMA_NONE for commands)
* @refcount: Reference count used for destruction
* @completion: Completed when the transaction completes
@@ -58,8 +61,8 @@ struct gsi_trans {
u32 len; /* total # bytes across sgl[] */
void *data;
+ u8 cmd_opcode[IPA_COMMAND_TRANS_TRE_MAX];
struct scatterlist *sgl;
- struct ipa_cmd_info *info; /* array of entries, or null */
enum dma_data_direction direction;
refcount_t refcount;
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 5fd74d7007044..e58cd4478fd3d 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -349,7 +349,6 @@ int ipa_cmd_pool_init(struct gsi_channel *channel, u32 tre_max)
{
struct gsi_trans_info *trans_info = &channel->trans_info;
struct device *dev = channel->gsi->dev;
- int ret;
/* This is as good a place as any to validate build constants */
ipa_cmd_validate_build();
@@ -358,20 +357,9 @@ int ipa_cmd_pool_init(struct gsi_channel *channel, u32 tre_max)
* a single transaction can require up to tlv_count of them,
* so we treat them as if that many can be allocated at once.
*/
- ret = gsi_trans_pool_init_dma(dev, &trans_info->cmd_pool,
- sizeof(union ipa_cmd_payload),
- tre_max, channel->tlv_count);
- if (ret)
- return ret;
-
- /* Each TRE needs a command info structure */
- ret = gsi_trans_pool_init(&trans_info->info_pool,
- sizeof(struct ipa_cmd_info),
- tre_max, channel->tlv_count);
- if (ret)
- gsi_trans_pool_exit_dma(dev, &trans_info->cmd_pool);
-
- return ret;
+ return gsi_trans_pool_init_dma(dev, &trans_info->cmd_pool,
+ sizeof(union ipa_cmd_payload),
+ tre_max, channel->tlv_count);
}
void ipa_cmd_pool_exit(struct gsi_channel *channel)
@@ -379,7 +367,6 @@ void ipa_cmd_pool_exit(struct gsi_channel *channel)
struct gsi_trans_info *trans_info = &channel->trans_info;
struct device *dev = channel->gsi->dev;
- gsi_trans_pool_exit(&trans_info->info_pool);
gsi_trans_pool_exit_dma(dev, &trans_info->cmd_pool);
}
@@ -652,28 +639,16 @@ void ipa_cmd_pipeline_clear_wait(struct ipa *ipa)
wait_for_completion(&ipa->completion);
}
-static struct ipa_cmd_info *
-ipa_cmd_info_alloc(struct ipa_endpoint *endpoint, u32 tre_count)
-{
- struct gsi_channel *channel;
-
- channel = &endpoint->ipa->gsi.channel[endpoint->channel_id];
-
- return gsi_trans_pool_alloc(&channel->trans_info.info_pool, tre_count);
-}
-
/* Allocate a transaction for the command TX endpoint */
struct gsi_trans *ipa_cmd_trans_alloc(struct ipa *ipa, u32 tre_count)
{
struct ipa_endpoint *endpoint;
- struct gsi_trans *trans;
+
+ if (WARN_ON(tre_count > IPA_COMMAND_TRANS_TRE_MAX))
+ return NULL;
endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX];
- trans = gsi_channel_trans_alloc(&ipa->gsi, endpoint->channel_id,
- tre_count, DMA_NONE);
- if (trans)
- trans->info = ipa_cmd_info_alloc(endpoint, tre_count);
-
- return trans;
+ return gsi_channel_trans_alloc(&ipa->gsi, endpoint->channel_id,
+ tre_count, DMA_NONE);
}
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index d4dbe2ce96dcd..9215ddad10107 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -46,15 +46,6 @@ enum ipa_cmd_opcode {
IPA_CMD_IP_PACKET_TAG_STATUS = 0x14,
};
-/**
- * struct ipa_cmd_info - information needed for an IPA immediate command
- *
- * @opcode: The command opcode.
- */
-struct ipa_cmd_info {
- enum ipa_cmd_opcode opcode;
-};
-
/**
* ipa_cmd_table_valid() - Validate a memory region holding a table
* @ipa: - IPA pointer
--
2.32.0
Hello:
This series was applied to netdev/net-next.git (master)
by David S. Miller <[email protected]>:
On Sat, 21 May 2022 19:32:14 -0500 you wrote:
> This series consists of three small sets of changes. Version 2 adds
> a patch that avoids a warning that occurs when handling a modem
> crash (I unfortunately didn't notice it earlier). All other patches
> are the same--just rebased.
>
> The first three patches allow a few endpoint features to be
> specified. At this time, currently-defined endpoints retain the
> same configuration, but when the monitor functionality is added in
> the next cycle these options will be required.
>
> [...]
Here is the summary with links:
- [net-next,v2,1/9] net: ipa: make endpoint HOLB drop configurable
https://git.kernel.org/netdev/net-next/c/153213f0554d
- [net-next,v2,2/9] net: ipa: support hard aggregation limits
(no matching commit)
- [net-next,v2,3/9] net: ipa: specify RX aggregation time limit in config data
https://git.kernel.org/netdev/net-next/c/beb90cba607f
- [net-next,v2,4/9] net: ipa: kill gsi_trans_commit_wait_timeout()
https://git.kernel.org/netdev/net-next/c/d15180b4eadb
- [net-next,v2,5/9] net: ipa: count the number of modem TX endpoints
https://git.kernel.org/netdev/net-next/c/2091c79ac4de
- [net-next,v2,6/9] net: ipa: get rid of ipa_cmd_info->direction
https://git.kernel.org/netdev/net-next/c/7ffba3bdf76a
- [net-next,v2,7/9] net: ipa: remove command direction argument
https://git.kernel.org/netdev/net-next/c/4de284b72e59
- [net-next,v2,8/9] net: ipa: remove command info pool
(no matching commit)
- [net-next,v2,9/9] net: ipa: use data space for command opcodes
https://git.kernel.org/netdev/net-next/c/a224bd4b88ca
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
The 64-bit data field in a transaction is not used for commands.
And the opcode array is *only* used for commands. They're
(currently) the same size; save a little space in the transaction
structure by enclosing the two fields in a union.
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/gsi_trans.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ipa/gsi_trans.h b/drivers/net/ipa/gsi_trans.h
index 99ce2cba0dc3c..020c3b32de1d7 100644
--- a/drivers/net/ipa/gsi_trans.h
+++ b/drivers/net/ipa/gsi_trans.h
@@ -60,8 +60,10 @@ struct gsi_trans {
u8 used; /* # entries used in sgl[] */
u32 len; /* total # bytes across sgl[] */
- void *data;
- u8 cmd_opcode[IPA_COMMAND_TRANS_TRE_MAX];
+ union {
+ void *data;
+ u8 cmd_opcode[IPA_COMMAND_TRANS_TRE_MAX];
+ };
struct scatterlist *sgl;
enum dma_data_direction direction;
--
2.32.0