Lines Matching +full:ipa +full:- +full:shared

1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2018-2021 Linaro Ltd.
15 #include <linux/dma-mapping.h>
17 #include "ipa.h"
28 * DOC: IPA Filter and Route Tables
30 * The IPA has tables defined in its local (IPA-resident) memory that define
32 * endian 64-bit "slot" that holds the address of a rule definition. (The
38 * by all IPA hardware (IPA v4.2 doesn't support hashed tables).
41 * an object (such as a route or filter table) in IPA-resident memory must
42 * 128-byte aligned. An object in system memory (such as a route or filter
43 * rule) must be at an 8-byte aligned address. We currently only place
46 * A rule consists of a contiguous block of 32-bit values terminated with
52 * not all TX endpoints support filtering. The first 64-bit slot in a
54 * the table. The low-order bit (bit 0) in this bitmap represents a
59 * for endpoint 2, and so on. Space is set aside in IPA local memory to
66 * IPA filtering functionality.
68 * IPA Filter Table
69 * ----------------------
71 * |--------------------|
73 * |--------------------|
75 * |--------------------|
77 * |--------------------|
79 * |--------------------|
81 * ----------------------
87 * though the AP currently does not use the IPA routing functionality.
89 * IPA Route Table
90 * ----------------------
92 * |--------------------|
94 * |--------------------|
96 * |--------------------|
98 * |--------------------|
100 * |--------------------|
102 * |--------------------|
104 * |--------------------|
106 * ----------------------
115 (IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT)
117 /* Filter or route rules consist of a set of 32-bit values followed by a
118 * 32-bit all-zero rule list terminator. The "zero rule" is simply an
119 * all-zero rule followed by the list terminator.
136 * It is a 64-bit block of zeroed memory. Code in ipa_table_init() in ipa_table_validate_build()
151 ipa_table_valid_one(struct ipa *ipa, enum ipa_mem_id mem_id, bool route) in ipa_table_valid_one() argument
153 const struct ipa_mem *mem = ipa_mem_find(ipa, mem_id); in ipa_table_valid_one()
154 struct device *dev = &ipa->pdev->dev; in ipa_table_valid_one()
162 if (!ipa_cmd_table_valid(ipa, mem, route)) in ipa_table_valid_one()
165 /* mem->size >= size is sufficient, but we'll demand more */ in ipa_table_valid_one()
166 if (mem->size == size) in ipa_table_valid_one()
170 if (ipa_table_hash_support(ipa) && !mem->size) in ipa_table_valid_one()
174 route ? "route" : "filter", mem_id, mem->size, size); in ipa_table_valid_one()
180 bool ipa_table_valid(struct ipa *ipa) in ipa_table_valid() argument
184 valid = ipa_table_valid_one(ipa, IPA_MEM_V4_FILTER, false); in ipa_table_valid()
185 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_FILTER, false); in ipa_table_valid()
186 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V4_ROUTE, true); in ipa_table_valid()
187 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_ROUTE, true); in ipa_table_valid()
189 if (!ipa_table_hash_support(ipa)) in ipa_table_valid()
192 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V4_FILTER_HASHED, in ipa_table_valid()
194 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_FILTER_HASHED, in ipa_table_valid()
196 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V4_ROUTE_HASHED, in ipa_table_valid()
198 valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_ROUTE_HASHED, in ipa_table_valid()
204 bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_map) in ipa_filter_map_valid() argument
206 struct device *dev = &ipa->pdev->dev; in ipa_filter_map_valid()
227 static dma_addr_t ipa_table_addr(struct ipa *ipa, bool filter_mask, u16 count) in ipa_table_addr() argument
239 return ipa->table_addr + skip * sizeof(*ipa->table_virt); in ipa_table_addr()
245 struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi); in ipa_table_reset_add() local
246 const struct ipa_mem *mem = ipa_mem_find(ipa, mem_id); in ipa_table_reset_add()
252 if (!mem->size) in ipa_table_reset_add()
258 offset = mem->offset + first * sizeof(__le64); in ipa_table_reset_add()
260 addr = ipa_table_addr(ipa, false, count); in ipa_table_reset_add()
267 * for the IPv4 and IPv6 non-hashed and hashed filter tables.
270 ipa_filter_reset_table(struct ipa *ipa, enum ipa_mem_id mem_id, bool modem) in ipa_filter_reset_table() argument
272 u32 ep_mask = ipa->filter_map; in ipa_filter_reset_table()
277 trans = ipa_cmd_trans_alloc(ipa, count); in ipa_filter_reset_table()
279 dev_err(&ipa->pdev->dev, in ipa_filter_reset_table()
282 return -EBUSY; in ipa_filter_reset_table()
292 endpoint = &ipa->endpoint[endpoint_id]; in ipa_filter_reset_table()
293 if (endpoint->ee_id != ee_id) in ipa_filter_reset_table()
308 static int ipa_filter_reset(struct ipa *ipa, bool modem) in ipa_filter_reset() argument
312 ret = ipa_filter_reset_table(ipa, IPA_MEM_V4_FILTER, modem); in ipa_filter_reset()
316 ret = ipa_filter_reset_table(ipa, IPA_MEM_V4_FILTER_HASHED, modem); in ipa_filter_reset()
320 ret = ipa_filter_reset_table(ipa, IPA_MEM_V6_FILTER, modem); in ipa_filter_reset()
323 ret = ipa_filter_reset_table(ipa, IPA_MEM_V6_FILTER_HASHED, modem); in ipa_filter_reset()
330 * won't exceed the per-transaction command limit.
332 static int ipa_route_reset(struct ipa *ipa, bool modem) in ipa_route_reset() argument
338 trans = ipa_cmd_trans_alloc(ipa, 4); in ipa_route_reset()
340 dev_err(&ipa->pdev->dev, in ipa_route_reset()
343 return -EBUSY; in ipa_route_reset()
367 void ipa_table_reset(struct ipa *ipa, bool modem) in ipa_table_reset() argument
369 struct device *dev = &ipa->pdev->dev; in ipa_table_reset()
376 ret = ipa_filter_reset(ipa, modem); in ipa_table_reset()
381 ret = ipa_route_reset(ipa, modem); in ipa_table_reset()
387 int ipa_table_hash_flush(struct ipa *ipa) in ipa_table_hash_flush() argument
389 u32 offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version); in ipa_table_hash_flush()
393 if (!ipa_table_hash_support(ipa)) in ipa_table_hash_flush()
396 trans = ipa_cmd_trans_alloc(ipa, 1); in ipa_table_hash_flush()
398 dev_err(&ipa->pdev->dev, "no transaction for hash flush\n"); in ipa_table_hash_flush()
399 return -EBUSY; in ipa_table_hash_flush()
417 struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi); in ipa_table_init_add() local
418 const struct ipa_mem *hash_mem = ipa_mem_find(ipa, hash_mem_id); in ipa_table_init_add()
419 const struct ipa_mem *mem = ipa_mem_find(ipa, mem_id); in ipa_table_init_add()
428 * in the filter table. The hashed and non-hashed filter table in ipa_table_init_add()
434 count = 1 + hweight32(ipa->filter_map); in ipa_table_init_add()
435 hash_count = hash_mem->size ? count : 0; in ipa_table_init_add()
437 count = mem->size / sizeof(__le64); in ipa_table_init_add()
438 hash_count = hash_mem->size / sizeof(__le64); in ipa_table_init_add()
443 addr = ipa_table_addr(ipa, filter, count); in ipa_table_init_add()
444 hash_addr = ipa_table_addr(ipa, filter, hash_count); in ipa_table_init_add()
446 ipa_cmd_table_init_add(trans, opcode, size, mem->offset, addr, in ipa_table_init_add()
447 hash_size, hash_mem->offset, hash_addr); in ipa_table_init_add()
450 int ipa_table_setup(struct ipa *ipa) in ipa_table_setup() argument
454 trans = ipa_cmd_trans_alloc(ipa, 4); in ipa_table_setup()
456 dev_err(&ipa->pdev->dev, "no transaction for table setup\n"); in ipa_table_setup()
457 return -EBUSY; in ipa_table_setup()
478 * ipa_filter_tuple_zero() - Zero an endpoint's hashed filter tuple
486 u32 endpoint_id = endpoint->endpoint_id; in ipa_filter_tuple_zero()
492 val = ioread32(endpoint->ipa->reg_virt + offset); in ipa_filter_tuple_zero()
494 /* Zero all filter-related fields, preserving the rest */ in ipa_filter_tuple_zero()
497 iowrite32(val, endpoint->ipa->reg_virt + offset); in ipa_filter_tuple_zero()
501 static void ipa_filter_config(struct ipa *ipa, bool modem) in ipa_filter_config() argument
504 u32 ep_mask = ipa->filter_map; in ipa_filter_config()
506 if (!ipa_table_hash_support(ipa)) in ipa_filter_config()
515 endpoint = &ipa->endpoint[endpoint_id]; in ipa_filter_config()
516 if (endpoint->ee_id == ee_id) in ipa_filter_config()
524 route_id <= IPA_ROUTE_MODEM_MIN + IPA_ROUTE_MODEM_COUNT - 1; in ipa_route_id_modem()
528 * ipa_route_tuple_zero() - Zero a hashed route table entry tuple
529 * @ipa: IPA pointer
534 static void ipa_route_tuple_zero(struct ipa *ipa, u32 route_id) in ipa_route_tuple_zero() argument
539 val = ioread32(ipa->reg_virt + offset); in ipa_route_tuple_zero()
541 /* Zero all route-related fields, preserving the rest */ in ipa_route_tuple_zero()
544 iowrite32(val, ipa->reg_virt + offset); in ipa_route_tuple_zero()
548 static void ipa_route_config(struct ipa *ipa, bool modem) in ipa_route_config() argument
552 if (!ipa_table_hash_support(ipa)) in ipa_route_config()
557 ipa_route_tuple_zero(ipa, route_id); in ipa_route_config()
561 void ipa_table_config(struct ipa *ipa) in ipa_table_config() argument
563 ipa_filter_config(ipa, false); in ipa_table_config()
564 ipa_filter_config(ipa, true); in ipa_table_config()
565 ipa_route_config(ipa, false); in ipa_table_config()
566 ipa_route_config(ipa, true); in ipa_table_config()
571 * route table data. This is used when initializing or resetting the IPA
583 * routing there is also a 64-bit "zero rule" that means no routing, and
585 * to the zero rule. The zero rule is shared for route and filter tables.
587 * Note that the IPA hardware requires a filter or route rule address to be
593 * +-------------------+
594 * --> | zero rule |
595 * / |-------------------|
597 * |\ |-------------------|
598 * | ---- zero rule address | \
599 * |\ |-------------------| |
600 * | ---- zero rule address | | IPA_FILTER_COUNT_MAX
601 * | |-------------------| > or IPA_ROUTE_COUNT_MAX,
603 * \ |-------------------| |
604 * ---- zero rule address | /
605 * +-------------------+
607 int ipa_table_init(struct ipa *ipa) in ipa_table_init() argument
610 struct device *dev = &ipa->pdev->dev; in ipa_table_init()
618 /* The IPA hardware requires route and filter table rules to be in ipa_table_init()
619 * aligned on a 128-byte boundary. We put the "zero rule" at the in ipa_table_init()
621 * by dma_alloc_coherent() is guaranteed to be a power-of-2 number in ipa_table_init()
627 return -ENOMEM; in ipa_table_init()
629 ipa->table_virt = virt; in ipa_table_init()
630 ipa->table_addr = addr; in ipa_table_init()
640 *virt++ = cpu_to_le64((u64)ipa->filter_map << 1); in ipa_table_init()
644 while (count--) in ipa_table_init()
650 void ipa_table_exit(struct ipa *ipa) in ipa_table_exit() argument
653 struct device *dev = &ipa->pdev->dev; in ipa_table_exit()
658 dma_free_coherent(dev, size, ipa->table_virt, ipa->table_addr); in ipa_table_exit()
659 ipa->table_addr = 0; in ipa_table_exit()
660 ipa->table_virt = NULL; in ipa_table_exit()