[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221102221139.1091510-9-elder@linaro.org>
Date: Wed, 2 Nov 2022 17:11:38 -0500
From: Alex Elder <elder@...aro.org>
To: davem@...emloft.net, edumazet@...gle.com, kuba@...nel.org,
pabeni@...hat.com
Cc: mka@...omium.org, evgreen@...omium.org, andersson@...nel.org,
quic_cpratapa@...cinc.com, quic_avuyyuru@...cinc.com,
quic_jponduru@...cinc.com, quic_subashab@...cinc.com,
elder@...nel.org, netdev@...r.kernel.org,
linux-arm-msm@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH net-next v2 8/9] net: ipa: use a bitmap for set-up endpoints
Replace the 32-bit unsigned used to track endpoints that have
completed setup with a Linux bitmap, to allow an arbitrary number
of endpoints to be represented.
Rework the error handling in ipa_endpoint_init() so the defined
endpoint bitmap is freed if an error occurs early. Once endpoints
have been initialized, ipa_endpoint_exit() is used to recover if
the set of filtered endpoints is invalid.
Signed-off-by: Alex Elder <elder@...aro.org>
---
drivers/net/ipa/ipa.h | 4 ++--
drivers/net/ipa/ipa_endpoint.c | 38 +++++++++++++++++++---------------
2 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index 557101c2d5838..f14d1bd34e7e5 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -66,7 +66,7 @@ struct ipa_interrupt;
* @defined: Bitmap of endpoints defined in config data
* @available: Bitmap of endpoints supported by hardware
* @filtered: Bitmap of endpoints that support filtering
- * @set_up: Bit mask indicating endpoints set up
+ * @set_up: Bitmap of endpoints that are set up for use
* @enabled: Bit mask indicating endpoints enabled
* @modem_tx_count: Number of defined modem TX endoints
* @endpoint: Array of endpoint information
@@ -124,7 +124,7 @@ struct ipa {
unsigned long *defined; /* Defined in configuration data */
unsigned long *available; /* Supported by hardware */
u64 filtered; /* Support filtering (AP and modem) */
- u32 set_up;
+ unsigned long *set_up;
u32 enabled;
u32 modem_tx_count;
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 03811871dc4aa..3fe20b4d9c90b 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -1802,12 +1802,12 @@ static void ipa_endpoint_setup_one(struct ipa_endpoint *endpoint)
ipa_endpoint_program(endpoint);
- endpoint->ipa->set_up |= BIT(endpoint->endpoint_id);
+ __set_bit(endpoint->endpoint_id, endpoint->ipa->set_up);
}
static void ipa_endpoint_teardown_one(struct ipa_endpoint *endpoint)
{
- endpoint->ipa->set_up &= ~BIT(endpoint->endpoint_id);
+ __clear_bit(endpoint->endpoint_id, endpoint->ipa->set_up);
if (!endpoint->toward_ipa)
cancel_delayed_work_sync(&endpoint->replenish_work);
@@ -1819,23 +1819,16 @@ void ipa_endpoint_setup(struct ipa *ipa)
{
u32 endpoint_id;
- ipa->set_up = 0;
for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count)
ipa_endpoint_setup_one(&ipa->endpoint[endpoint_id]);
}
void ipa_endpoint_teardown(struct ipa *ipa)
{
- u32 set_up = ipa->set_up;
-
- while (set_up) {
- u32 endpoint_id = __fls(set_up);
-
- set_up ^= BIT(endpoint_id);
+ u32 endpoint_id;
+ for_each_set_bit(endpoint_id, ipa->set_up, ipa->endpoint_count)
ipa_endpoint_teardown_one(&ipa->endpoint[endpoint_id]);
- }
- ipa->set_up = 0;
}
void ipa_endpoint_deconfig(struct ipa *ipa)
@@ -1978,6 +1971,8 @@ void ipa_endpoint_exit(struct ipa *ipa)
for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count)
ipa_endpoint_exit_one(&ipa->endpoint[endpoint_id]);
+ bitmap_free(ipa->set_up);
+ ipa->set_up = NULL;
bitmap_free(ipa->defined);
ipa->defined = NULL;
@@ -1999,11 +1994,15 @@ int ipa_endpoint_init(struct ipa *ipa, u32 count,
if (!ipa->endpoint_count)
return -EINVAL;
- /* Initialize the defined endpoint bitmap */
+ /* Initialize endpoint state bitmaps */
ipa->defined = bitmap_zalloc(ipa->endpoint_count, GFP_KERNEL);
if (!ipa->defined)
return -ENOMEM;
+ ipa->set_up = bitmap_zalloc(ipa->endpoint_count, GFP_KERNEL);
+ if (!ipa->set_up)
+ goto err_free_defined;
+
filtered = 0;
for (name = 0; name < count; name++, data++) {
if (ipa_gsi_endpoint_data_empty(data))
@@ -2017,15 +2016,20 @@ int ipa_endpoint_init(struct ipa *ipa, u32 count,
ipa->modem_tx_count++;
}
- if (!ipa_filtered_valid(ipa, filtered))
- goto err_endpoint_exit;
+ /* Make sure the set of filtered endpoints is valid */
+ if (!ipa_filtered_valid(ipa, filtered)) {
+ ipa_endpoint_exit(ipa);
+
+ return -EINVAL;
+ }
ipa->filtered = filtered;
return 0;
-err_endpoint_exit:
- ipa_endpoint_exit(ipa);
+err_free_defined:
+ bitmap_free(ipa->defined);
+ ipa->defined = NULL;
- return -EINVAL;
+ return -ENOMEM;
}
--
2.34.1
Powered by blists - more mailing lists