Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ipa: support more filtering endpoints

Prior to IPA v5.0, there could be no more than 32 endpoints.

A filter table begins with a bitmap indicating which endpoints have
a filter defined. That bitmap is currently assumed to fit in a
32-bit value.

Starting with IPA v5.0, more than 32 endpoints are supported, so
it's conceivable that a TX endpoint has an ID that exceeds 32.
Increase the size of the field representing endpoints that support
filtering to 64 bits. Rename the bitmap field "filtered".

Unlike other similar fields, we do not use an (arbitrarily long)
Linux bitmap for this purpose. The reason is that if a filter table
ever *did* need to support more than 64 TX endpoints, its format
would change in ways we can't anticipate.

Have ipa_endpoint_init() return a negative errno rather than a mask
that indicates which endpoints support filtering, and have that
function assign the "filtered" field directly.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Alex Elder and committed by
David S. Miller
0f97fbd4 88de7672

+32 -32
+2 -2
drivers/net/ipa/ipa.h
··· 65 65 * @available_count: Number of defined bits in the available bitmap 66 66 * @defined: Bitmap of endpoints defined in config data 67 67 * @available: Bitmap of endpoints supported by hardware 68 - * @filter_map: Bit mask indicating endpoints that support filtering 68 + * @filtered: Bitmap of endpoints that support filtering 69 69 * @set_up: Bit mask indicating endpoints set up 70 70 * @enabled: Bit mask indicating endpoints enabled 71 71 * @modem_tx_count: Number of defined modem TX endoints ··· 123 123 u32 available_count; 124 124 unsigned long *defined; /* Defined in configuration data */ 125 125 unsigned long *available; /* Supported by hardware */ 126 - u32 filter_map; 126 + u64 filtered; /* Support filtering (AP and modem) */ 127 127 u32 set_up; 128 128 u32 enabled; 129 129
+13 -9
drivers/net/ipa/ipa_endpoint.c
··· 1973 1973 { 1974 1974 u32 endpoint_id; 1975 1975 1976 + ipa->filtered = 0; 1977 + 1976 1978 for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count) 1977 1979 ipa_endpoint_exit_one(&ipa->endpoint[endpoint_id]); 1978 1980 ··· 1986 1984 } 1987 1985 1988 1986 /* Returns a bitmask of endpoints that support filtering, or 0 on error */ 1989 - u32 ipa_endpoint_init(struct ipa *ipa, u32 count, 1987 + int ipa_endpoint_init(struct ipa *ipa, u32 count, 1990 1988 const struct ipa_gsi_endpoint_data *data) 1991 1989 { 1992 1990 enum ipa_endpoint_name name; 1993 - u32 filter_map; 1991 + u32 filtered; 1994 1992 1995 1993 BUILD_BUG_ON(!IPA_REPLENISH_BATCH); 1996 1994 1997 1995 /* Number of endpoints is one more than the maximum ID */ 1998 1996 ipa->endpoint_count = ipa_endpoint_max(ipa, count, data) + 1; 1999 1997 if (!ipa->endpoint_count) 2000 - return 0; /* Error */ 1998 + return -EINVAL; 2001 1999 2002 2000 /* Initialize the defined endpoint bitmap */ 2003 2001 ipa->defined = bitmap_zalloc(ipa->endpoint_count, GFP_KERNEL); 2004 2002 if (!ipa->defined) 2005 - return 0; /* Error */ 2003 + return -ENOMEM; 2006 2004 2007 - filter_map = 0; 2005 + filtered = 0; 2008 2006 for (name = 0; name < count; name++, data++) { 2009 2007 if (ipa_gsi_endpoint_data_empty(data)) 2010 2008 continue; /* Skip over empty slots */ ··· 2012 2010 ipa_endpoint_init_one(ipa, name, data); 2013 2011 2014 2012 if (data->endpoint.filter_support) 2015 - filter_map |= BIT(data->endpoint_id); 2013 + filtered |= BIT(data->endpoint_id); 2016 2014 if (data->ee_id == GSI_EE_MODEM && data->toward_ipa) 2017 2015 ipa->modem_tx_count++; 2018 2016 } 2019 2017 2020 - if (!ipa_filter_map_valid(ipa, filter_map)) 2018 + if (!ipa_filtered_valid(ipa, filtered)) 2021 2019 goto err_endpoint_exit; 2022 2020 2023 - return filter_map; /* Non-zero bitmask */ 2021 + ipa->filtered = filtered; 2022 + 2023 + return 0; 2024 2024 2025 2025 err_endpoint_exit: 2026 2026 ipa_endpoint_exit(ipa); 2027 2027 2028 - return 0; /* Error */ 2028 + return -EINVAL; 2029 2029 }
+1 -1
drivers/net/ipa/ipa_endpoint.h
··· 195 195 void ipa_endpoint_default_route_set(struct ipa *ipa, u32 endpoint_id); 196 196 void ipa_endpoint_default_route_clear(struct ipa *ipa); 197 197 198 - u32 ipa_endpoint_init(struct ipa *ipa, u32 count, 198 + int ipa_endpoint_init(struct ipa *ipa, u32 count, 199 199 const struct ipa_gsi_endpoint_data *data); 200 200 void ipa_endpoint_exit(struct ipa *ipa); 201 201
+2 -5
drivers/net/ipa/ipa_main.c
··· 788 788 goto err_mem_exit; 789 789 790 790 /* Result is a non-zero mask of endpoints that support filtering */ 791 - ipa->filter_map = ipa_endpoint_init(ipa, data->endpoint_count, 792 - data->endpoint_data); 793 - if (!ipa->filter_map) { 794 - ret = -EINVAL; 791 + ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data); 792 + if (ret) 795 793 goto err_gsi_exit; 796 - } 797 794 798 795 ret = ipa_table_init(ipa); 799 796 if (ret)
+11 -12
drivers/net/ipa/ipa_table.c
··· 161 161 return ipa_mem_find(ipa, mem_id); 162 162 } 163 163 164 - bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_map) 164 + bool ipa_filtered_valid(struct ipa *ipa, u64 filtered) 165 165 { 166 166 struct device *dev = &ipa->pdev->dev; 167 167 u32 count; 168 168 169 - if (!filter_map) { 169 + if (!filtered) { 170 170 dev_err(dev, "at least one filtering endpoint is required\n"); 171 171 172 172 return false; 173 173 } 174 174 175 - count = hweight32(filter_map); 175 + count = hweight64(filtered); 176 176 if (count > ipa->filter_count) { 177 - dev_err(dev, "too many filtering endpoints (%u, max %u)\n", 177 + dev_err(dev, "too many filtering endpoints (%u > %u)\n", 178 178 count, ipa->filter_count); 179 179 180 180 return false; ··· 230 230 static int 231 231 ipa_filter_reset_table(struct ipa *ipa, bool hashed, bool ipv6, bool modem) 232 232 { 233 - u32 ep_mask = ipa->filter_map; 234 - u32 count = hweight32(ep_mask); 233 + u64 ep_mask = ipa->filtered; 235 234 struct gsi_trans *trans; 236 235 enum gsi_ee_id ee_id; 237 236 238 - trans = ipa_cmd_trans_alloc(ipa, count); 237 + trans = ipa_cmd_trans_alloc(ipa, hweight64(ep_mask)); 239 238 if (!trans) { 240 239 dev_err(&ipa->pdev->dev, 241 240 "no transaction for %s filter reset\n", ··· 404 405 * to hold the bitmap itself. The size of the hashed filter 405 406 * table is either the same as the non-hashed one, or zero. 406 407 */ 407 - count = 1 + hweight32(ipa->filter_map); 408 + count = 1 + hweight64(ipa->filtered); 408 409 hash_count = hash_mem && hash_mem->size ? count : 0; 409 410 } else { 410 411 /* The size of a route table region determines the number ··· 502 503 static void ipa_filter_config(struct ipa *ipa, bool modem) 503 504 { 504 505 enum gsi_ee_id ee_id = modem ? GSI_EE_MODEM : GSI_EE_AP; 505 - u32 ep_mask = ipa->filter_map; 506 + u64 ep_mask = ipa->filtered; 506 507 507 508 if (!ipa_table_hash_support(ipa)) 508 509 return; ··· 614 615 /* Filter tables must able to hold the endpoint bitmap plus 615 616 * an entry for each endpoint that supports filtering 616 617 */ 617 - if (count < 1 + hweight32(ipa->filter_map)) 618 + if (count < 1 + hweight64(ipa->filtered)) 618 619 return false; 619 620 } else { 620 621 /* Routing tables must be able to hold all modem entries, ··· 719 720 * that option, so there's no shifting required. 720 721 */ 721 722 if (ipa->version < IPA_VERSION_5_0) 722 - *virt++ = cpu_to_le64((u64)ipa->filter_map << 1); 723 + *virt++ = cpu_to_le64(ipa->filtered << 1); 723 724 else 724 - *virt++ = cpu_to_le64((u64)ipa->filter_map); 725 + *virt++ = cpu_to_le64(ipa->filtered); 725 726 726 727 /* All the rest contain the DMA address of the zero rule */ 727 728 le_addr = cpu_to_le64(addr);
+3 -3
drivers/net/ipa/ipa_table.h
··· 11 11 struct ipa; 12 12 13 13 /** 14 - * ipa_filter_map_valid() - Validate a filter table endpoint bitmap 14 + * ipa_filtered_valid() - Validate a filter table endpoint bitmap 15 15 * @ipa: IPA pointer 16 - * @filter_mask: Filter table endpoint bitmap to check 16 + * @filtered: Filter table endpoint bitmap to check 17 17 * 18 18 * Return: true if all regions are valid, false otherwise 19 19 */ 20 - bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_mask); 20 + bool ipa_filtered_valid(struct ipa *ipa, u64 filtered); 21 21 22 22 /** 23 23 * ipa_table_hash_support() - Return true if hashed tables are supported