History log of /linux-master/drivers/net/ipa/gsi_trans.c
Revision Date Author Comments
# 6c75dc94 28-Mar-2023 Alex Elder <elder@linaro.org>

net: ipa: compute DMA pool size properly

In gsi_trans_pool_init_dma(), the total size of a pool of memory
used for DMA transactions is calculated. However the calculation is
done incorrectly.

For 4KB pages, this total size is currently always more than one
page, and as a result, the calculation produces a positive (though
incorrect) total size. The code still works in this case; we just
end up with fewer DMA pool entries than we intended.

Bjorn Andersson tested booting a kernel with 16KB pages, and hit a
null pointer derereference in sg_alloc_append_table_from_pages(),
descending from gsi_trans_pool_init_dma(). The cause of this was
that a 16KB total size was going to be allocated, and with 16KB
pages the order of that allocation is 0. The total_size calculation
yielded 0, which eventually led to the crash.

Correcting the total_size calculation fixes the problem.

Reported-by: Bjorn Andersson <quic_bjorande@quicinc.com>
Tested-by: Bjorn Andersson <quic_bjorande@quicinc.com>
Fixes: 9dd441e4ed57 ("soc: qcom: ipa: GSI transactions")
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Link: https://lore.kernel.org/r/20230328162751.2861791-1-elder@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 36875a06 18-Oct-2022 Kees Cook <keescook@chromium.org>

net: ipa: Proactively round up to kmalloc bucket size

Instead of discovering the kmalloc bucket size _after_ allocation, round
up proactively so the allocation is explicitly made for the full size,
allowing the compiler to correctly reason about the resulting size of
the buffer through the existing __alloc_size() hint.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org
Reviewed-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/lkml/4d75a9fd-1b94-7208-9de8-5a0102223e68@ieee.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20221018092724.give.735-kees@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>


# a4388da5 30-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: update copyrights

Some source files state copyright dates that are earlier than the
last modification of the file. Change the copyright year to 2022 in
all such cases.

Signed-off-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20220930224549.3503434-1-elder@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# ace5dc61 30-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: update comments

This patch just updates comments throughout the IPA code.

Transaction state is now tracked using indexes into an array rather
than linked lists, and a few comments refer to the "old way" of
doing things. The description of how transactions are used was
changed to refer to "operations" rather than "commands", to
(hopefully) remove a possible ambiguity.

IPA register offsets and fields are now handled differently as well,
and the register documentation is updated to better describe the
code.

A few minor updates to comments were made (e.g., adding a missing
word, fixing a typo or punctuation, etc.).

Finally, the local macro atomic_dec_not_zero() is no longer used, so
it is deleted.

Signed-off-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20220930224527.3503404-1-elder@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 019e37ea 05-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: don't have gsi_channel_update() return a value

If it finds no completed transactions, gsi_channel_trans_complete()
calls gsi_channel_update() to check hardware. If new transactions
have completed, gsi_channel_update() records that, then calls
gsi_channel_trans_complete() to return the first of those found.
This recursion won't go any further, but can be avoided if we
have gsi_channel_update() only be responsible for updating state
after accessing hardware.

Change gsi_channel_update() so it simply checks for and handles
new completions, without returning a value. If it needs to call
that function, have gsi_channel_trans_complete() determine whether
there are new transactions available after the update.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# e0e3406c 05-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: update channel in gsi_channel_trans_complete()

Have gsi_channel_trans_complete() update the known state from
hardware rather than doing so in gsi_channel_poll_one().

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# d338ae28 05-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: kill all other transaction lists

None of the transaction lists are actually needed any more, because
transaction IDs (which have been shown to be equivalent) are used
instead. So we can remove all of them, as well as the spinlock
that protects updates to them.

Not requiring a lock simplifies gsi_trans_free() as well; we only
need to check the reference count once to decide whether we've hit
the last reference.

This makes the links field in the gsi_trans structure unused, so get
rid of that as well.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 11902b41 05-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: kill the allocated transaction list

The only place the trans_info->alloc list is used is when
initializing it, when adding a transaction to it when allocation
finishes, and when moving a transaction from that list to the
committed list.

We can just skip putting a transaction on the allocated list, and
add it (rather than move it) to the committed list when it is
committed.

On additional caveat is that an allocated transaction that's
committed without any TREs added will be immediately freed. Because
we aren't adding allocated transactions to a list any more, the
list links need to be initialized to ensure they're valid at the
time list_del() is called for the transaction.

Then we can safely eliminate the allocated transaction list.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 0c126ec3 05-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: always use transaction IDs instead of lists

In gsi_channel_trans_complete(), use the completed and pending IDs
to determine whether there are any transactions in completed state.

Similarly, in gsi_channel_trans_cancel_pending(), use the pending
and committed IDs to mark pending transactions cancelled. Rearrange
the logic a bit there for a simpler result.

This removes the only user of list_last_entry_or_null(), so get rid
of that macro.

Remove the temporary warnings added by the previous commit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 8672bab7 02-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: verify a few more IDs

The completed transaction list is used in gsi_channel_trans_complete()
to return the next transaction in completed state.

Add some temporary checks to verify the transaction indicated by the
completed ID matches the one first in this list.

Similarly, we use the pending and completed transaction lists when
cancelling pending transactions in gsi_channel_trans_cancel_pending().

Add temporary checks there to verify the transactions indicated by
IDs match those tracked by these lists.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# b2abe33d 02-Sep-2022 Alex Elder <elder@linaro.org>

net: ipa: rework last transaction determination

When quiescing a channel, we find the "last" transaction, which is
the latest one to have been allocated. (New transaction allocation
will have been prevented by the time this is called.)

Currently we do this by looking for the first non-empty transaction
list in each state, then return the last entry from that last.
Instead, determine the last entry in each list (if any) and return
that entry if found.

Temporarily (locally) introduce list_last_entry_or_null() as a
helper for this, mirroring list_first_entry_or_null(). This macro
definition will be removed by an upcoming patch.

Remove the temporary warnings added by the previous commit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# fd3bd039 31-Aug-2022 Alex Elder <elder@linaro.org>

net: ipa: track polled transactions with an ID

Add a transaction ID to track the first element in the transaction
array that has been polled. Advance the ID when we are releasing a
transaction.

Temporarily add warnings that verify that the first polled
transaction tracked by the ID matches the first element on the
polled list, both when polling and freeing.

Remove the temporary warnings added by the previous commit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 949cd0b5 31-Aug-2022 Alex Elder <elder@linaro.org>

net: ipa: track completed transactions with an ID

Add a transaction ID field to track the first element in the
transaction array that has completed but has not yet been polled.

Advance the ID when we are processing a transaction in the NAPI
polling loop (where completed transactions become polled).

Temporarily add warnings that verify that the first completed
transaction tracked by the ID matches the first element on the
completed list, both when pending and completing.

Remove the temporary warnings added by the previous commit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# eeff7c14 31-Aug-2022 Alex Elder <elder@linaro.org>

net: ipa: track pending transactions with an ID

Add a transaction ID field to track the first element in the
transaction array that is pending (sent to hardware) but not yet
complete. Advance the ID when a completion event for a channel
indicates that transactions have completed.

Temporarily add warnings that verify that the first pending
transaction tracked by the ID matches the first element on the
pending list, both when pending and completing, as well as when
resetting the channel.

Remove the temporary warnings added by the previous commit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# fc95d958 31-Aug-2022 Alex Elder <elder@linaro.org>

net: ipa: track committed transactions with an ID

Add a transaction ID field to track the first element in a channel's
transaction array that has been committed, but not yet passed to the
hardware. Advance the ID when the hardware is notified via doorbell
that TREs from a transaction are ready for consumption.

Temporarily add warnings that verify that the first committed
transaction tracked by the ID matches the first element on the
committed list, both when committing and pending (at doorbell).

Remove the temporary warnings added by the previous commit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 41e2a2c0 31-Aug-2022 Alex Elder <elder@linaro.org>

net: ipa: track allocated transactions with an ID

Transactions for a channel are now managed in an array, with a free
transaction ID indicating which is the next one free.

Add another transaction ID field to track the first element in the
array that has been allocated. Advance it when a transaction is
committed (because that is when that transaction leaves allocated
state).

Temporarily add warnings that verify that the first allocated
transaction tracked by the ID matches the first element on the
allocated list, both when allocating and committing a transaction.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 12382d11 31-Aug-2022 Alex Elder <elder@linaro.org>

net: ipa: use an array for transactions

Transactions are always allocated one at a time. The maximum number
of them we could ever need occurs if each TRE is assigned to a
transaction. So a channel requires no more transactions than the
number of TREs in its transfer ring. That number is known to be a
power-of-2 less than 65536.

The transaction pool abstraction is used for other things, but for
transactions we can use a simple array of transaction structures,
and use a free index to indicate which entry in the array is the
next one free for allocation.

By having the number of elements in the array be a power-of-2, we
can use an ever-incrementing 16-bit free index, and use it modulo
the array size. Distinguish a "trans_id" (whose value can exceed
the number of entries in the transaction array) from a "trans_index"
(which is less than the number of entries).

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 616c4a83 19-Jul-2022 Alex Elder <elder@linaro.org>

net: ipa: fix an outdated comment

Since commit 8797972afff3d ("net: ipa: remove command info pool"),
we don't allocate "command info" entries for command channel
transactions. Fix a comment that seems to suggest we still do.
(Even before that commit, the comment was out of place.)

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 4d8996cb 19-Jul-2022 Alex Elder <elder@linaro.org>

net: ipa: skip some cleanup for unused transactions

In gsi_trans_free(), there's no point in ipa_gsi_trans_release() if
a transaction is unused. No used TREs means no IPA layer resources
to clean up. So only call ipa_gsi_trans_release() if at least one
TRE was used.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 49200658 19-Jul-2022 Alex Elder <elder@linaro.org>

net: ipa: rearrange transaction initialization

The transaction map is really associated with the transaction pool;
move its definition earlier in the gsi_trans_info structure.

Rearrange initialization in gsi_channel_trans_init() so it
sets the tre_avail value first, then initializes the transaction
pool, and finally allocating the transaction map.

Update comments.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# b63f507c 19-Jul-2022 Alex Elder <elder@linaro.org>

net: ipa: add a transaction committed list

We currently put a transaction on the pending list when it has
been committed. But until the channel's doorbell rings, these
transactions aren't actually "owned" by the hardware yet.

Add a new "committed" state (and list), to represent transactions
that have been committed but not yet sent to hardware. Define
"pending" to mean committed transactions that have been sent
to hardware but have not yet completed.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 7c0d97e4 21-Jun-2022 Jiang Jian <jiangjian@cdjrlc.com>

net: ipa: remove unexpected word "the"

there is an unexpected word "the" in the comments that need to be removed

Signed-off-by: Jiang Jian <jiangjian@cdjrlc.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20220621085001.61320-1-jiangjian@cdjrlc.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 8eec7831 15-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: don't pass channel when mapping transaction

Change gsi_channel_trans_map() so it derives the channel used from
the transaction. Pass the index of the *first* TRE used by the
transaction, and have the called function account for the fact that
the last one used is what's important.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# dd5a046c 15-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: don't assume one channel per event ring

In gsi_evt_ring_rx_update(), use gsi_event_trans() repeatedly
to find the transaction associated with an event, rather than
assuming consecutive events are associated with the same channel.
This removes the only caller of gsi_trans_pool_next(), so get rid
of it.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 4e0f28e9 12-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: introduce gsi_trans_tx_committed()

Create a new function that encapsulates recording information needed
for TX channel statistics when a transaction is committed.

Record the accumulated length in the transaction before the call
(for both RX and TX), so it can be used when updating TX statistics.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 3eeabea6 12-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: rename two transaction fields

There are two fields in a GSI transaction that keep track of TRE
counts. The first represents the number of TREs reserved for the
transaction in the TRE ring; that's currently named "tre_count".
The second is the number of TREs that are actually *used* by the
transaction at the time it is committed.

Rename the "tre_count" field to be "rsvd_count", to make its meaning
a little more specific. The "_count" is present in the name mainly
to avoid interpreting it as a reserved (not-to-be-used) field. This
name also distinguishes it from the "tre_count" field associated
with a channel.

Rename the "used" field to be "used_count", to match the convention
used for reserved TREs.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 2295947b 12-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: use "tre_ring" for all TRE ring local variables

All local variables that represent event rings are named "ring".

All but two functions that represent a channel's TRE ring with a
local variable use the name "tre_ring". For consistency, use that
name in the two functions that don't fit the pattern.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# bcec9ecb 10-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: derive channel from transaction

In gsi_channel_tx_queued(), we report when a transaction gets passed
to hardware. Change that function so it takes transaction rather
than a channel as its argument, and derive the channel from the
transaction. Rename the function accordingly.

Delete the header comments above the function definition; the ones
above the declaration in "gsi_private.h" should suffice. In
addition, the comments above gsi_channel_tx_update() do a fine job
of explaining what's going on.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 88e03057 10-Jun-2022 Alex Elder <elder@linaro.org>

net: ipa: rename channel->tlv_count

Each GSI channel has a TLV FIFO of a certain size, specified in the
configuration data for an AP channel. That size dictates the
maximum number of TREs that are allowed in a single transaction.

The only way that value is used after initialization is as a limit
on the number of TREs in a transaction; calling it "tlv_count"
isn't helpful, and in fact gsi_channel_trans_tre_max() exists to
sort of abstract it.

Instead, rename the channel->tlv_count field trans_tre_max, and get
rid of the helper function. Update a couple of comments as well.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 8797972a 21-May-2022 Alex Elder <elder@linaro.org>

net: ipa: remove command info pool

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 <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 4de284b7 21-May-2022 Alex Elder <elder@linaro.org>

net: ipa: remove command direction argument

We no longer use the direction argument for gsi_trans_cmd_add(), so
get rid of it in its definition, and in its seven callers.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 7ffba3bd 21-May-2022 Alex Elder <elder@linaro.org>

net: ipa: get rid of ipa_cmd_info->direction

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 <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# d15180b4 21-May-2022 Alex Elder <elder@linaro.org>

net: ipa: kill gsi_trans_commit_wait_timeout()

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 <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 5fc7f9ba 03-Feb-2022 Alex Elder <elder@linaro.org>

net: ipa: introduce gsi_channel_trans_idle()

Create a new function that returns true if all transactions for a
channel are available for use.

Use it in ipa_endpoint_replenish_enable() to see whether to start
replenishing, and in ipa_endpoint_replenish() to determine whether
it's necessary after a failure to schedule delayed work to ensure a
future replenish attempt occurs.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 5bc55884 25-Jul-2021 Alex Elder <elder@linaro.org>

net: ipa: use WARN_ON() rather than assertions

I've added commented assertions to record certain properties that
can be assumed to hold in certain places in the IPA code. Convert
these into real WARN_ON() calls so the assertions are actually
checked, using the standard WARN_ON() mechanism.

Where errors can be returned, return an error if a warning is
triggered.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 442d68eb 25-Jul-2021 Alex Elder <elder@linaro.org>

net: ipa: kill the remaining conditional validation code

There are only a few remaining spots that validate IPA code
conditional on whether a symbol is defined at compile time.
The checks are not expensive, so just build them always.

This completes the removal of all CONFIG_VALIDATE/CONFIG_VALIDATION
IPA code.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 7ad3bd52 09-Apr-2021 Alex Elder <elder@linaro.org>

net: ipa: relax pool entry size requirement

I no longer know why a validation check ensured the size of an entry
passed to gsi_trans_pool_init() was restricted to be a multiple of 8.
For 32-bit builds, this condition doesn't always hold, and for DMA
pools, the size is rounded up to a power of 2 anyway.

Remove this restriction.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 19aaf72c 27-Mar-2021 Alex Elder <elder@linaro.org>

net: ipa: DMA addresses are nicely aligned

A recent patch avoided doing 64-bit modulo operations by checking
the alignment of some DMA allocations using only the lower 32 bits
of the address.

David Laight pointed out (after the fix was committed) that DMA
allocations might already satisfy the alignment requirements. And
he was right.

Remove the alignment checks that occur after DMA allocation requests,
and update comments to explain why the constraint is satisfied. The
only place IPA_TABLE_ALIGN was used was to check the alignment; it is
therefore no longer needed, so get rid of it.

Add comments where GSI_RING_ELEMENT_SIZE and the tre_count and
event_count channel data fields are defined to make explicit they
are required to be powers of 2.

Revise a comment in gsi_trans_pool_init_dma(), taking into account
that dma_alloc_coherent() guarantees its result is aligned to a page
size (or order thereof).

Don't bother printing an error if a DMA allocation fails.

Suggested-by: David Laight <David.Laight@ACULAB.COM>
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 1130b252 03-Dec-2020 Alex Elder <elder@linaro.org>

net: ipa: pass the correct size when freeing DMA memory

When the coherent memory is freed in gsi_trans_pool_exit_dma(), we
are mistakenly passing the size of a single element in the pool
rather than the actual allocated size. Fix this bug.

Fixes: 9dd441e4ed575 ("soc: qcom: ipa: GSI transactions")
Reported-by: Stephen Boyd <swboyd@chromium.org>
Tested-by: Sujit Kautkar <sujitka@chromium.org>
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20201203215106.17450-1-elder@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# 064c9c32 13-Nov-2020 Alex Elder <elder@linaro.org>

net: ipa: lock when freeing transaction

Transactions sit on one of several lists, depending on their state
(allocated, pending, complete, or polled). A spinlock protects
against concurrent access when transactions are moved between these
lists.

Transactions are also reference counted. A newly-allocated
transaction has an initial count of 1; a transaction is released in
gsi_trans_free() only if its decremented reference count reaches 0.
Releasing a transaction includes removing it from the polled (or if
unused, allocated) list, so the spinlock is acquired when we release
a transaction.

The reference count is used to allow a caller to synchronously wait
for a committed transaction to complete. In this case, the waiter
takes an extra reference to the transaction *before* committing it
(so it won't be freed), and releases its reference (calls
gsi_trans_free()) when it is done with it.

Similarly, gsi_channel_update() takes an extra reference to ensure a
transaction isn't released before the function is done operating on
it. Until the transaction is moved to the completed list (by this
function) it won't be freed, so this reference is taken "safely."

But in the quiesce path, we want to wait for the "last" transaction,
which we find in the completed or polled list. Transactions on
these lists can be freed at any time, so we (try to) prevent that
by taking the reference while holding the spinlock.

Currently gsi_trans_free() decrements a transaction's reference
count unconditionally, acquiring the lock to remove the transaction
from its list *only* when the count reaches 0. This does not
protect the quiesce path, which depends on the lock to ensure its
extra reference prevents release of the transaction.

Fix this by only dropping the last reference to a transaction
in gsi_trans_free() while holding the spinlock.

Fixes: 9dd441e4ed575 ("soc: qcom: ipa: GSI transactions")
Reported-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20201114182017.28270-1-elder@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>


# df833050 21-Oct-2020 Alex Elder <elder@linaro.org>

net: ipa: command payloads already mapped

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: 9dd441e4ed575 ("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>


# 90159458 28-Sep-2020 Alex Elder <elder@linaro.org>

net: ipa: kill definition of TRE_FLAGS_IEOB_FMASK

In "gsi_trans.c", the field mask TRE_FLAGS_IEOB_FMASK is defined but
never used. Although there's no harm in defining this, remove it
for now and redefine it at some future date if it becomes needed.
This is warned about if "W=2" is added to the build command.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# c781e1d4 07-May-2020 Alex Elder <elder@linaro.org>

net: ipa: set DMA length in gsi_trans_cmd_add()

When a command gets added to a transaction for the AP->command
channel we set the DMA address of its scatterlist entry, but not
its DMA length. Fix this bug.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>


# 9dd441e4 05-Mar-2020 Alex Elder <elder@linaro.org>

soc: qcom: ipa: GSI transactions

This patch implements GSI transactions. A GSI transaction is a
structure that represents a single request (consisting of one or
more TREs) sent to the GSI hardware. The last TRE in a transaction
includes a flag requesting that the GSI interrupt the AP to notify
that it has completed.

TREs are executed and completed strictly in order. For this reason,
the completion of a single TRE implies that all previous TREs (in
particular all of those "earlier" in a transaction) have completed.

Whenever there is a need to send a request (a set of TREs) to the
IPA, a GSI transaction is allocated, specifying the number of TREs
that will be required. Details of the request (e.g. transfer offsets
and length) are represented by in a Linux scatterlist array that is
incorporated in the transaction structure.

Once all commands (TREs) are added to a transaction it is committed.
When the hardware signals that the request has completed, a callback
function allows for cleanup or followup activity to be performed
before the transaction is freed.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>