Commit fef1869f authored by David S. Miller's avatar David S. Miller

Merge branch 'ipa-next'

Alex Elder says:

====================
net: ipa: a few last bits

This series incorporates a few last things that didn't fit neatly
with patches I've posted recently.

The first patch eliminates all remaining kernel-doc warnings.
There's still room for kernel-doc improvement, but at least what's
there will no longer produce warnings.

The next moves the definition of the value to store in the backward
compatibility register (when present) into platform data files.

The third removes two endpoint definitions that do not need to be
defined.

The next two switch the naming convention used for configuration
data files to be based on the IPA version rather than the specific
platform.  I was skeptical about this at first (i.e., I thought a
platform might have quirks separate from the IPA version).  But
I'm now convinced the IPA version is enough to define the details
of the hardware block.  If any exceptions to this are found, we can
treat those differently.  Note:  these two patches produce warnings
from checkpatch.pl about updating MAINTAINERS: these can be ignored.

The sixth removes unnecessary checks for alignment of DMA memory
allocations, based comments from David Laight.

And the last removes a symbol representing the size of a table
entry, using sizeof(__le64) in its place.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9d036544 4ea29143
...@@ -12,8 +12,7 @@ config QCOM_IPA ...@@ -12,8 +12,7 @@ config QCOM_IPA
that is capable of generic hardware handling of IP packets, that is capable of generic hardware handling of IP packets,
including routing, filtering, and NAT. Currently the IPA including routing, filtering, and NAT. Currently the IPA
driver supports only basic transport of network traffic driver supports only basic transport of network traffic
between the AP and modem, on the Qualcomm SDM845 and SC7180 between the AP and modem.
SoCs.
Note that if selected, the selection type must match that Note that if selected, the selection type must match that
of QCOM_Q6V5_COMMON (Y or M). of QCOM_Q6V5_COMMON (Y or M).
......
...@@ -9,4 +9,4 @@ ipa-y := ipa_main.o ipa_clock.o ipa_reg.o ipa_mem.o \ ...@@ -9,4 +9,4 @@ ipa-y := ipa_main.o ipa_clock.o ipa_reg.o ipa_mem.o \
ipa_endpoint.o ipa_cmd.o ipa_modem.o \ ipa_endpoint.o ipa_cmd.o ipa_modem.o \
ipa_resource.o ipa_qmi.o ipa_qmi_msg.o ipa_resource.o ipa_qmi.o ipa_qmi_msg.o
ipa-y += ipa_data-sdm845.o ipa_data-sc7180.o ipa-y += ipa_data-v3.5.1.o ipa_data-v4.2.o
...@@ -1444,18 +1444,13 @@ static int gsi_ring_alloc(struct gsi *gsi, struct gsi_ring *ring, u32 count) ...@@ -1444,18 +1444,13 @@ static int gsi_ring_alloc(struct gsi *gsi, struct gsi_ring *ring, u32 count)
dma_addr_t addr; dma_addr_t addr;
/* Hardware requires a 2^n ring size, with alignment equal to size. /* Hardware requires a 2^n ring size, with alignment equal to size.
* The size is a power of 2, so we can check alignment using just * The DMA address returned by dma_alloc_coherent() is guaranteed to
* the bottom 32 bits for a DMA address of any size. * be a power-of-2 number of pages, which satisfies the requirement.
*/ */
ring->virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL); ring->virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL);
if (ring->virt && lower_32_bits(addr) % size) { if (!ring->virt)
dma_free_coherent(dev, size, ring->virt, addr);
dev_err(dev, "unable to alloc 0x%x-aligned ring buffer\n",
size);
return -EINVAL; /* Not a good error value, but distinct */
} else if (!ring->virt) {
return -ENOMEM; return -ENOMEM;
}
ring->addr = addr; ring->addr = addr;
ring->count = count; ring->count = count;
......
...@@ -14,7 +14,7 @@ struct gsi_trans; ...@@ -14,7 +14,7 @@ struct gsi_trans;
struct gsi_ring; struct gsi_ring;
struct gsi_channel; struct gsi_channel;
#define GSI_RING_ELEMENT_SIZE 16 /* bytes */ #define GSI_RING_ELEMENT_SIZE 16 /* bytes; must be a power of 2 */
/* Return the entry that follows one provided in a transaction pool */ /* Return the entry that follows one provided in a transaction pool */
void *gsi_trans_pool_next(struct gsi_trans_pool *pool, void *element); void *gsi_trans_pool_next(struct gsi_trans_pool *pool, void *element);
...@@ -100,7 +100,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel); ...@@ -100,7 +100,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel);
/** /**
* gsi_ring_virt() - Return virtual address for a ring entry * gsi_ring_virt() - Return virtual address for a ring entry
* @ring: Ring whose address is to be translated * @ring: Ring whose address is to be translated
* @addr: Index (slot number) of entry * @index: Index (slot number) of entry
*/ */
void *gsi_ring_virt(struct gsi_ring *ring, u32 index); void *gsi_ring_virt(struct gsi_ring *ring, u32 index);
......
...@@ -153,11 +153,10 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool, ...@@ -153,11 +153,10 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
size = __roundup_pow_of_two(size); size = __roundup_pow_of_two(size);
total_size = (count + max_alloc - 1) * size; total_size = (count + max_alloc - 1) * size;
/* The allocator will give us a power-of-2 number of pages. But we /* The allocator will give us a power-of-2 number of pages
* can't guarantee that, so request it. That way we won't waste any * sufficient to satisfy our request. Round up our requested
* memory that would be available beyond the required space. * size to avoid any unused space in the allocation. This way
* * gsi_trans_pool_exit_dma() can assume the total allocated
* Note that gsi_trans_pool_exit_dma() assumes the total allocated
* size is exactly (count * size). * size is exactly (count * size).
*/ */
total_size = get_order(total_size) << PAGE_SHIFT; total_size = get_order(total_size) << PAGE_SHIFT;
......
...@@ -71,7 +71,7 @@ struct gsi_trans { ...@@ -71,7 +71,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
* @gsi: GSI pointer * @pool: GSI transaction poll 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
...@@ -123,7 +123,8 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool, ...@@ -123,7 +123,8 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
void *gsi_trans_pool_alloc_dma(struct gsi_trans_pool *pool, dma_addr_t *addr); void *gsi_trans_pool_alloc_dma(struct gsi_trans_pool *pool, dma_addr_t *addr);
/** /**
* gsi_trans_pool_exit() - Inverse of gsi_trans_pool_init() * gsi_trans_pool_exit_dma() - Inverse of gsi_trans_pool_init_dma()
* @dev: Device used for DMA
* @pool: Pool pointer * @pool: Pool pointer
*/ */
void gsi_trans_pool_exit_dma(struct device *dev, struct gsi_trans_pool *pool); void gsi_trans_pool_exit_dma(struct device *dev, struct gsi_trans_pool *pool);
......
...@@ -44,6 +44,8 @@ enum ipa_flag { ...@@ -44,6 +44,8 @@ enum ipa_flag {
* @version: IPA hardware version * @version: IPA hardware version
* @pdev: Platform device * @pdev: Platform device
* @completion: Used to signal pipeline clear transfer complete * @completion: Used to signal pipeline clear transfer complete
* @nb: Notifier block used for remoteproc SSR
* @notifier: Remoteproc SSR notifier
* @smp2p: SMP2P information * @smp2p: SMP2P information
* @clock: IPA clocking information * @clock: IPA clocking information
* @table_addr: DMA address of filter/route table content * @table_addr: DMA address of filter/route table content
...@@ -58,13 +60,12 @@ enum ipa_flag { ...@@ -58,13 +60,12 @@ enum ipa_flag {
* @mem_size: Total size (bytes) of memory at @mem_virt * @mem_size: Total size (bytes) of memory at @mem_virt
* @mem: Array of IPA-local memory region descriptors * @mem: Array of IPA-local memory region descriptors
* @imem_iova: I/O virtual address of IPA region in IMEM * @imem_iova: I/O virtual address of IPA region in IMEM
* @imem_size; Size of IMEM region * @imem_size: Size of IMEM region
* @smem_iova: I/O virtual address of IPA region in SMEM * @smem_iova: I/O virtual address of IPA region in SMEM
* @smem_size; Size of SMEM region * @smem_size: Size of SMEM region
* @zero_addr: DMA address of preallocated zero-filled memory * @zero_addr: DMA address of preallocated zero-filled memory
* @zero_virt: Virtual address of preallocated zero-filled memory * @zero_virt: Virtual address of preallocated zero-filled memory
* @zero_size: Size (bytes) of preallocated zero-filled memory * @zero_size: Size (bytes) of preallocated zero-filled memory
* @wakeup_source: Wakeup source information
* @available: Bit mask indicating endpoints hardware supports * @available: Bit mask indicating endpoints hardware supports
* @filter_map: Bit mask indicating endpoints that support filtering * @filter_map: Bit mask indicating endpoints that support filtering
* @initialized: Bit mask indicating endpoints initialized * @initialized: Bit mask indicating endpoints initialized
......
...@@ -153,7 +153,7 @@ static void ipa_cmd_validate_build(void) ...@@ -153,7 +153,7 @@ static void ipa_cmd_validate_build(void)
* of entries, as and IPv4 and IPv6 route tables have the same number * of entries, as and IPv4 and IPv6 route tables have the same number
* of entries. * of entries.
*/ */
#define TABLE_SIZE (TABLE_COUNT_MAX * IPA_TABLE_ENTRY_SIZE) #define TABLE_SIZE (TABLE_COUNT_MAX * sizeof(__le64))
#define TABLE_COUNT_MAX max_t(u32, IPA_ROUTE_COUNT_MAX, IPA_FILTER_COUNT_MAX) #define TABLE_COUNT_MAX max_t(u32, IPA_ROUTE_COUNT_MAX, IPA_FILTER_COUNT_MAX)
BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK)); BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK));
BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK)); BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK));
......
...@@ -20,11 +20,18 @@ struct gsi_channel; ...@@ -20,11 +20,18 @@ struct gsi_channel;
/** /**
* enum ipa_cmd_opcode: IPA immediate commands * enum ipa_cmd_opcode: IPA immediate commands
* *
* All immediate commands are issued using the AP command TX endpoint. * @IPA_CMD_IP_V4_FILTER_INIT: Initialize IPv4 filter table
* The numeric values here are the opcodes for IPA v3.5.1 hardware. * @IPA_CMD_IP_V6_FILTER_INIT: Initialize IPv6 filter table
* @IPA_CMD_IP_V4_ROUTING_INIT: Initialize IPv4 routing table
* @IPA_CMD_IP_V6_ROUTING_INIT: Initialize IPv6 routing table
* @IPA_CMD_HDR_INIT_LOCAL: Initialize IPA-local header memory
* @IPA_CMD_REGISTER_WRITE: Register write performed by IPA
* @IPA_CMD_IP_PACKET_INIT: Set up next packet's destination endpoint
* @IPA_CMD_DMA_SHARED_MEM: DMA command performed by IPA
* @IPA_CMD_IP_PACKET_TAG_STATUS: Have next packet generate tag * status
* @IPA_CMD_NONE: Special (invalid) "not a command" value
* *
* IPA_CMD_NONE is a special (invalid) value that's used to indicate * All immediate commands are issued using the AP command TX endpoint.
* a request is *not* an immediate command.
*/ */
enum ipa_cmd_opcode { enum ipa_cmd_opcode {
IPA_CMD_NONE = 0x0, IPA_CMD_NONE = 0x0,
...@@ -96,7 +103,7 @@ static inline bool ipa_cmd_data_valid(struct ipa *ipa) ...@@ -96,7 +103,7 @@ static inline bool ipa_cmd_data_valid(struct ipa *ipa)
* *
* Return: 0 if successful, or a negative error code * Return: 0 if successful, or a negative error code
*/ */
int ipa_cmd_pool_init(struct gsi_channel *gsi_channel, u32 tre_count); int ipa_cmd_pool_init(struct gsi_channel *channel, u32 tre_count);
/** /**
* ipa_cmd_pool_exit() - Inverse of ipa_cmd_pool_init() * ipa_cmd_pool_exit() - Inverse of ipa_cmd_pool_init()
...@@ -124,7 +131,7 @@ void ipa_cmd_table_init_add(struct gsi_trans *trans, enum ipa_cmd_opcode opcode, ...@@ -124,7 +131,7 @@ void ipa_cmd_table_init_add(struct gsi_trans *trans, enum ipa_cmd_opcode opcode,
/** /**
* ipa_cmd_hdr_init_local_add() - Add a header init command to a transaction * ipa_cmd_hdr_init_local_add() - Add a header init command to a transaction
* @ipa: IPA structure * @trans: GSI transaction
* @offset: Offset of header memory in IPA local space * @offset: Offset of header memory in IPA local space
* @size: Size of header memory * @size: Size of header memory
* @addr: DMA address of buffer to be written from * @addr: DMA address of buffer to be written from
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "ipa_endpoint.h" #include "ipa_endpoint.h"
#include "ipa_mem.h" #include "ipa_mem.h"
/** enum ipa_resource_type - IPA resource types */ /** enum ipa_resource_type - IPA resource types for an SoC having IPA v3.5.1 */
enum ipa_resource_type { enum ipa_resource_type {
/* Source resource types; first must have value 0 */ /* Source resource types; first must have value 0 */
IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS = 0, IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS = 0,
...@@ -25,7 +25,7 @@ enum ipa_resource_type { ...@@ -25,7 +25,7 @@ enum ipa_resource_type {
IPA_RESOURCE_TYPE_DST_DPS_DMARS, IPA_RESOURCE_TYPE_DST_DPS_DMARS,
}; };
/* Resource groups used for the SDM845 SoC */ /* Resource groups used for an SoC having IPA v3.5.1 */
enum ipa_rsrc_group_id { enum ipa_rsrc_group_id {
/* Source resource group identifiers */ /* Source resource group identifiers */
IPA_RSRC_GROUP_SRC_LWA_DL = 0, IPA_RSRC_GROUP_SRC_LWA_DL = 0,
...@@ -41,7 +41,7 @@ enum ipa_rsrc_group_id { ...@@ -41,7 +41,7 @@ enum ipa_rsrc_group_id {
IPA_RSRC_GROUP_DST_COUNT, /* Last; not a destination group */ IPA_RSRC_GROUP_DST_COUNT, /* Last; not a destination group */
}; };
/* QSB configuration for the SDM845 SoC. */ /* QSB configuration data for an SoC having IPA v3.5.1 */
static const struct ipa_qsb_data ipa_qsb_data[] = { static const struct ipa_qsb_data ipa_qsb_data[] = {
[IPA_QSB_MASTER_DDR] = { [IPA_QSB_MASTER_DDR] = {
.max_writes = 8, .max_writes = 8,
...@@ -53,7 +53,7 @@ static const struct ipa_qsb_data ipa_qsb_data[] = { ...@@ -53,7 +53,7 @@ static const struct ipa_qsb_data ipa_qsb_data[] = {
}, },
}; };
/* Endpoint configuration for the SDM845 SoC. */ /* Endpoint datdata for an SoC having IPA v3.5.1 */
static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = { static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
[IPA_ENDPOINT_AP_COMMAND_TX] = { [IPA_ENDPOINT_AP_COMMAND_TX] = {
.ee_id = GSI_EE_AP, .ee_id = GSI_EE_AP,
...@@ -144,12 +144,6 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = { ...@@ -144,12 +144,6 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
}, },
}, },
}, },
[IPA_ENDPOINT_MODEM_COMMAND_TX] = {
.ee_id = GSI_EE_MODEM,
.channel_id = 1,
.endpoint_id = 4,
.toward_ipa = true,
},
[IPA_ENDPOINT_MODEM_LAN_TX] = { [IPA_ENDPOINT_MODEM_LAN_TX] = {
.ee_id = GSI_EE_MODEM, .ee_id = GSI_EE_MODEM,
.channel_id = 0, .channel_id = 0,
...@@ -159,12 +153,6 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = { ...@@ -159,12 +153,6 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
.filter_support = true, .filter_support = true,
}, },
}, },
[IPA_ENDPOINT_MODEM_LAN_RX] = {
.ee_id = GSI_EE_MODEM,
.channel_id = 3,
.endpoint_id = 13,
.toward_ipa = false,
},
[IPA_ENDPOINT_MODEM_AP_TX] = { [IPA_ENDPOINT_MODEM_AP_TX] = {
.ee_id = GSI_EE_MODEM, .ee_id = GSI_EE_MODEM,
.channel_id = 4, .channel_id = 4,
...@@ -182,7 +170,7 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = { ...@@ -182,7 +170,7 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
}, },
}; };
/* Source resource configuration data for the SDM845 SoC */ /* Source resource configuration data for an SoC having IPA v3.5.1 */
static const struct ipa_resource ipa_resource_src[] = { static const struct ipa_resource ipa_resource_src[] = {
[IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = { [IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = {
.limits[IPA_RSRC_GROUP_SRC_LWA_DL] = { .limits[IPA_RSRC_GROUP_SRC_LWA_DL] = {
...@@ -244,7 +232,7 @@ static const struct ipa_resource ipa_resource_src[] = { ...@@ -244,7 +232,7 @@ static const struct ipa_resource ipa_resource_src[] = {
}, },
}; };
/* Destination resource configuration data for the SDM845 SoC */ /* Destination resource configuration data for an SoC having IPA v3.5.1 */
static const struct ipa_resource ipa_resource_dst[] = { static const struct ipa_resource ipa_resource_dst[] = {
[IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = { [IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = {
.limits[IPA_RSRC_GROUP_DST_LWA_DL] = { .limits[IPA_RSRC_GROUP_DST_LWA_DL] = {
...@@ -270,7 +258,7 @@ static const struct ipa_resource ipa_resource_dst[] = { ...@@ -270,7 +258,7 @@ static const struct ipa_resource ipa_resource_dst[] = {
}, },
}; };
/* Resource configuration for the SDM845 SoC. */ /* Resource configuration data for an SoC having IPA v3.5.1 */
static const struct ipa_resource_data ipa_resource_data = { static const struct ipa_resource_data ipa_resource_data = {
.rsrc_group_src_count = IPA_RSRC_GROUP_SRC_COUNT, .rsrc_group_src_count = IPA_RSRC_GROUP_SRC_COUNT,
.rsrc_group_dst_count = IPA_RSRC_GROUP_DST_COUNT, .rsrc_group_dst_count = IPA_RSRC_GROUP_DST_COUNT,
...@@ -280,7 +268,7 @@ static const struct ipa_resource_data ipa_resource_data = { ...@@ -280,7 +268,7 @@ static const struct ipa_resource_data ipa_resource_data = {
.resource_dst = ipa_resource_dst, .resource_dst = ipa_resource_dst,
}; };
/* IPA-resident memory region configuration for the SDM845 SoC. */ /* IPA-resident memory region data for an SoC having IPA v3.5.1 */
static const struct ipa_mem ipa_mem_local_data[] = { static const struct ipa_mem ipa_mem_local_data[] = {
[IPA_MEM_UC_SHARED] = { [IPA_MEM_UC_SHARED] = {
.offset = 0x0000, .offset = 0x0000,
...@@ -359,6 +347,7 @@ static const struct ipa_mem ipa_mem_local_data[] = { ...@@ -359,6 +347,7 @@ static const struct ipa_mem ipa_mem_local_data[] = {
}, },
}; };
/* Memory configuration data for an SoC having IPA v3.5.1 */
static const struct ipa_mem_data ipa_mem_data = { static const struct ipa_mem_data ipa_mem_data = {
.local_count = ARRAY_SIZE(ipa_mem_local_data), .local_count = ARRAY_SIZE(ipa_mem_local_data),
.local = ipa_mem_local_data, .local = ipa_mem_local_data,
...@@ -388,15 +377,21 @@ static const struct ipa_interconnect_data ipa_interconnect_data[] = { ...@@ -388,15 +377,21 @@ static const struct ipa_interconnect_data ipa_interconnect_data[] = {
}, },
}; };
/* Clock and interconnect configuration data for an SoC having IPA v3.5.1 */
static const struct ipa_clock_data ipa_clock_data = { static const struct ipa_clock_data ipa_clock_data = {
.core_clock_rate = 75 * 1000 * 1000, /* Hz */ .core_clock_rate = 75 * 1000 * 1000, /* Hz */
.interconnect_count = ARRAY_SIZE(ipa_interconnect_data), .interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
.interconnect_data = ipa_interconnect_data, .interconnect_data = ipa_interconnect_data,
}; };
/* Configuration data for the SDM845 SoC. */ /* Configuration data for an SoC having IPA v3.5.1 */
const struct ipa_data ipa_data_sdm845 = { const struct ipa_data ipa_data_v3_5_1 = {
.version = IPA_VERSION_3_5_1, .version = IPA_VERSION_3_5_1,
.backward_compat = BCR_CMDQ_L_LACK_ONE_ENTRY_FMASK |
BCR_TX_NOT_USING_BRESP_FMASK |
BCR_SUSPEND_L2_IRQ_FMASK |
BCR_HOLB_DROP_L2_IRQ_FMASK |
BCR_DUAL_TX_FMASK,
.qsb_count = ARRAY_SIZE(ipa_qsb_data), .qsb_count = ARRAY_SIZE(ipa_qsb_data),
.qsb_data = ipa_qsb_data, .qsb_data = ipa_qsb_data,
.endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data), .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "ipa_endpoint.h" #include "ipa_endpoint.h"
#include "ipa_mem.h" #include "ipa_mem.h"
/** enum ipa_resource_type - IPA resource types */ /** enum ipa_resource_type - IPA resource types for an SoC having IPA v4.2 */
enum ipa_resource_type { enum ipa_resource_type {
/* Source resource types; first must have value 0 */ /* Source resource types; first must have value 0 */
IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS = 0, IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS = 0,
...@@ -23,7 +23,7 @@ enum ipa_resource_type { ...@@ -23,7 +23,7 @@ enum ipa_resource_type {
IPA_RESOURCE_TYPE_DST_DPS_DMARS, IPA_RESOURCE_TYPE_DST_DPS_DMARS,
}; };
/* Resource groups used for the SC7180 SoC */ /* Resource groups used for an SoC having IPA v4.2 */
enum ipa_rsrc_group_id { enum ipa_rsrc_group_id {
/* Source resource group identifiers */ /* Source resource group identifiers */
IPA_RSRC_GROUP_SRC_UL_DL = 0, IPA_RSRC_GROUP_SRC_UL_DL = 0,
...@@ -34,7 +34,7 @@ enum ipa_rsrc_group_id { ...@@ -34,7 +34,7 @@ enum ipa_rsrc_group_id {
IPA_RSRC_GROUP_DST_COUNT, /* Last; not a destination group */ IPA_RSRC_GROUP_DST_COUNT, /* Last; not a destination group */
}; };
/* QSB configuration for the SC7180 SoC. */ /* QSB configuration data for an SoC having IPA v4.2 */
static const struct ipa_qsb_data ipa_qsb_data[] = { static const struct ipa_qsb_data ipa_qsb_data[] = {
[IPA_QSB_MASTER_DDR] = { [IPA_QSB_MASTER_DDR] = {
.max_writes = 8, .max_writes = 8,
...@@ -43,7 +43,7 @@ static const struct ipa_qsb_data ipa_qsb_data[] = { ...@@ -43,7 +43,7 @@ static const struct ipa_qsb_data ipa_qsb_data[] = {
}, },
}; };
/* Endpoint configuration for the SC7180 SoC. */ /* Endpoint configuration data for an SoC having IPA v4.2 */
static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = { static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
[IPA_ENDPOINT_AP_COMMAND_TX] = { [IPA_ENDPOINT_AP_COMMAND_TX] = {
.ee_id = GSI_EE_AP, .ee_id = GSI_EE_AP,
...@@ -164,7 +164,7 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = { ...@@ -164,7 +164,7 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
}, },
}; };
/* Source resource configuration data for the SC7180 SoC */ /* Source resource configuration data for an SoC having IPA v4.2 */
static const struct ipa_resource ipa_resource_src[] = { static const struct ipa_resource ipa_resource_src[] = {
[IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = { [IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = {
.limits[IPA_RSRC_GROUP_SRC_UL_DL] = { .limits[IPA_RSRC_GROUP_SRC_UL_DL] = {
...@@ -193,7 +193,7 @@ static const struct ipa_resource ipa_resource_src[] = { ...@@ -193,7 +193,7 @@ static const struct ipa_resource ipa_resource_src[] = {
}, },
}; };
/* Destination resource configuration data for the SC7180 SoC */ /* Destination resource configuration data for an SoC having IPA v4.2 */
static const struct ipa_resource ipa_resource_dst[] = { static const struct ipa_resource ipa_resource_dst[] = {
[IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = { [IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = {
.limits[IPA_RSRC_GROUP_DST_UL_DL_DPL] = { .limits[IPA_RSRC_GROUP_DST_UL_DL_DPL] = {
...@@ -207,7 +207,7 @@ static const struct ipa_resource ipa_resource_dst[] = { ...@@ -207,7 +207,7 @@ static const struct ipa_resource ipa_resource_dst[] = {
}, },
}; };
/* Resource configuration for the SC7180 SoC. */ /* Resource configuration data for an SoC having IPA v4.2 */
static const struct ipa_resource_data ipa_resource_data = { static const struct ipa_resource_data ipa_resource_data = {
.rsrc_group_src_count = IPA_RSRC_GROUP_SRC_COUNT, .rsrc_group_src_count = IPA_RSRC_GROUP_SRC_COUNT,
.rsrc_group_dst_count = IPA_RSRC_GROUP_DST_COUNT, .rsrc_group_dst_count = IPA_RSRC_GROUP_DST_COUNT,
...@@ -217,7 +217,7 @@ static const struct ipa_resource_data ipa_resource_data = { ...@@ -217,7 +217,7 @@ static const struct ipa_resource_data ipa_resource_data = {
.resource_dst = ipa_resource_dst, .resource_dst = ipa_resource_dst,
}; };
/* IPA-resident memory region configuration for the SC7180 SoC. */ /* IPA-resident memory region data for an SoC having IPA v4.2 */
static const struct ipa_mem ipa_mem_local_data[] = { static const struct ipa_mem ipa_mem_local_data[] = {
[IPA_MEM_UC_SHARED] = { [IPA_MEM_UC_SHARED] = {
.offset = 0x0000, .offset = 0x0000,
...@@ -311,6 +311,7 @@ static const struct ipa_mem ipa_mem_local_data[] = { ...@@ -311,6 +311,7 @@ static const struct ipa_mem ipa_mem_local_data[] = {
}, },
}; };
/* Memory configuration data for an SoC having IPA v4.2 */
static const struct ipa_mem_data ipa_mem_data = { static const struct ipa_mem_data ipa_mem_data = {
.local_count = ARRAY_SIZE(ipa_mem_local_data), .local_count = ARRAY_SIZE(ipa_mem_local_data),
.local = ipa_mem_local_data, .local = ipa_mem_local_data,
...@@ -320,7 +321,7 @@ static const struct ipa_mem_data ipa_mem_data = { ...@@ -320,7 +321,7 @@ static const struct ipa_mem_data ipa_mem_data = {
.smem_size = 0x00002000, .smem_size = 0x00002000,
}; };
/* Interconnect bandwidths are in 1000 byte/second units */ /* Interconnect rates are in 1000 byte/second units */
static const struct ipa_interconnect_data ipa_interconnect_data[] = { static const struct ipa_interconnect_data ipa_interconnect_data[] = {
{ {
.name = "memory", .name = "memory",
...@@ -340,15 +341,17 @@ static const struct ipa_interconnect_data ipa_interconnect_data[] = { ...@@ -340,15 +341,17 @@ static const struct ipa_interconnect_data ipa_interconnect_data[] = {
}, },
}; };
/* Clock and interconnect configuration data for an SoC having IPA v4.2 */
static const struct ipa_clock_data ipa_clock_data = { static const struct ipa_clock_data ipa_clock_data = {
.core_clock_rate = 100 * 1000 * 1000, /* Hz */ .core_clock_rate = 100 * 1000 * 1000, /* Hz */
.interconnect_count = ARRAY_SIZE(ipa_interconnect_data), .interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
.interconnect_data = ipa_interconnect_data, .interconnect_data = ipa_interconnect_data,
}; };
/* Configuration data for the SC7180 SoC. */ /* Configuration data for an SoC having IPA v4.2 */
const struct ipa_data ipa_data_sc7180 = { const struct ipa_data ipa_data_v4_2 = {
.version = IPA_VERSION_4_2, .version = IPA_VERSION_4_2,
/* backward_compat value is 0 */
.qsb_count = ARRAY_SIZE(ipa_qsb_data), .qsb_count = ARRAY_SIZE(ipa_qsb_data),
.qsb_data = ipa_qsb_data, .qsb_data = ipa_qsb_data,
.endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data), .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
......
...@@ -90,8 +90,8 @@ struct ipa_qsb_data { ...@@ -90,8 +90,8 @@ struct ipa_qsb_data {
* that can be included in a single transaction. * that can be included in a single transaction.
*/ */
struct gsi_channel_data { struct gsi_channel_data {
u16 tre_count; u16 tre_count; /* must be a power of 2 */
u16 event_count; u16 event_count; /* must be a power of 2 */
u8 tlv_count; u8 tlv_count;
}; };
...@@ -279,6 +279,7 @@ struct ipa_clock_data { ...@@ -279,6 +279,7 @@ struct ipa_clock_data {
/** /**
* struct ipa_data - combined IPA/GSI configuration data * struct ipa_data - combined IPA/GSI configuration data
* @version: IPA hardware version * @version: IPA hardware version
* @backward_compat: BCR register value (prior to IPA v4.5 only)
* @qsb_count: number of entries in the qsb_data array * @qsb_count: number of entries in the qsb_data array
* @qsb_data: Qualcomm System Bus configuration data * @qsb_data: Qualcomm System Bus configuration data
* @endpoint_count: number of entries in the endpoint_data array * @endpoint_count: number of entries in the endpoint_data array
...@@ -289,6 +290,7 @@ struct ipa_clock_data { ...@@ -289,6 +290,7 @@ struct ipa_clock_data {
*/ */
struct ipa_data { struct ipa_data {
enum ipa_version version; enum ipa_version version;
u32 backward_compat;
u32 qsb_count; /* number of entries in qsb_data[] */ u32 qsb_count; /* number of entries in qsb_data[] */
const struct ipa_qsb_data *qsb_data; const struct ipa_qsb_data *qsb_data;
u32 endpoint_count; /* number of entries in endpoint_data[] */ u32 endpoint_count; /* number of entries in endpoint_data[] */
...@@ -298,7 +300,7 @@ struct ipa_data { ...@@ -298,7 +300,7 @@ struct ipa_data {
const struct ipa_clock_data *clock_data; const struct ipa_clock_data *clock_data;
}; };
extern const struct ipa_data ipa_data_sdm845; extern const struct ipa_data ipa_data_v3_5_1;
extern const struct ipa_data ipa_data_sc7180; extern const struct ipa_data ipa_data_v4_2;
#endif /* _IPA_DATA_H_ */ #endif /* _IPA_DATA_H_ */
...@@ -25,15 +25,16 @@ struct ipa_gsi_endpoint_data; ...@@ -25,15 +25,16 @@ struct ipa_gsi_endpoint_data;
#define IPA_MTU ETH_DATA_LEN #define IPA_MTU ETH_DATA_LEN
enum ipa_endpoint_name { enum ipa_endpoint_name {
IPA_ENDPOINT_AP_MODEM_TX,
IPA_ENDPOINT_MODEM_LAN_TX,
IPA_ENDPOINT_MODEM_COMMAND_TX,
IPA_ENDPOINT_AP_COMMAND_TX, IPA_ENDPOINT_AP_COMMAND_TX,
IPA_ENDPOINT_MODEM_AP_TX,
IPA_ENDPOINT_AP_LAN_RX, IPA_ENDPOINT_AP_LAN_RX,
IPA_ENDPOINT_AP_MODEM_TX,
IPA_ENDPOINT_AP_MODEM_RX, IPA_ENDPOINT_AP_MODEM_RX,
IPA_ENDPOINT_MODEM_AP_RX, IPA_ENDPOINT_MODEM_COMMAND_TX,
IPA_ENDPOINT_MODEM_LAN_TX,
IPA_ENDPOINT_MODEM_LAN_RX, IPA_ENDPOINT_MODEM_LAN_RX,
IPA_ENDPOINT_MODEM_AP_TX,
IPA_ENDPOINT_MODEM_AP_RX,
IPA_ENDPOINT_MODEM_DL_NLO_TX,
IPA_ENDPOINT_COUNT, /* Number of names (not an index) */ IPA_ENDPOINT_COUNT, /* Number of names (not an index) */
}; };
...@@ -41,8 +42,20 @@ enum ipa_endpoint_name { ...@@ -41,8 +42,20 @@ enum ipa_endpoint_name {
/** /**
* struct ipa_endpoint - IPA endpoint information * struct ipa_endpoint - IPA endpoint information
* @channel_id: EP's GSI channel * @ipa: IPA pointer
* @evt_ring_id: EP's GSI channel event ring * @ee_id: Execution environmnent endpoint is associated with
* @channel_id: GSI channel used by the endpoint
* @endpoint_id: IPA endpoint number
* @toward_ipa: Endpoint direction (true = TX, false = RX)
* @data: Endpoint configuration data
* @trans_tre_max: Maximum number of TRE descriptors per transaction
* @evt_ring_id: GSI event ring used by the endpoint
* @netdev: Network device pointer, if endpoint uses one
* @replenish_enabled: Whether receive buffer replenishing is enabled
* @replenish_ready: Number of replenish transactions without doorbell
* @replenish_saved: Replenish requests held while disabled
* @replenish_backlog: Number of buffers needed to fill hardware queue
* @replenish_work: Work item used for repeated replenish failures
*/ */
struct ipa_endpoint { struct ipa_endpoint {
struct ipa *ipa; struct ipa *ipa;
...@@ -52,7 +65,7 @@ struct ipa_endpoint { ...@@ -52,7 +65,7 @@ struct ipa_endpoint {
bool toward_ipa; bool toward_ipa;
const struct ipa_endpoint_config_data *data; const struct ipa_endpoint_config_data *data;
u32 trans_tre_max; /* maximum descriptors per transaction */ u32 trans_tre_max;
u32 evt_ring_id; u32 evt_ring_id;
/* Net device this endpoint is associated with, if any */ /* Net device this endpoint is associated with, if any */
......
...@@ -24,6 +24,7 @@ typedef void (*ipa_irq_handler_t)(struct ipa *ipa, enum ipa_irq_id irq_id); ...@@ -24,6 +24,7 @@ typedef void (*ipa_irq_handler_t)(struct ipa *ipa, enum ipa_irq_id irq_id);
/** /**
* ipa_interrupt_add() - Register a handler for an IPA interrupt type * ipa_interrupt_add() - Register a handler for an IPA interrupt type
* @interrupt: IPA interrupt structure
* @irq_id: IPA interrupt type * @irq_id: IPA interrupt type
* @handler: Handler function for the interrupt * @handler: Handler function for the interrupt
* *
......
...@@ -397,9 +397,9 @@ static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data) ...@@ -397,9 +397,9 @@ static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data)
u32 granularity; u32 granularity;
u32 val; u32 val;
/* IPA v4.5 has no backward compatibility register */ /* IPA v4.5+ has no backward compatibility register */
if (version < IPA_VERSION_4_5) { if (version < IPA_VERSION_4_5) {
val = ipa_reg_bcr_val(version); val = data->backward_compat;
iowrite32(val, ipa->reg_virt + IPA_REG_BCR_OFFSET); iowrite32(val, ipa->reg_virt + IPA_REG_BCR_OFFSET);
} }
...@@ -578,11 +578,11 @@ static int ipa_firmware_load(struct device *dev) ...@@ -578,11 +578,11 @@ static int ipa_firmware_load(struct device *dev)
static const struct of_device_id ipa_match[] = { static const struct of_device_id ipa_match[] = {
{ {
.compatible = "qcom,sdm845-ipa", .compatible = "qcom,sdm845-ipa",
.data = &ipa_data_sdm845, .data = &ipa_data_v3_5_1,
}, },
{ {
.compatible = "qcom,sc7180-ipa", .compatible = "qcom,sc7180-ipa",
.data = &ipa_data_sc7180, .data = &ipa_data_v4_2,
}, },
{ }, { },
}; };
......
...@@ -77,7 +77,7 @@ enum ipa_mem_id { ...@@ -77,7 +77,7 @@ enum ipa_mem_id {
* struct ipa_mem - IPA local memory region description * struct ipa_mem - IPA local memory region description
* @offset: offset in IPA memory space to base of the region * @offset: offset in IPA memory space to base of the region
* @size: size in bytes base of the region * @size: size in bytes base of the region
* @canary_count # 32-bit "canary" values that precede region * @canary_count: Number of 32-bit "canary" values that precede region
*/ */
struct ipa_mem { struct ipa_mem {
u32 offset; u32 offset;
......
...@@ -308,12 +308,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi) ...@@ -308,12 +308,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
mem = &ipa->mem[IPA_MEM_V4_ROUTE]; mem = &ipa->mem[IPA_MEM_V4_ROUTE];
req.v4_route_tbl_info_valid = 1; req.v4_route_tbl_info_valid = 1;
req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset; req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset;
req.v4_route_tbl_info.count = mem->size / IPA_TABLE_ENTRY_SIZE; req.v4_route_tbl_info.count = mem->size / sizeof(__le64);
mem = &ipa->mem[IPA_MEM_V6_ROUTE]; mem = &ipa->mem[IPA_MEM_V6_ROUTE];
req.v6_route_tbl_info_valid = 1; req.v6_route_tbl_info_valid = 1;
req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset; req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset;
req.v6_route_tbl_info.count = mem->size / IPA_TABLE_ENTRY_SIZE; req.v6_route_tbl_info.count = mem->size / sizeof(__le64);
mem = &ipa->mem[IPA_MEM_V4_FILTER]; mem = &ipa->mem[IPA_MEM_V4_FILTER];
req.v4_filter_tbl_start_valid = 1; req.v4_filter_tbl_start_valid = 1;
...@@ -352,8 +352,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi) ...@@ -352,8 +352,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
req.v4_hash_route_tbl_info_valid = 1; req.v4_hash_route_tbl_info_valid = 1;
req.v4_hash_route_tbl_info.start = req.v4_hash_route_tbl_info.start =
ipa->mem_offset + mem->offset; ipa->mem_offset + mem->offset;
req.v4_hash_route_tbl_info.count = req.v4_hash_route_tbl_info.count = mem->size / sizeof(__le64);
mem->size / IPA_TABLE_ENTRY_SIZE;
} }
mem = &ipa->mem[IPA_MEM_V6_ROUTE_HASHED]; mem = &ipa->mem[IPA_MEM_V6_ROUTE_HASHED];
...@@ -361,8 +360,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi) ...@@ -361,8 +360,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
req.v6_hash_route_tbl_info_valid = 1; req.v6_hash_route_tbl_info_valid = 1;
req.v6_hash_route_tbl_info.start = req.v6_hash_route_tbl_info.start =
ipa->mem_offset + mem->offset; ipa->mem_offset + mem->offset;
req.v6_hash_route_tbl_info.count = req.v6_hash_route_tbl_info.count = mem->size / sizeof(__le64);
mem->size / IPA_TABLE_ENTRY_SIZE;
} }
mem = &ipa->mem[IPA_MEM_V4_FILTER_HASHED]; mem = &ipa->mem[IPA_MEM_V4_FILTER_HASHED];
......
...@@ -13,11 +13,15 @@ struct ipa; ...@@ -13,11 +13,15 @@ struct ipa;
/** /**
* struct ipa_qmi - QMI state associated with an IPA * struct ipa_qmi - QMI state associated with an IPA
* @client_handle - used to send an QMI requests to the modem * @client_handle: Used to send an QMI requests to the modem
* @server_handle - used to handle QMI requests from the modem * @server_handle: Used to handle QMI requests from the modem
* @initialized - whether QMI initialization has completed * @modem_sq: QMAP socket address for the modem QMI server
* @indication_register_received - tracks modem request receipt * @init_driver_work: Work structure used for INIT_DRIVER message handling
* @init_driver_response_received - tracks modem response receipt * @initial_boot: True if first boot has not yet completed
* @uc_ready: True once DRIVER_INIT_COMPLETE request received
* @modem_ready: True when INIT_DRIVER response received
* @indication_requested: True when INDICATION_REGISTER request received
* @indication_sent: True when INIT_COMPLETE indication sent
*/ */
struct ipa_qmi { struct ipa_qmi {
struct qmi_handle client_handle; struct qmi_handle client_handle;
......
...@@ -235,27 +235,6 @@ static inline u32 ipa_reg_state_aggr_active_offset(enum ipa_version version) ...@@ -235,27 +235,6 @@ static inline u32 ipa_reg_state_aggr_active_offset(enum ipa_version version)
#define BCR_FILTER_PREFETCH_EN_FMASK GENMASK(8, 8) #define BCR_FILTER_PREFETCH_EN_FMASK GENMASK(8, 8)
#define BCR_ROUTER_PREFETCH_EN_FMASK GENMASK(9, 9) #define BCR_ROUTER_PREFETCH_EN_FMASK GENMASK(9, 9)
/* Backward compatibility register value to use for each version */
static inline u32 ipa_reg_bcr_val(enum ipa_version version)
{
if (version == IPA_VERSION_3_5_1)
return BCR_CMDQ_L_LACK_ONE_ENTRY_FMASK |
BCR_TX_NOT_USING_BRESP_FMASK |
BCR_SUSPEND_L2_IRQ_FMASK |
BCR_HOLB_DROP_L2_IRQ_FMASK |
BCR_DUAL_TX_FMASK;
if (version == IPA_VERSION_4_0 || version == IPA_VERSION_4_1)
return BCR_CMDQ_L_LACK_ONE_ENTRY_FMASK |
BCR_SUSPEND_L2_IRQ_FMASK |
BCR_HOLB_DROP_L2_IRQ_FMASK |
BCR_DUAL_TX_FMASK;
/* assert(version != IPA_VERSION_4_5); */
return 0x00000000;
}
/* The value of the next register must be a multiple of 8 (bottom 3 bits 0) */ /* The value of the next register must be a multiple of 8 (bottom 3 bits 0) */
#define IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET 0x000001e8 #define IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET 0x000001e8
......
...@@ -28,7 +28,7 @@ void ipa_smp2p_exit(struct ipa *ipa); ...@@ -28,7 +28,7 @@ void ipa_smp2p_exit(struct ipa *ipa);
/** /**
* ipa_smp2p_disable() - Prevent "ipa-setup-ready" interrupt handling * ipa_smp2p_disable() - Prevent "ipa-setup-ready" interrupt handling
* @IPA: IPA pointer * @ipa: IPA pointer
* *
* Prevent handling of the "setup ready" interrupt from the modem. * Prevent handling of the "setup ready" interrupt from the modem.
* This is used before initiating shutdown of the driver. * This is used before initiating shutdown of the driver.
......
...@@ -27,28 +27,38 @@ ...@@ -27,28 +27,38 @@
/** /**
* DOC: IPA Filter and Route Tables * DOC: IPA Filter and Route Tables
* *
* The IPA has tables defined in its local shared memory that define filter * The IPA has tables defined in its local (IPA-resident) memory that define
* and routing rules. Each entry in these tables contains a 64-bit DMA * filter and routing rules. An entry in either of these tables is a little
* address that refers to DRAM (system memory) containing a rule definition. * endian 64-bit "slot" that holds the address of a rule definition. (The
* size of these slots is 64 bits regardless of the host DMA address size.)
*
* Separate tables (both filter and route) used for IPv4 and IPv6. There
* are normally another set of "hashed" filter and route tables, which are
* used with a hash of message metadata. Hashed operation is not supported
* by all IPA hardware (IPA v4.2 doesn't support hashed tables).
*
* Rules can be in local memory or in DRAM (system memory). The offset of
* an object (such as a route or filter table) in IPA-resident memory must
* 128-byte aligned. An object in system memory (such as a route or filter
* rule) must be at an 8-byte aligned address. We currently only place
* route or filter rules in system memory.
*
* A rule consists of a contiguous block of 32-bit values terminated with * A rule consists of a contiguous block of 32-bit values terminated with
* 32 zero bits. A special "zero entry" rule consisting of 64 zero bits * 32 zero bits. A special "zero entry" rule consisting of 64 zero bits
* represents "no filtering" or "no routing," and is the reset value for * represents "no filtering" or "no routing," and is the reset value for
* filter or route table rules. Separate tables (both filter and route) * filter or route table rules.
* used for IPv4 and IPv6. Additionally, there can be hashed filter or
* route tables, which are used when a hash of message metadata matches.
* Hashed operation is not supported by all IPA hardware.
* *
* Each filter rule is associated with an AP or modem TX endpoint, though * Each filter rule is associated with an AP or modem TX endpoint, though
* not all TX endpoints support filtering. The first 64-bit entry in a * not all TX endpoints support filtering. The first 64-bit slot in a
* filter table is a bitmap indicating which endpoints have entries in * filter table is a bitmap indicating which endpoints have entries in
* the table. The low-order bit (bit 0) in this bitmap represents a * the table. The low-order bit (bit 0) in this bitmap represents a
* special global filter, which applies to all traffic. This is not * special global filter, which applies to all traffic. This is not
* used in the current code. Bit 1, if set, indicates that there is an * used in the current code. Bit 1, if set, indicates that there is an
* entry (i.e. a DMA address referring to a rule) for endpoint 0 in the * entry (i.e. slot containing a system address referring to a rule) for
* table. Bit 2, if set, indicates there is an entry for endpoint 1, * endpoint 0 in the table. Bit 3, if set, indicates there is an entry
* and so on. Space is set aside in IPA local memory to hold as many * for endpoint 2, and so on. Space is set aside in IPA local memory to
* filter table entries as might be required, but typically they are not * hold as many filter table entries as might be required, but typically
* all used. * they are not all used.
* *
* The AP initializes all entries in a filter table to refer to a "zero" * The AP initializes all entries in a filter table to refer to a "zero"
* entry. Once initialized the modem and AP update the entries for * entry. Once initialized the modem and AP update the entries for
...@@ -96,9 +106,6 @@ ...@@ -96,9 +106,6 @@
* ---------------------- * ----------------------
*/ */
/* IPA hardware constrains filter and route tables alignment */
#define IPA_TABLE_ALIGN 128 /* Minimum table alignment */
/* Assignment of route table entries to the modem and AP */ /* Assignment of route table entries to the modem and AP */
#define IPA_ROUTE_MODEM_MIN 0 #define IPA_ROUTE_MODEM_MIN 0
#define IPA_ROUTE_MODEM_COUNT 8 #define IPA_ROUTE_MODEM_COUNT 8
...@@ -125,8 +132,7 @@ static void ipa_table_validate_build(void) ...@@ -125,8 +132,7 @@ static void ipa_table_validate_build(void)
* code in ipa_table_init() uses a pointer to __le64 to * code in ipa_table_init() uses a pointer to __le64 to
* initialize tables. * initialize tables.
*/ */
BUILD_BUG_ON(sizeof(dma_addr_t) > IPA_TABLE_ENTRY_SIZE); BUILD_BUG_ON(sizeof(dma_addr_t) > sizeof(__le64));
BUILD_BUG_ON(sizeof(__le64) != IPA_TABLE_ENTRY_SIZE);
/* A "zero rule" is used to represent no filtering or no routing. /* A "zero rule" is used to represent no filtering or no routing.
* It is a 64-bit block of zeroed memory. Code in ipa_table_init() * It is a 64-bit block of zeroed memory. Code in ipa_table_init()
...@@ -157,7 +163,7 @@ ipa_table_valid_one(struct ipa *ipa, bool route, bool ipv6, bool hashed) ...@@ -157,7 +163,7 @@ ipa_table_valid_one(struct ipa *ipa, bool route, bool ipv6, bool hashed)
else else
mem = hashed ? &ipa->mem[IPA_MEM_V4_ROUTE_HASHED] mem = hashed ? &ipa->mem[IPA_MEM_V4_ROUTE_HASHED]
: &ipa->mem[IPA_MEM_V4_ROUTE]; : &ipa->mem[IPA_MEM_V4_ROUTE];
size = IPA_ROUTE_COUNT_MAX * IPA_TABLE_ENTRY_SIZE; size = IPA_ROUTE_COUNT_MAX * sizeof(__le64);
} else { } else {
if (ipv6) if (ipv6)
mem = hashed ? &ipa->mem[IPA_MEM_V6_FILTER_HASHED] mem = hashed ? &ipa->mem[IPA_MEM_V6_FILTER_HASHED]
...@@ -165,7 +171,7 @@ ipa_table_valid_one(struct ipa *ipa, bool route, bool ipv6, bool hashed) ...@@ -165,7 +171,7 @@ ipa_table_valid_one(struct ipa *ipa, bool route, bool ipv6, bool hashed)
else else
mem = hashed ? &ipa->mem[IPA_MEM_V4_FILTER_HASHED] mem = hashed ? &ipa->mem[IPA_MEM_V4_FILTER_HASHED]
: &ipa->mem[IPA_MEM_V4_FILTER]; : &ipa->mem[IPA_MEM_V4_FILTER];
size = (1 + IPA_FILTER_COUNT_MAX) * IPA_TABLE_ENTRY_SIZE; size = (1 + IPA_FILTER_COUNT_MAX) * sizeof(__le64);
} }
if (!ipa_cmd_table_valid(ipa, mem, route, ipv6, hashed)) if (!ipa_cmd_table_valid(ipa, mem, route, ipv6, hashed))
...@@ -264,8 +270,8 @@ static void ipa_table_reset_add(struct gsi_trans *trans, bool filter, ...@@ -264,8 +270,8 @@ static void ipa_table_reset_add(struct gsi_trans *trans, bool filter,
if (filter) if (filter)
first++; /* skip over bitmap */ first++; /* skip over bitmap */
offset = mem->offset + first * IPA_TABLE_ENTRY_SIZE; offset = mem->offset + first * sizeof(__le64);
size = count * IPA_TABLE_ENTRY_SIZE; size = count * sizeof(__le64);
addr = ipa_table_addr(ipa, false, count); addr = ipa_table_addr(ipa, false, count);
ipa_cmd_dma_shared_mem_add(trans, offset, size, addr, true); ipa_cmd_dma_shared_mem_add(trans, offset, size, addr, true);
...@@ -447,11 +453,11 @@ static void ipa_table_init_add(struct gsi_trans *trans, bool filter, ...@@ -447,11 +453,11 @@ static void ipa_table_init_add(struct gsi_trans *trans, bool filter,
count = hweight32(ipa->filter_map); count = hweight32(ipa->filter_map);
hash_count = hash_mem->size ? count : 0; hash_count = hash_mem->size ? count : 0;
} else { } else {
count = mem->size / IPA_TABLE_ENTRY_SIZE; count = mem->size / sizeof(__le64);
hash_count = hash_mem->size / IPA_TABLE_ENTRY_SIZE; hash_count = hash_mem->size / sizeof(__le64);
} }
size = count * IPA_TABLE_ENTRY_SIZE; size = count * sizeof(__le64);
hash_size = hash_count * IPA_TABLE_ENTRY_SIZE; hash_size = hash_count * sizeof(__le64);
addr = ipa_table_addr(ipa, filter, count); addr = ipa_table_addr(ipa, filter, count);
hash_addr = ipa_table_addr(ipa, filter, hash_count); hash_addr = ipa_table_addr(ipa, filter, hash_count);
...@@ -652,26 +658,17 @@ int ipa_table_init(struct ipa *ipa) ...@@ -652,26 +658,17 @@ int ipa_table_init(struct ipa *ipa)
ipa_table_validate_build(); ipa_table_validate_build();
size = IPA_ZERO_RULE_SIZE + (1 + count) * IPA_TABLE_ENTRY_SIZE; /* The IPA hardware requires route and filter table rules to be
* aligned on a 128-byte boundary. We put the "zero rule" at the
* base of the table area allocated here. The DMA address returned
* by dma_alloc_coherent() is guaranteed to be a power-of-2 number
* of pages, which satisfies the rule alignment requirement.
*/
size = IPA_ZERO_RULE_SIZE + (1 + count) * sizeof(__le64);
virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL); virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL);
if (!virt) if (!virt)
return -ENOMEM; return -ENOMEM;
/* We put the "zero rule" at the base of our table area. The IPA
* hardware requires route and filter table rules to be aligned
* on a 128-byte boundary. As long as the alignment constraint
* is a power of 2, we can check alignment using just the bottom
* 32 bits for a DMA address of any size.
*/
BUILD_BUG_ON(!is_power_of_2(IPA_TABLE_ALIGN));
if (lower_32_bits(addr) % IPA_TABLE_ALIGN) {
dev_err(dev, "table address %pad not %u-byte aligned\n",
&addr, IPA_TABLE_ALIGN);
dma_free_coherent(dev, size, virt, addr);
return -ERANGE;
}
ipa->table_virt = virt; ipa->table_virt = virt;
ipa->table_addr = addr; ipa->table_addr = addr;
...@@ -699,7 +696,7 @@ void ipa_table_exit(struct ipa *ipa) ...@@ -699,7 +696,7 @@ void ipa_table_exit(struct ipa *ipa)
struct device *dev = &ipa->pdev->dev; struct device *dev = &ipa->pdev->dev;
size_t size; size_t size;
size = IPA_ZERO_RULE_SIZE + (1 + count) * IPA_TABLE_ENTRY_SIZE; size = IPA_ZERO_RULE_SIZE + (1 + count) * sizeof(__le64);
dma_free_coherent(dev, size, ipa->table_virt, ipa->table_addr); dma_free_coherent(dev, size, ipa->table_virt, ipa->table_addr);
ipa->table_addr = 0; ipa->table_addr = 0;
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
struct ipa; struct ipa;
/* The size of a filter or route table entry */
#define IPA_TABLE_ENTRY_SIZE sizeof(__le64) /* Holds a physical address */
/* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */ /* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
#define IPA_FILTER_COUNT_MAX 14 #define IPA_FILTER_COUNT_MAX 14
...@@ -24,7 +21,7 @@ struct ipa; ...@@ -24,7 +21,7 @@ struct ipa;
/** /**
* ipa_table_valid() - Validate route and filter table memory regions * ipa_table_valid() - Validate route and filter table memory regions
* @ipa: IPA pointer * @ipa: IPA pointer
*
* Return: true if all regions are valid, false otherwise * Return: true if all regions are valid, false otherwise
*/ */
bool ipa_table_valid(struct ipa *ipa); bool ipa_table_valid(struct ipa *ipa);
...@@ -32,6 +29,7 @@ bool ipa_table_valid(struct ipa *ipa); ...@@ -32,6 +29,7 @@ bool ipa_table_valid(struct ipa *ipa);
/** /**
* ipa_filter_map_valid() - Validate a filter table endpoint bitmap * ipa_filter_map_valid() - Validate a filter table endpoint bitmap
* @ipa: IPA pointer * @ipa: IPA pointer
* @filter_mask: Filter table endpoint bitmap to check
* *
* Return: true if all regions are valid, false otherwise * Return: true if all regions are valid, false otherwise
*/ */
......
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