summaryrefslogtreecommitdiff
path: root/drivers/net/ipa/ipa_endpoint.c
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2022-11-03 01:11:36 +0300
committerDavid S. Miller <davem@davemloft.net>2022-11-04 13:16:53 +0300
commit88de7672404de72e273c4f1f4228120b8d7f01f1 (patch)
tree86327d56f8c70c89c7d0fccbf5ef47befd16277c /drivers/net/ipa/ipa_endpoint.c
parent9a9f512974d5e3e721e106f30429c16dfeb23326 (diff)
downloadlinux-88de7672404de72e273c4f1f4228120b8d7f01f1.tar.xz
net: ipa: use a bitmap for available endpoints
Similar to the previous patch, replace the 32-bit unsigned used to track endpoints supported by hardware with a Linux bitmap, to allow an arbitrary number of endpoints to be represented. Move ipa_endpoint_deconfig() above ipa_endpoint_config() and use it in the error path of the latter function. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ipa/ipa_endpoint.c')
-rw-r--r--drivers/net/ipa/ipa_endpoint.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index abc939c272b5..a7932e8d0b2b 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -351,19 +351,17 @@ ipa_endpoint_program_delay(struct ipa_endpoint *endpoint, bool enable)
static bool ipa_endpoint_aggr_active(struct ipa_endpoint *endpoint)
{
u32 endpoint_id = endpoint->endpoint_id;
- u32 mask = BIT(endpoint_id % 32);
struct ipa *ipa = endpoint->ipa;
u32 unit = endpoint_id / 32;
const struct ipa_reg *reg;
u32 val;
- /* This works until we actually have more than 32 endpoints */
- WARN_ON(!(mask & ipa->available));
+ WARN_ON(!test_bit(endpoint_id, ipa->available));
reg = ipa_reg(ipa, STATE_AGGR_ACTIVE);
val = ioread32(ipa->reg_virt + ipa_reg_n_offset(reg, unit));
- return !!(val & mask);
+ return !!(val & BIT(endpoint_id % 32));
}
static void ipa_endpoint_force_close(struct ipa_endpoint *endpoint)
@@ -374,8 +372,7 @@ static void ipa_endpoint_force_close(struct ipa_endpoint *endpoint)
u32 unit = endpoint_id / 32;
const struct ipa_reg *reg;
- /* This works until we actually have more than 32 endpoints */
- WARN_ON(!(mask & ipa->available));
+ WARN_ON(!test_bit(endpoint_id, ipa->available));
reg = ipa_reg(ipa, AGGR_FORCE_CLOSE);
iowrite32(mask, ipa->reg_virt + ipa_reg_n_offset(reg, unit));
@@ -1841,6 +1838,13 @@ void ipa_endpoint_teardown(struct ipa *ipa)
ipa->set_up = 0;
}
+void ipa_endpoint_deconfig(struct ipa *ipa)
+{
+ ipa->available_count = 0;
+ bitmap_free(ipa->available);
+ ipa->available = NULL;
+}
+
int ipa_endpoint_config(struct ipa *ipa)
{
struct device *dev = &ipa->pdev->dev;
@@ -1863,7 +1867,13 @@ int ipa_endpoint_config(struct ipa *ipa)
* assume the configuration is valid.
*/
if (ipa->version < IPA_VERSION_3_5) {
- ipa->available = ~0;
+ ipa->available = bitmap_zalloc(IPA_ENDPOINT_MAX, GFP_KERNEL);
+ if (!ipa->available)
+ return -ENOMEM;
+ ipa->available_count = IPA_ENDPOINT_MAX;
+
+ bitmap_set(ipa->available, 0, IPA_ENDPOINT_MAX);
+
return 0;
}
@@ -1885,8 +1895,15 @@ int ipa_endpoint_config(struct ipa *ipa)
return -EINVAL;
}
+ /* Allocate and initialize the available endpoint bitmap */
+ ipa->available = bitmap_zalloc(limit, GFP_KERNEL);
+ if (!ipa->available)
+ return -ENOMEM;
+ ipa->available_count = limit;
+
/* Mark all supported RX and TX endpoints as available */
- ipa->available = GENMASK(limit - 1, rx_base) | GENMASK(tx_count - 1, 0);
+ bitmap_set(ipa->available, 0, tx_count);
+ bitmap_set(ipa->available, rx_base, rx_count);
for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count) {
struct ipa_endpoint *endpoint;
@@ -1894,13 +1911,13 @@ int ipa_endpoint_config(struct ipa *ipa)
if (endpoint_id >= limit) {
dev_err(dev, "invalid endpoint id, %u > %u\n",
endpoint_id, limit - 1);
- return -EINVAL;
+ goto err_free_bitmap;
}
- if (!(BIT(endpoint_id) & ipa->available)) {
+ if (!test_bit(endpoint_id, ipa->available)) {
dev_err(dev, "unavailable endpoint id %u\n",
endpoint_id);
- return -EINVAL;
+ goto err_free_bitmap;
}
/* Make sure it's pointing in the right direction */
@@ -1913,15 +1930,15 @@ int ipa_endpoint_config(struct ipa *ipa)
}
dev_err(dev, "endpoint id %u wrong direction\n", endpoint_id);
- return -EINVAL;
+ goto err_free_bitmap;
}
return 0;
-}
-void ipa_endpoint_deconfig(struct ipa *ipa)
-{
- ipa->available = 0; /* Nothing more to do */
+err_free_bitmap:
+ ipa_endpoint_deconfig(ipa);
+
+ return -EINVAL;
}
static void ipa_endpoint_init_one(struct ipa *ipa, enum ipa_endpoint_name name,