// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2018-2024 Linaro Ltd. */ #include <linux/bitops.h> #include <linux/build_bug.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/io.h> #include <linux/types.h> #include "gsi.h" #include "gsi_trans.h" #include "ipa.h" #include "ipa_cmd.h" #include "ipa_endpoint.h" #include "ipa_mem.h" #include "ipa_reg.h" #include "ipa_table.h" #include "ipa_version.h" /** * DOC: IPA Filter and Route Tables * * 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) are used for IPv4 and IPv6. There * is 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. * * Each filter rule is associated with an AP or modem TX endpoint, though * 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. Each set bit in this bitmap indicates the presence of the * address of a filter rule in the memory following the bitmap. Until IPA * v5.0, the low-order bit (bit 0) in this bitmap represents a special * global filter, which applies to all traffic. Otherwise the position of * each set bit represents an endpoint for which a filter rule is defined. * * The global rule is not used in current code, and support for it is * removed starting at IPA v5.0. For IPA v5.0+, the endpoint bitmap * position defines the endpoint ID--i.e. if bit 1 is set in the endpoint * bitmap, endpoint 1 has a filter rule. Older versions of IPA represent * the presence of a filter rule for endpoint X by bit (X + 1) being set. * I.e., bit 1 set indicates the presence of a filter rule for endpoint 0, * and bit 3 set means there is a filter rule present for endpoint 2. * * Each filter table entry has the address of a set of equations that * implement a filter rule. So following the endpoint bitmap there * will be such an address/entry for each endpoint with a set bit in * the bitmap. * * The AP initializes all entries in a filter table to refer to a "zero" * rule. Once initialized, the modem and AP update the entries for * endpoints they "own" directly. Currently the AP does not use the IPA * filtering functionality. * * This diagram shows an example of a filter table with an endpoint * bitmap as defined prior to IPA v5.0. * * IPA Filter Table * ---------------------- * endpoint bitmap | 0x0000000000000048 | Bits 3 and 6 set (endpoints 2 and 5) * |--------------------| * 1st endpoint | 0x000123456789abc0 | DMA address for modem endpoint 2 rule * |--------------------| * 2nd endpoint | 0x000123456789abf0 | DMA address for AP endpoint 5 rule * |--------------------| * (unused) | | (Unused space in filter table) * |--------------------| * . . . * |--------------------| * (unused) | | (Unused space in filter table) * ---------------------- * * The set of available route rules is divided about equally between the AP * and modem. The AP initializes all entries in a route table to refer to * a "zero entry". Once initialized, the modem and AP are responsible for * updating their own entries. All entries in a route table are usable, * though the AP currently does not use the IPA routing functionality. * * IPA Route Table * ---------------------- * 1st modem route | 0x0001234500001100 | DMA address for first route rule * |--------------------| * 2nd modem route | 0x0001234500001140 | DMA address for second route rule * |--------------------| * . . . * |--------------------| * Last modem route| 0x0001234500002280 | DMA address for Nth route rule * |--------------------| * 1st AP route | 0x0001234500001100 | DMA address for route rule (N+1) * |--------------------| * 2nd AP route | 0x0001234500001140 | DMA address for next route rule * |--------------------| * . . . * |--------------------| * Last AP route | 0x0001234500002280 | DMA address for last route rule * ---------------------- */ /* Filter or route rules consist of a set of 32-bit values followed by a * 32-bit all-zero rule list terminator. The "zero rule" is simply an * all-zero rule followed by the list terminator. */ #define IPA_ZERO_RULE_SIZE … /* Check things that can be validated at build time. */ static void ipa_table_validate_build(void) { … } static const struct ipa_mem * ipa_table_mem(struct ipa *ipa, bool filter, bool hashed, bool ipv6) { … } /* Return true if hashed tables are supported */ bool ipa_table_hash_support(struct ipa *ipa) { … } bool ipa_filtered_valid(struct ipa *ipa, u64 filtered) { … } /* Zero entry count means no table, so just return a 0 address */ static dma_addr_t ipa_table_addr(struct ipa *ipa, bool filter_mask, u16 count) { … } static void ipa_table_reset_add(struct gsi_trans *trans, bool filter, bool hashed, bool ipv6, u16 first, u16 count) { … } /* Reset entries in a single filter table belonging to either the AP or * modem to refer to the zero entry. The memory region supplied will be * for the IPv4 and IPv6 non-hashed and hashed filter tables. */ static int ipa_filter_reset_table(struct ipa *ipa, bool hashed, bool ipv6, bool modem) { … } /* Theoretically, each filter table could have more filter slots to * update than the maximum number of commands in a transaction. So * we do each table separately. */ static int ipa_filter_reset(struct ipa *ipa, bool modem) { … } /* The AP routes and modem routes are each contiguous within the * table. We can update each table with a single command, and we * won't exceed the per-transaction command limit. * */ static int ipa_route_reset(struct ipa *ipa, bool modem) { … } void ipa_table_reset(struct ipa *ipa, bool modem) { … } int ipa_table_hash_flush(struct ipa *ipa) { … } static void ipa_table_init_add(struct gsi_trans *trans, bool filter, bool ipv6) { … } int ipa_table_setup(struct ipa *ipa) { … } /** * ipa_filter_tuple_zero() - Zero an endpoint's hashed filter tuple * @endpoint: Endpoint whose filter hash tuple should be zeroed * * Endpoint must be for the AP (not modem) and support filtering. Updates * the filter hash values without changing route ones. */ static void ipa_filter_tuple_zero(struct ipa_endpoint *endpoint) { … } /* Configure a hashed filter table; there is no ipa_filter_deconfig() */ static void ipa_filter_config(struct ipa *ipa, bool modem) { … } static bool ipa_route_id_modem(struct ipa *ipa, u32 route_id) { … } /** * ipa_route_tuple_zero() - Zero a hashed route table entry tuple * @ipa: IPA pointer * @route_id: Route table entry whose hash tuple should be zeroed * * Updates the route hash values without changing filter ones. */ static void ipa_route_tuple_zero(struct ipa *ipa, u32 route_id) { … } /* Configure a hashed route table; there is no ipa_route_deconfig() */ static void ipa_route_config(struct ipa *ipa, bool modem) { … } /* Configure a filter and route tables; there is no ipa_table_deconfig() */ void ipa_table_config(struct ipa *ipa) { … } /* Verify the sizes of all IPA table filter or routing table memory regions * are valid. If valid, this records the size of the routing table. */ bool ipa_table_mem_valid(struct ipa *ipa, bool filter) { … } /* Initialize a coherent DMA allocation containing initialized filter and * route table data. This is used when initializing or resetting the IPA * filter or route table. * * The first entry in a filter table contains a bitmap indicating which * endpoints contain entries in the table. In addition to that first entry, * there is a fixed maximum number of entries that follow. Filter table * entries are 64 bits wide, and (other than the bitmap) contain the DMA * address of a filter rule. A "zero rule" indicates no filtering, and * consists of 64 bits of zeroes. When a filter table is initialized (or * reset) its entries are made to refer to the zero rule. * * Each entry in a route table is the DMA address of a routing rule. For * routing there is also a 64-bit "zero rule" that means no routing, and * when a route table is initialized or reset, its entries are made to refer * to the zero rule. The zero rule is shared for route and filter tables. * * +-------------------+ * --> | zero rule | * / |-------------------| * | | filter mask | * |\ |-------------------| * | ---- zero rule address | \ * |\ |-------------------| | * | ---- zero rule address | | Max IPA filter count * | |-------------------| > or IPA route count, * | ... | whichever is greater * \ |-------------------| | * ---- zero rule address | / * +-------------------+ */ int ipa_table_init(struct ipa *ipa) { … } void ipa_table_exit(struct ipa *ipa) { … }