Skip to content

Commit 50dd09c

Browse files
Alex Eldergregkh
authored andcommitted
net: ipa: command payloads already mapped
[ Upstream commit df83305 ] IPA transactions describe actions to be performed by the IPA hardware. Three cases use IPA transactions: transmitting a socket buffer; providing a page to receive packet data; and issuing an IPA immediate command. An IPA transaction contains a scatter/gather list (SGL) to hold the set of actions to be performed. We map buffers in the SGL for DMA at the time they are added to the transaction. For skb TX transactions, we fill the SGL with a call to skb_to_sgvec(). Page RX transactions involve a single page pointer, and that is recorded in the SGL with sg_set_page(). In both of these cases we then map the SGL for DMA with a call to dma_map_sg(). Immediate commands are different. The payload for an immediate command comes from a region of coherent DMA memory, which must *not* be mapped for DMA. For that reason, gsi_trans_cmd_add() sort of hand-crafts each SGL entry added to a command transaction. This patch fixes a problem with the code that crafts the SGL entry for an immediate command. Previously a portion of the SGL entry was updated using sg_set_buf(). However this is not valid because it includes a call to virt_to_page() on the buffer, but the command buffer pointer is not a linear address. Since we never actually map the SGL for command transactions, there are very few fields in the SGL we need to fill. Specifically, we only need to record the DMA address and the length, so they can be used by __gsi_trans_commit() to fill a TRE. We additionally need to preserve the SGL flags so for_each_sg() still works. For that we can simply assign a null page pointer for command SGL entries. Fixes: 9dd441e ("soc: qcom: ipa: GSI transactions") Reported-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Alex Elder <elder@linaro.org> Link: https://lore.kernel.org/r/20201022010029.11877-1-elder@linaro.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent fb596e9 commit 50dd09c

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

drivers/net/ipa/gsi_trans.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,15 +398,24 @@ void gsi_trans_cmd_add(struct gsi_trans *trans, void *buf, u32 size,
398398

399399
/* assert(which < trans->tre_count); */
400400

401-
/* Set the page information for the buffer. We also need to fill in
402-
* the DMA address and length for the buffer (something dma_map_sg()
403-
* normally does).
401+
/* Commands are quite different from data transfer requests.
402+
* Their payloads come from a pool whose memory is allocated
403+
* using dma_alloc_coherent(). We therefore do *not* map them
404+
* for DMA (unlike what we do for pages and skbs).
405+
*
406+
* When a transaction completes, the SGL is normally unmapped.
407+
* A command transaction has direction DMA_NONE, which tells
408+
* gsi_trans_complete() to skip the unmapping step.
409+
*
410+
* The only things we use directly in a command scatter/gather
411+
* entry are the DMA address and length. We still need the SG
412+
* table flags to be maintained though, so assign a NULL page
413+
* pointer for that purpose.
404414
*/
405415
sg = &trans->sgl[which];
406-
407-
sg_set_buf(sg, buf, size);
416+
sg_assign_page(sg, NULL);
408417
sg_dma_address(sg) = addr;
409-
sg_dma_len(sg) = sg->length;
418+
sg_dma_len(sg) = size;
410419

411420
info = &trans->info[which];
412421
info->opcode = opcode;

0 commit comments

Comments
 (0)