]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: hns3: fix the imp capability bit cannot exceed 32 bits issue
authorHao Lan <lanhao@huawei.com>
Thu, 20 Jul 2023 02:05:07 +0000 (10:05 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Aug 2023 08:23:58 +0000 (10:23 +0200)
[ Upstream commit b27d0232e8897f7c896dc8ad80c9907dd57fd3f3 ]

Current only the first 32 bits of the capability flag bit are considered.
When the matching capability flag bit is greater than 31 bits,
it will get an error bit.This patch use bitmap to solve this issue.
It can handle each capability bit whitout bit width limit.

Fixes: da77aef9cc58 ("net: hns3: create common cmdq resource allocate/free/query APIs")
Signed-off-by: Hao Lan <lanhao@huawei.com>
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c

index 17137de9338cf7aacf7fbb480765b91c2b27cd2f..fcb8b6dc5ab929bcb631b0e35378d1c6b71a978e 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/pci.h>
 #include <linux/pkt_sched.h>
 #include <linux/types.h>
+#include <linux/bitmap.h>
 #include <net/pkt_cls.h>
 
 #define HNAE3_MOD_VERSION "1.0"
@@ -402,7 +403,7 @@ struct hnae3_ae_dev {
        unsigned long hw_err_reset_req;
        struct hnae3_dev_specs dev_specs;
        u32 dev_version;
-       unsigned long caps[BITS_TO_LONGS(HNAE3_DEV_CAPS_MAX_NUM)];
+       DECLARE_BITMAP(caps, HNAE3_DEV_CAPS_MAX_NUM);
        void *priv;
 };
 
index c797d54f98caa5e773bcd6204f3016b0767dbe0f..2ccb0f5460797e48ef54e26449aff0fd67d126b5 100644 (file)
@@ -170,6 +170,20 @@ static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = {
        {HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B},
 };
 
+static void
+hclge_comm_capability_to_bitmap(unsigned long *bitmap, __le32 *caps)
+{
+       const unsigned int words = HCLGE_COMM_QUERY_CAP_LENGTH;
+       u32 val[HCLGE_COMM_QUERY_CAP_LENGTH];
+       unsigned int i;
+
+       for (i = 0; i < words; i++)
+               val[i] = __le32_to_cpu(caps[i]);
+
+       bitmap_from_arr32(bitmap, val,
+                         HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32));
+}
+
 static void
 hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf,
                            struct hclge_comm_query_version_cmd *cmd)
@@ -178,11 +192,12 @@ hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf,
                                is_pf ? hclge_pf_cmd_caps : hclge_vf_cmd_caps;
        u32 size = is_pf ? ARRAY_SIZE(hclge_pf_cmd_caps) :
                                ARRAY_SIZE(hclge_vf_cmd_caps);
-       u32 caps, i;
+       DECLARE_BITMAP(caps, HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32));
+       u32 i;
 
-       caps = __le32_to_cpu(cmd->caps[0]);
+       hclge_comm_capability_to_bitmap(caps, cmd->caps);
        for (i = 0; i < size; i++)
-               if (hnae3_get_bit(caps, caps_map[i].imp_bit))
+               if (test_bit(caps_map[i].imp_bit, caps))
                        set_bit(caps_map[i].local_bit, ae_dev->caps);
 }