Commit ace5dc61 authored by Alex Elder's avatar Alex Elder Committed by Jakub Kicinski

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: default avatarAlex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20220930224527.3503404-1-elder@linaro.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 450a580f
...@@ -56,9 +56,9 @@ ...@@ -56,9 +56,9 @@
* element can also contain an immediate command, requesting the IPA perform * element can also contain an immediate command, requesting the IPA perform
* actions other than data transfer. * actions other than data transfer.
* *
* Each TRE refers to a block of data--also located DRAM. After writing one * Each TRE refers to a block of data--also located in DRAM. After writing
* or more TREs to a channel, the writer (either the IPA or an EE) writes a * one or more TREs to a channel, the writer (either the IPA or an EE) writes
* doorbell register to inform the receiving side how many elements have * a doorbell register to inform the receiving side how many elements have
* been written. * been written.
* *
* Each channel has a GSI "event ring" associated with it. An event ring * Each channel has a GSI "event ring" associated with it. An event ring
...@@ -1347,8 +1347,8 @@ gsi_event_trans(struct gsi *gsi, struct gsi_event *event) ...@@ -1347,8 +1347,8 @@ gsi_event_trans(struct gsi *gsi, struct gsi_event *event)
* we update transactions to record their actual received lengths. * we update transactions to record their actual received lengths.
* *
* When an event for a TX channel arrives we use information in the * When an event for a TX channel arrives we use information in the
* transaction to report the number of requests and bytes have been * transaction to report the number of requests and bytes that have
* transferred. * been transferred.
* *
* This function is called whenever we learn that the GSI hardware has filled * This function is called whenever we learn that the GSI hardware has filled
* new events since the last time we checked. The ring's index field tells * new events since the last time we checked. The ring's index field tells
...@@ -1474,7 +1474,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel) ...@@ -1474,7 +1474,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel)
iowrite32(val, gsi->virt + GSI_CH_C_DOORBELL_0_OFFSET(channel_id)); iowrite32(val, gsi->virt + GSI_CH_C_DOORBELL_0_OFFSET(channel_id));
} }
/* Consult hardware, move any newly completed transactions to completed list */ /* Consult hardware, move newly completed transactions to completed state */
void gsi_channel_update(struct gsi_channel *channel) void gsi_channel_update(struct gsi_channel *channel)
{ {
u32 evt_ring_id = channel->evt_ring_id; u32 evt_ring_id = channel->evt_ring_id;
...@@ -1515,17 +1515,17 @@ void gsi_channel_update(struct gsi_channel *channel) ...@@ -1515,17 +1515,17 @@ void gsi_channel_update(struct gsi_channel *channel)
* *
* Return: Transaction pointer, or null if none are available * Return: Transaction pointer, or null if none are available
* *
* This function returns the first entry on a channel's completed transaction * This function returns the first of a channel's completed transactions.
* list. If that list is empty, the hardware is consulted to determine * If no transactions are in completed state, the hardware is consulted to
* whether any new transactions have completed. If so, they're moved to the * determine whether any new transactions have completed. If so, they're
* completed list and the new first entry is returned. If there are no more * moved to completed state and the first such transaction is returned.
* completed transactions, a null pointer is returned. * If there are no more completed transactions, a null pointer is returned.
*/ */
static struct gsi_trans *gsi_channel_poll_one(struct gsi_channel *channel) static struct gsi_trans *gsi_channel_poll_one(struct gsi_channel *channel)
{ {
struct gsi_trans *trans; struct gsi_trans *trans;
/* Get the first transaction from the completed list */ /* Get the first completed transaction */
trans = gsi_channel_trans_complete(channel); trans = gsi_channel_trans_complete(channel);
if (trans) if (trans)
gsi_trans_move_polled(trans); gsi_trans_move_polled(trans);
......
...@@ -18,13 +18,13 @@ struct gsi_channel; ...@@ -18,13 +18,13 @@ struct gsi_channel;
/** /**
* gsi_trans_move_complete() - Mark a GSI transaction completed * gsi_trans_move_complete() - Mark a GSI transaction completed
* @trans: Transaction to commit * @trans: Transaction whose state is to be updated
*/ */
void gsi_trans_move_complete(struct gsi_trans *trans); void gsi_trans_move_complete(struct gsi_trans *trans);
/** /**
* gsi_trans_move_polled() - Mark a transaction polled * gsi_trans_move_polled() - Mark a transaction polled
* @trans: Transaction to update * @trans: Transaction whose state is to be updated
*/ */
void gsi_trans_move_polled(struct gsi_trans *trans); void gsi_trans_move_polled(struct gsi_trans *trans);
...@@ -97,8 +97,8 @@ void gsi_channel_doorbell(struct gsi_channel *channel); ...@@ -97,8 +97,8 @@ void gsi_channel_doorbell(struct gsi_channel *channel);
/* gsi_channel_update() - Update knowledge of channel hardware state /* gsi_channel_update() - Update knowledge of channel hardware state
* @channel: Channel to be updated * @channel: Channel to be updated
* *
* Consult hardware, move any newly completed transactions to a * Consult hardware, change the state of any newly-completed transactions
* channel's completed list. * on a channel.
*/ */
void gsi_channel_update(struct gsi_channel *channel); void gsi_channel_update(struct gsi_channel *channel);
......
...@@ -22,37 +22,36 @@ ...@@ -22,37 +22,36 @@
* DOC: GSI Transactions * DOC: GSI Transactions
* *
* A GSI transaction abstracts the behavior of a GSI channel by representing * A GSI transaction abstracts the behavior of a GSI channel by representing
* everything about a related group of IPA commands in a single structure. * everything about a related group of IPA operations in a single structure.
* (A "command" in this sense is either a data transfer or an IPA immediate * (A "operation" in this sense is either a data transfer or an IPA immediate
* command.) Most details of interaction with the GSI hardware are managed * command.) Most details of interaction with the GSI hardware are managed
* by the GSI transaction core, allowing users to simply describe commands * by the GSI transaction core, allowing users to simply describe operations
* to be performed. When a transaction has completed a callback function * to be performed. When a transaction has completed a callback function
* (dependent on the type of endpoint associated with the channel) allows * (dependent on the type of endpoint associated with the channel) allows
* cleanup of resources associated with the transaction. * cleanup of resources associated with the transaction.
* *
* To perform a command (or set of them), a user of the GSI transaction * To perform an operation (or set of them), a user of the GSI transaction
* interface allocates a transaction, indicating the number of TREs required * interface allocates a transaction, indicating the number of TREs required
* (one per command). If sufficient TREs are available, they are reserved * (one per operation). If sufficient TREs are available, they are reserved
* for use in the transaction and the allocation succeeds. This way * for use in the transaction and the allocation succeeds. This way
* exhaustion of the available TREs in a channel ring is detected * exhaustion of the available TREs in a channel ring is detected as early
* as early as possible. All resources required to complete a transaction * as possible. Any other resources that might be needed to complete a
* are allocated at transaction allocation time. * transaction are also allocated when the transaction is allocated.
* *
* Commands performed as part of a transaction are represented in an array * Operations performed as part of a transaction are represented in an array
* of Linux scatterlist structures. This array is allocated with the * of Linux scatterlist structures, allocated with the transaction. These
* transaction, and its entries are initialized using standard scatterlist * scatterlist structures are initialized by "adding" operations to the
* functions (such as sg_set_buf() or skb_to_sgvec()). * transaction. If a buffer in an operation must be mapped for DMA, this is
* done at the time it is added to the transaction. It is possible for a
* mapping error to occur when an operation is added. In this case the
* transaction should simply be freed; this correctly releases resources
* associated with the transaction.
* *
* Once a transaction's scatterlist structures have been initialized, the * Once all operations have been successfully added to a transaction, the
* transaction is committed. The caller is responsible for mapping buffers * transaction is committed. Committing transfers ownership of the entire
* for DMA if necessary, and this should be done *before* allocating * transaction to the GSI transaction core. The GSI transaction code
* the transaction. Between a successful allocation and commit of a * formats the content of the scatterlist array into the channel ring
* transaction no errors should occur. * buffer and informs the hardware that new TREs are available to process.
*
* Committing transfers ownership of the entire transaction to the GSI
* transaction core. The GSI transaction code formats the content of
* the scatterlist array into the channel ring buffer and informs the
* hardware that new TREs are available to process.
* *
* The last TRE in each transaction is marked to interrupt the AP when the * The last TRE in each transaction is marked to interrupt the AP when the
* GSI hardware has completed it. Because transfers described by TREs are * GSI hardware has completed it. Because transfers described by TREs are
...@@ -125,11 +124,10 @@ void gsi_trans_pool_exit(struct gsi_trans_pool *pool) ...@@ -125,11 +124,10 @@ void gsi_trans_pool_exit(struct gsi_trans_pool *pool)
memset(pool, 0, sizeof(*pool)); memset(pool, 0, sizeof(*pool));
} }
/* Allocate the requested number of (zeroed) entries from the pool */ /* Home-grown DMA pool. This way we can preallocate the pool, and guarantee
/* Home-grown DMA pool. This way we can preallocate and use the tre_count * allocations will succeed. The immediate commands in a transaction can
* to guarantee allocations will succeed. Even though we specify max_alloc * require up to max_alloc elements from the pool. But we only allow
* (and it can be more than one), we only allow allocation of a single * allocation of a single element from a DMA pool at a time.
* element from a DMA pool.
*/ */
int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool, int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
size_t size, u32 count, u32 max_alloc) size_t size, u32 count, u32 max_alloc)
...@@ -537,8 +535,8 @@ static void gsi_trans_tre_fill(struct gsi_tre *dest_tre, dma_addr_t addr, ...@@ -537,8 +535,8 @@ static void gsi_trans_tre_fill(struct gsi_tre *dest_tre, dma_addr_t addr,
* *
* Formats channel ring TRE entries based on the content of the scatterlist. * Formats channel ring TRE entries based on the content of the scatterlist.
* Maps a transaction pointer to the last ring entry used for the transaction, * Maps a transaction pointer to the last ring entry used for the transaction,
* so it can be recovered when it completes. Moves the transaction to the * so it can be recovered when it completes. Moves the transaction to
* pending list. Finally, updates the channel ring pointer and optionally * pending state. Finally, updates the channel ring pointer and optionally
* rings the doorbell. * rings the doorbell.
*/ */
static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db) static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db)
......
...@@ -74,7 +74,7 @@ struct gsi_trans { ...@@ -74,7 +74,7 @@ struct gsi_trans {
/** /**
* gsi_trans_pool_init() - Initialize a pool of structures for transactions * gsi_trans_pool_init() - Initialize a pool of structures for transactions
* @pool: GSI transaction poll pointer * @pool: GSI transaction pool pointer
* @size: Size of elements in the pool * @size: Size of elements in the pool
* @count: Minimum number of elements in the pool * @count: Minimum number of elements in the pool
* @max_alloc: Maximum number of elements allocated at a time from pool * @max_alloc: Maximum number of elements allocated at a time from pool
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* immediate command's opcode. The payload for a command resides in AP * immediate command's opcode. The payload for a command resides in AP
* memory and is described by a single scatterlist entry in its transaction. * memory and is described by a single scatterlist entry in its transaction.
* Commands do not require a transaction completion callback, and are * Commands do not require a transaction completion callback, and are
* (currently) always issued using gsi_trans_commit_wait(). * always issued using gsi_trans_commit_wait().
*/ */
/* Some commands can wait until indicated pipeline stages are clear */ /* Some commands can wait until indicated pipeline stages are clear */
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* communication path between the IPA and a particular execution environment * communication path between the IPA and a particular execution environment
* (EE), such as the AP or Modem. Each EE has a set of channels associated * (EE), such as the AP or Modem. Each EE has a set of channels associated
* with it, and each channel has an ID unique for that EE. For the most part * with it, and each channel has an ID unique for that EE. For the most part
* the only GSI channels of concern to this driver belong to the AP * the only GSI channels of concern to this driver belong to the AP.
* *
* An endpoint is an IPA construct representing a single channel anywhere * An endpoint is an IPA construct representing a single channel anywhere
* in the system. An IPA endpoint ID maps directly to an (EE, channel_id) * in the system. An IPA endpoint ID maps directly to an (EE, channel_id)
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include "ipa_gsi.h" #include "ipa_gsi.h"
#include "ipa_power.h" #include "ipa_power.h"
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* Hardware is told about receive buffers once a "batch" has been queued */ /* Hardware is told about receive buffers once a "batch" has been queued */
#define IPA_REPLENISH_BATCH 16 /* Must be non-zero */ #define IPA_REPLENISH_BATCH 16 /* Must be non-zero */
......
...@@ -17,53 +17,38 @@ struct ipa; ...@@ -17,53 +17,38 @@ struct ipa;
* DOC: IPA Registers * DOC: IPA Registers
* *
* IPA registers are located within the "ipa-reg" address space defined by * IPA registers are located within the "ipa-reg" address space defined by
* Device Tree. The offset of each register within that space is specified * Device Tree. Each register has a specified offset within that space,
* by symbols defined below. The address space is mapped to virtual memory * which is mapped into virtual memory space in ipa_mem_init(). Each
* space in ipa_mem_init(). All IPA registers are 32 bits wide. * has a unique identifer, taken from the ipa_reg_id enumerated type.
* All IPA registers are 32 bits wide.
* *
* Certain register types are duplicated for a number of instances of * Certain "parameterized" register types are duplicated for a number of
* something. For example, each IPA endpoint has an set of registers * instances of something. For example, each IPA endpoint has an set of
* defining its configuration. The offset to an endpoint's set of registers * registers defining its configuration. The offset to an endpoint's set
* is computed based on an "base" offset, plus an endpoint's ID multiplied * of registers is computed based on an "base" offset, plus an endpoint's
* and a "stride" value for the register. For such registers, the offset is * ID multiplied and a "stride" value for the register. Similarly, some
* computed by a function-like macro that takes a parameter used in the * registers have an offset that depends on execution environment. In
* computation. * this case, the stride is multiplied by a member of the gsi_ee_id
* enumerated type.
* *
* Some register offsets depend on execution environment. For these an "ee" * Each version of IPA implements an array of ipa_reg structures indexed
* parameter is supplied to the offset macro. The "ee" value is a member of * by register ID. Each entry in the array specifies the base offset and
* the gsi_ee enumerated type. * (for parameterized registers) a non-zero stride value. Not all versions
* of IPA define all registers. The offset for a register is returned by
* ipa_reg_offset() when the register's ipa_reg structure is supplied;
* zero is returned for an undefined register (this should never happen).
* *
* The offset of a register dependent on endpoint ID is computed by a macro * Some registers encode multiple fields within them. Each field in
* that is supplied a parameter "ep", "txep", or "rxep". A register with an * such a register has a unique identifier (from an enumerated type).
* "ep" parameter is valid for any endpoint; a register with a "txep" or * The position and width of the fields in a register are defined by
* "rxep" parameter is valid only for TX or RX endpoints, respectively. The * an array of field masks, indexed by field ID. Two functions are
* "*ep" value is assumed to be less than the maximum valid endpoint ID * used to access register fields; both take an ipa_reg structure as
* for the current hardware, and that will not exceed IPA_ENDPOINT_MAX. * argument. To encode a value to be represented in a register field,
* * the value and field ID are passed to ipa_reg_encode(). To extract
* The offset of registers related to filter and route tables is computed * a value encoded in a register field, the field ID is passed to
* by a macro that is supplied a parameter "er". The "er" represents an * ipa_reg_decode(). In addition, for single-bit fields, ipa_reg_bit()
* endpoint ID for filters, or a route ID for routes. For filters, the * can be used to either encode the bit value, or to generate a mask
* endpoint ID must be less than IPA_ENDPOINT_MAX, but is further restricted * used to extract the bit value.
* because not all endpoints support filtering. For routes, the route ID
* must be less than IPA_ROUTE_MAX.
*
* The offset of registers related to resource types is computed by a macro
* that is supplied a parameter "rt". The "rt" represents a resource type,
* which is a member of the ipa_resource_type_src enumerated type for
* source endpoint resources or the ipa_resource_type_dst enumerated type
* for destination endpoint resources.
*
* Some registers encode multiple fields within them. For these, each field
* has a symbol below defining a field mask that encodes both the position
* and width of the field within its register.
*
* In some cases, different versions of IPA hardware use different offset or
* field mask values. In such cases an inline_function(ipa) is used rather
* than a MACRO to define the offset or field mask to use.
*
* Finally, some registers hold bitmasks representing endpoints. In such
* cases the @available field in the @ipa structure defines the "full" set
* of valid bits for the register.
*/ */
/* enum ipa_reg_id - IPA register IDs */ /* enum ipa_reg_id - IPA register IDs */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment