summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ipa/Kconfig3
-rw-r--r--drivers/net/ipa/Makefile2
-rw-r--r--drivers/net/ipa/gsi.c13
-rw-r--r--drivers/net/ipa/gsi_private.h4
-rw-r--r--drivers/net/ipa/gsi_trans.c9
-rw-r--r--drivers/net/ipa/gsi_trans.h5
-rw-r--r--drivers/net/ipa/ipa.h7
-rw-r--r--drivers/net/ipa/ipa_cmd.c2
-rw-r--r--drivers/net/ipa/ipa_cmd.h19
-rw-r--r--drivers/net/ipa/ipa_data-v3.5.1.c (renamed from drivers/net/ipa/ipa_data-sdm845.c)39
-rw-r--r--drivers/net/ipa/ipa_data-v4.2.c (renamed from drivers/net/ipa/ipa_data-sc7180.c)25
-rw-r--r--drivers/net/ipa/ipa_data.h10
-rw-r--r--drivers/net/ipa/ipa_endpoint.h29
-rw-r--r--drivers/net/ipa/ipa_interrupt.h1
-rw-r--r--drivers/net/ipa/ipa_main.c8
-rw-r--r--drivers/net/ipa/ipa_mem.h2
-rw-r--r--drivers/net/ipa/ipa_qmi.c10
-rw-r--r--drivers/net/ipa/ipa_qmi.h14
-rw-r--r--drivers/net/ipa/ipa_reg.h21
-rw-r--r--drivers/net/ipa/ipa_smp2p.h2
-rw-r--r--drivers/net/ipa/ipa_table.c83
-rw-r--r--drivers/net/ipa/ipa_table.h6
22 files changed, 153 insertions, 161 deletions
diff --git a/drivers/net/ipa/Kconfig b/drivers/net/ipa/Kconfig
index 90a90262e0d0..8f99cfa14680 100644
--- a/drivers/net/ipa/Kconfig
+++ b/drivers/net/ipa/Kconfig
@@ -12,8 +12,7 @@ config QCOM_IPA
that is capable of generic hardware handling of IP packets,
including routing, filtering, and NAT. Currently the IPA
driver supports only basic transport of network traffic
- between the AP and modem, on the Qualcomm SDM845 and SC7180
- SoCs.
+ between the AP and modem.
Note that if selected, the selection type must match that
of QCOM_Q6V5_COMMON (Y or M).
diff --git a/drivers/net/ipa/Makefile b/drivers/net/ipa/Makefile
index 14a7d8429baa..6abd1db9fe33 100644
--- a/drivers/net/ipa/Makefile
+++ b/drivers/net/ipa/Makefile
@@ -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_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
diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 585574af36ec..1c835b3e1a43 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -1444,18 +1444,13 @@ static int gsi_ring_alloc(struct gsi *gsi, struct gsi_ring *ring, u32 count)
dma_addr_t addr;
/* 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 bottom 32 bits for a DMA address of any size.
+ * The DMA address returned by dma_alloc_coherent() is guaranteed to
+ * be a power-of-2 number of pages, which satisfies the requirement.
*/
ring->virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL);
- if (ring->virt && lower_32_bits(addr) % size) {
- 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) {
+ if (!ring->virt)
return -ENOMEM;
- }
+
ring->addr = addr;
ring->count = count;
diff --git a/drivers/net/ipa/gsi_private.h b/drivers/net/ipa/gsi_private.h
index 1785c9d3344d..ea333a244cf5 100644
--- a/drivers/net/ipa/gsi_private.h
+++ b/drivers/net/ipa/gsi_private.h
@@ -14,7 +14,7 @@ struct gsi_trans;
struct gsi_ring;
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 */
void *gsi_trans_pool_next(struct gsi_trans_pool *pool, void *element);
@@ -100,7 +100,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel);
/**
* gsi_ring_virt() - Return virtual address for a ring entry
* @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);
diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c
index 6c3ed5b17b80..70c2b585f98d 100644
--- a/drivers/net/ipa/gsi_trans.c
+++ b/drivers/net/ipa/gsi_trans.c
@@ -153,11 +153,10 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
size = __roundup_pow_of_two(size);
total_size = (count + max_alloc - 1) * size;
- /* The allocator will give us a power-of-2 number of pages. But we
- * can't guarantee that, so request it. That way we won't waste any
- * memory that would be available beyond the required space.
- *
- * Note that gsi_trans_pool_exit_dma() assumes the total allocated
+ /* The allocator will give us a power-of-2 number of pages
+ * sufficient to satisfy our request. Round up our requested
+ * size to avoid any unused space in the allocation. This way
+ * gsi_trans_pool_exit_dma() can assume the total allocated
* size is exactly (count * size).
*/
total_size = get_order(total_size) << PAGE_SHIFT;
diff --git a/drivers/net/ipa/gsi_trans.h b/drivers/net/ipa/gsi_trans.h
index 3a4ab8a94d82..17fd1822d8a9 100644
--- a/drivers/net/ipa/gsi_trans.h
+++ b/drivers/net/ipa/gsi_trans.h
@@ -71,7 +71,7 @@ struct gsi_trans {
/**
* 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
* @count: Minimum number of elements in the 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,
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
*/
void gsi_trans_pool_exit_dma(struct device *dev, struct gsi_trans_pool *pool);
diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index 802077631371..e7ff376cb5b7 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -44,6 +44,8 @@ enum ipa_flag {
* @version: IPA hardware version
* @pdev: Platform device
* @completion: Used to signal pipeline clear transfer complete
+ * @nb: Notifier block used for remoteproc SSR
+ * @notifier: Remoteproc SSR notifier
* @smp2p: SMP2P information
* @clock: IPA clocking information
* @table_addr: DMA address of filter/route table content
@@ -58,13 +60,12 @@ enum ipa_flag {
* @mem_size: Total size (bytes) of memory at @mem_virt
* @mem: Array of IPA-local memory region descriptors
* @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_size; Size of SMEM region
+ * @smem_size: Size of SMEM region
* @zero_addr: DMA address of preallocated zero-filled memory
* @zero_virt: Virtual address 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
* @filter_map: Bit mask indicating endpoints that support filtering
* @initialized: Bit mask indicating endpoints initialized
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 2ac6dd8413de..525cdf28d9ea 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -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.
*/
-#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)
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));
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index 6dd3d35cf315..b99262281f41 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -20,11 +20,18 @@ struct gsi_channel;
/**
* enum ipa_cmd_opcode: IPA immediate commands
*
- * All immediate commands are issued using the AP command TX endpoint.
- * The numeric values here are the opcodes for IPA v3.5.1 hardware.
+ * @IPA_CMD_IP_V4_FILTER_INIT: Initialize IPv4 filter table
+ * @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
- * a request is *not* an immediate command.
+ * All immediate commands are issued using the AP command TX endpoint.
*/
enum ipa_cmd_opcode {
IPA_CMD_NONE = 0x0,
@@ -96,7 +103,7 @@ static inline bool ipa_cmd_data_valid(struct ipa *ipa)
*
* 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()
@@ -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: IPA structure
+ * @trans: GSI transaction
* @offset: Offset of header memory in IPA local space
* @size: Size of header memory
* @addr: DMA address of buffer to be written from
diff --git a/drivers/net/ipa/ipa_data-sdm845.c b/drivers/net/ipa/ipa_data-v3.5.1.c
index e14e3fb1d970..57703e95a3f9 100644
--- a/drivers/net/ipa/ipa_data-sdm845.c
+++ b/drivers/net/ipa/ipa_data-v3.5.1.c
@@ -11,7 +11,7 @@
#include "ipa_endpoint.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 {
/* Source resource types; first must have value 0 */
IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS = 0,
@@ -25,7 +25,7 @@ enum ipa_resource_type {
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 {
/* Source resource group identifiers */
IPA_RSRC_GROUP_SRC_LWA_DL = 0,
@@ -41,7 +41,7 @@ enum ipa_rsrc_group_id {
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[] = {
[IPA_QSB_MASTER_DDR] = {
.max_writes = 8,
@@ -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[] = {
[IPA_ENDPOINT_AP_COMMAND_TX] = {
.ee_id = GSI_EE_AP,
@@ -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] = {
.ee_id = GSI_EE_MODEM,
.channel_id = 0,
@@ -159,12 +153,6 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
.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] = {
.ee_id = GSI_EE_MODEM,
.channel_id = 4,
@@ -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[] = {
[IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = {
.limits[IPA_RSRC_GROUP_SRC_LWA_DL] = {
@@ -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[] = {
[IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = {
.limits[IPA_RSRC_GROUP_DST_LWA_DL] = {
@@ -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 = {
.rsrc_group_src_count = IPA_RSRC_GROUP_SRC_COUNT,
.rsrc_group_dst_count = IPA_RSRC_GROUP_DST_COUNT,
@@ -280,7 +268,7 @@ static const struct ipa_resource_data ipa_resource_data = {
.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[] = {
[IPA_MEM_UC_SHARED] = {
.offset = 0x0000,
@@ -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 = {
.local_count = ARRAY_SIZE(ipa_mem_local_data),
.local = ipa_mem_local_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 = {
.core_clock_rate = 75 * 1000 * 1000, /* Hz */
.interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
.interconnect_data = ipa_interconnect_data,
};
-/* Configuration data for the SDM845 SoC. */
-const struct ipa_data ipa_data_sdm845 = {
+/* Configuration data for an SoC having IPA v3.5.1 */
+const struct ipa_data ipa_data_v3_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_data = ipa_qsb_data,
.endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
diff --git a/drivers/net/ipa/ipa_data-sc7180.c b/drivers/net/ipa/ipa_data-v4.2.c
index c9b6a6aaadac..8744f19c6401 100644
--- a/drivers/net/ipa/ipa_data-sc7180.c
+++ b/drivers/net/ipa/ipa_data-v4.2.c
@@ -9,7 +9,7 @@
#include "ipa_endpoint.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 {
/* Source resource types; first must have value 0 */
IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS = 0,
@@ -23,7 +23,7 @@ enum ipa_resource_type {
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 {
/* Source resource group identifiers */
IPA_RSRC_GROUP_SRC_UL_DL = 0,
@@ -34,7 +34,7 @@ enum ipa_rsrc_group_id {
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[] = {
[IPA_QSB_MASTER_DDR] = {
.max_writes = 8,
@@ -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[] = {
[IPA_ENDPOINT_AP_COMMAND_TX] = {
.ee_id = GSI_EE_AP,
@@ -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[] = {
[IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = {
.limits[IPA_RSRC_GROUP_SRC_UL_DL] = {
@@ -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[] = {
[IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = {
.limits[IPA_RSRC_GROUP_DST_UL_DL_DPL] = {
@@ -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 = {
.rsrc_group_src_count = IPA_RSRC_GROUP_SRC_COUNT,
.rsrc_group_dst_count = IPA_RSRC_GROUP_DST_COUNT,
@@ -217,7 +217,7 @@ static const struct ipa_resource_data ipa_resource_data = {
.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[] = {
[IPA_MEM_UC_SHARED] = {
.offset = 0x0000,
@@ -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 = {
.local_count = ARRAY_SIZE(ipa_mem_local_data),
.local = ipa_mem_local_data,
@@ -320,7 +321,7 @@ static const struct ipa_mem_data ipa_mem_data = {
.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[] = {
{
.name = "memory",
@@ -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 = {
.core_clock_rate = 100 * 1000 * 1000, /* Hz */
.interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
.interconnect_data = ipa_interconnect_data,
};
-/* Configuration data for the SC7180 SoC. */
-const struct ipa_data ipa_data_sc7180 = {
+/* Configuration data for an SoC having IPA v4.2 */
+const struct ipa_data ipa_data_v4_2 = {
.version = IPA_VERSION_4_2,
+ /* backward_compat value is 0 */
.qsb_count = ARRAY_SIZE(ipa_qsb_data),
.qsb_data = ipa_qsb_data,
.endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
diff --git a/drivers/net/ipa/ipa_data.h b/drivers/net/ipa/ipa_data.h
index ea8f99286228..769f68923527 100644
--- a/drivers/net/ipa/ipa_data.h
+++ b/drivers/net/ipa/ipa_data.h
@@ -90,8 +90,8 @@ struct ipa_qsb_data {
* that can be included in a single transaction.
*/
struct gsi_channel_data {
- u16 tre_count;
- u16 event_count;
+ u16 tre_count; /* must be a power of 2 */
+ u16 event_count; /* must be a power of 2 */
u8 tlv_count;
};
@@ -279,6 +279,7 @@ struct ipa_clock_data {
/**
* struct ipa_data - combined IPA/GSI configuration data
* @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_data: Qualcomm System Bus configuration data
* @endpoint_count: number of entries in the endpoint_data array
@@ -289,6 +290,7 @@ struct ipa_clock_data {
*/
struct ipa_data {
enum ipa_version version;
+ u32 backward_compat;
u32 qsb_count; /* number of entries in qsb_data[] */
const struct ipa_qsb_data *qsb_data;
u32 endpoint_count; /* number of entries in endpoint_data[] */
@@ -298,7 +300,7 @@ struct ipa_data {
const struct ipa_clock_data *clock_data;
};
-extern const struct ipa_data ipa_data_sdm845;
-extern const struct ipa_data ipa_data_sc7180;
+extern const struct ipa_data ipa_data_v3_5_1;
+extern const struct ipa_data ipa_data_v4_2;
#endif /* _IPA_DATA_H_ */
diff --git a/drivers/net/ipa/ipa_endpoint.h b/drivers/net/ipa/ipa_endpoint.h
index c6c55ea35394..f034a9e6ef21 100644
--- a/drivers/net/ipa/ipa_endpoint.h
+++ b/drivers/net/ipa/ipa_endpoint.h
@@ -25,15 +25,16 @@ struct ipa_gsi_endpoint_data;
#define IPA_MTU ETH_DATA_LEN
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_MODEM_AP_TX,
IPA_ENDPOINT_AP_LAN_RX,
+ IPA_ENDPOINT_AP_MODEM_TX,
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_AP_TX,
+ IPA_ENDPOINT_MODEM_AP_RX,
+ IPA_ENDPOINT_MODEM_DL_NLO_TX,
IPA_ENDPOINT_COUNT, /* Number of names (not an index) */
};
@@ -41,8 +42,20 @@ enum ipa_endpoint_name {
/**
* struct ipa_endpoint - IPA endpoint information
- * @channel_id: EP's GSI channel
- * @evt_ring_id: EP's GSI channel event ring
+ * @ipa: IPA pointer
+ * @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 *ipa;
@@ -52,7 +65,7 @@ struct ipa_endpoint {
bool toward_ipa;
const struct ipa_endpoint_config_data *data;
- u32 trans_tre_max; /* maximum descriptors per transaction */
+ u32 trans_tre_max;
u32 evt_ring_id;
/* Net device this endpoint is associated with, if any */
diff --git a/drivers/net/ipa/ipa_interrupt.h b/drivers/net/ipa/ipa_interrupt.h
index b5d63a0cd19e..d5c486a6800d 100644
--- a/drivers/net/ipa/ipa_interrupt.h
+++ b/drivers/net/ipa/ipa_interrupt.h
@@ -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
+ * @interrupt: IPA interrupt structure
* @irq_id: IPA interrupt type
* @handler: Handler function for the interrupt
*
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index e18029152d78..a970d10e650e 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -397,9 +397,9 @@ static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data)
u32 granularity;
u32 val;
- /* IPA v4.5 has no backward compatibility register */
+ /* IPA v4.5+ has no backward compatibility register */
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);
}
@@ -578,11 +578,11 @@ out_release_firmware:
static const struct of_device_id ipa_match[] = {
{
.compatible = "qcom,sdm845-ipa",
- .data = &ipa_data_sdm845,
+ .data = &ipa_data_v3_5_1,
},
{
.compatible = "qcom,sc7180-ipa",
- .data = &ipa_data_sc7180,
+ .data = &ipa_data_v4_2,
},
{ },
};
diff --git a/drivers/net/ipa/ipa_mem.h b/drivers/net/ipa/ipa_mem.h
index f82e8939622b..df61ef48df36 100644
--- a/drivers/net/ipa/ipa_mem.h
+++ b/drivers/net/ipa/ipa_mem.h
@@ -77,7 +77,7 @@ enum ipa_mem_id {
* struct ipa_mem - IPA local memory region description
* @offset: offset in IPA memory space to 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 {
u32 offset;
diff --git a/drivers/net/ipa/ipa_qmi.c b/drivers/net/ipa/ipa_qmi.c
index ccdb4a6a4c75..593665efbcf9 100644
--- a/drivers/net/ipa/ipa_qmi.c
+++ b/drivers/net/ipa/ipa_qmi.c
@@ -308,12 +308,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
mem = &ipa->mem[IPA_MEM_V4_ROUTE];
req.v4_route_tbl_info_valid = 1;
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];
req.v6_route_tbl_info_valid = 1;
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];
req.v4_filter_tbl_start_valid = 1;
@@ -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.start =
ipa->mem_offset + mem->offset;
- req.v4_hash_route_tbl_info.count =
- mem->size / IPA_TABLE_ENTRY_SIZE;
+ req.v4_hash_route_tbl_info.count = mem->size / sizeof(__le64);
}
mem = &ipa->mem[IPA_MEM_V6_ROUTE_HASHED];
@@ -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.start =
ipa->mem_offset + mem->offset;
- req.v6_hash_route_tbl_info.count =
- mem->size / IPA_TABLE_ENTRY_SIZE;
+ req.v6_hash_route_tbl_info.count = mem->size / sizeof(__le64);
}
mem = &ipa->mem[IPA_MEM_V4_FILTER_HASHED];
diff --git a/drivers/net/ipa/ipa_qmi.h b/drivers/net/ipa/ipa_qmi.h
index 3993687593d0..b6f2055d35a6 100644
--- a/drivers/net/ipa/ipa_qmi.h
+++ b/drivers/net/ipa/ipa_qmi.h
@@ -13,11 +13,15 @@ struct ipa;
/**
* struct ipa_qmi - QMI state associated with an IPA
- * @client_handle - used to send an QMI requests to the modem
- * @server_handle - used to handle QMI requests from the modem
- * @initialized - whether QMI initialization has completed
- * @indication_register_received - tracks modem request receipt
- * @init_driver_response_received - tracks modem response receipt
+ * @client_handle: Used to send an QMI requests to the modem
+ * @server_handle: Used to handle QMI requests from the modem
+ * @modem_sq: QMAP socket address for the modem QMI server
+ * @init_driver_work: Work structure used for INIT_DRIVER message handling
+ * @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 qmi_handle client_handle;
diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h
index de2a944bad86..286ea9634c49 100644
--- a/drivers/net/ipa/ipa_reg.h
+++ b/drivers/net/ipa/ipa_reg.h
@@ -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_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) */
#define IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET 0x000001e8
diff --git a/drivers/net/ipa/ipa_smp2p.h b/drivers/net/ipa/ipa_smp2p.h
index bf0e4063cfd9..20319438a841 100644
--- a/drivers/net/ipa/ipa_smp2p.h
+++ b/drivers/net/ipa/ipa_smp2p.h
@@ -28,7 +28,7 @@ void ipa_smp2p_exit(struct ipa *ipa);
/**
* 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.
* This is used before initiating shutdown of the driver.
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 4236a50ff03a..401b568df6a3 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -27,28 +27,38 @@
/**
* DOC: IPA Filter and Route Tables
*
- * The IPA has tables defined in its local shared memory that define filter
- * and routing rules. Each entry in these tables contains a 64-bit DMA
- * address that refers to DRAM (system memory) containing a rule definition.
+ * The IPA has tables defined in its local (IPA-resident) memory that define
+ * filter and routing rules. An entry in either of these tables is a little
+ * 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
* 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
- * filter or route table rules. Separate tables (both filter and route)
- * 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.
+ * filter or route table rules.
*
* 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
* the table. The low-order bit (bit 0) in this bitmap represents a
* 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
- * entry (i.e. a DMA address referring to a rule) for endpoint 0 in the
- * table. Bit 2, if set, indicates there is an entry for endpoint 1,
- * and so on. Space is set aside in IPA local memory to hold as many
- * filter table entries as might be required, but typically they are not
- * all used.
+ * entry (i.e. slot containing a system address referring to a rule) for
+ * endpoint 0 in the table. Bit 3, if set, indicates there is an entry
+ * for endpoint 2, and so on. Space is set aside in IPA local memory to
+ * hold as many filter table entries as might be required, but typically
+ * they are not all used.
*
* 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
@@ -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 */
#define IPA_ROUTE_MODEM_MIN 0
#define IPA_ROUTE_MODEM_COUNT 8
@@ -125,8 +132,7 @@ static void ipa_table_validate_build(void)
* code in ipa_table_init() uses a pointer to __le64 to
* initialize tables.
*/
- BUILD_BUG_ON(sizeof(dma_addr_t) > IPA_TABLE_ENTRY_SIZE);
- BUILD_BUG_ON(sizeof(__le64) != IPA_TABLE_ENTRY_SIZE);
+ BUILD_BUG_ON(sizeof(dma_addr_t) > sizeof(__le64));
/* 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()
@@ -157,7 +163,7 @@ ipa_table_valid_one(struct ipa *ipa, bool route, bool ipv6, bool hashed)
else
mem = hashed ? &ipa->mem[IPA_MEM_V4_ROUTE_HASHED]
: &ipa->mem[IPA_MEM_V4_ROUTE];
- size = IPA_ROUTE_COUNT_MAX * IPA_TABLE_ENTRY_SIZE;
+ size = IPA_ROUTE_COUNT_MAX * sizeof(__le64);
} else {
if (ipv6)
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)
else
mem = hashed ? &ipa->mem[IPA_MEM_V4_FILTER_HASHED]
: &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))
@@ -264,8 +270,8 @@ static void ipa_table_reset_add(struct gsi_trans *trans, bool filter,
if (filter)
first++; /* skip over bitmap */
- offset = mem->offset + first * IPA_TABLE_ENTRY_SIZE;
- size = count * IPA_TABLE_ENTRY_SIZE;
+ offset = mem->offset + first * sizeof(__le64);
+ size = count * sizeof(__le64);
addr = ipa_table_addr(ipa, false, count);
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,
count = hweight32(ipa->filter_map);
hash_count = hash_mem->size ? count : 0;
} else {
- count = mem->size / IPA_TABLE_ENTRY_SIZE;
- hash_count = hash_mem->size / IPA_TABLE_ENTRY_SIZE;
+ count = mem->size / sizeof(__le64);
+ hash_count = hash_mem->size / sizeof(__le64);
}
- size = count * IPA_TABLE_ENTRY_SIZE;
- hash_size = hash_count * IPA_TABLE_ENTRY_SIZE;
+ size = count * sizeof(__le64);
+ hash_size = hash_count * sizeof(__le64);
addr = ipa_table_addr(ipa, filter, count);
hash_addr = ipa_table_addr(ipa, filter, hash_count);
@@ -652,26 +658,17 @@ int ipa_table_init(struct ipa *ipa)
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);
if (!virt)
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_addr = addr;
@@ -699,7 +696,7 @@ void ipa_table_exit(struct ipa *ipa)
struct device *dev = &ipa->pdev->dev;
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);
ipa->table_addr = 0;
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 889c2e93b122..018045b95aad 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -10,9 +10,6 @@
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) */
#define IPA_FILTER_COUNT_MAX 14
@@ -24,7 +21,7 @@ struct ipa;
/**
* ipa_table_valid() - Validate route and filter table memory regions
* @ipa: IPA pointer
-
+ *
* Return: true if all regions are valid, false otherwise
*/
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: IPA pointer
+ * @filter_mask: Filter table endpoint bitmap to check
*
* Return: true if all regions are valid, false otherwise
*/