]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu/discovery: use common function to check discovery table
authorLikun Gao <Likun.Gao@amd.com>
Thu, 5 Mar 2026 19:34:56 +0000 (14:34 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 11 Mar 2026 17:58:07 +0000 (13:58 -0400)
Use an common function to check the validation of discovery table.

Signed-off-by: Likun Gao <Likun.Gao@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c

index 163b40c8afb06c69f17f708f4b11f57a370bd5af..6dd2886e6e7cb0998b98b68cf7f0f8196b671a28 100644 (file)
@@ -513,15 +513,95 @@ static int amdgpu_discovery_get_table_info(struct amdgpu_device *adev,
        return 0;
 }
 
-static int amdgpu_discovery_init(struct amdgpu_device *adev)
+static int amdgpu_discovery_table_check(struct amdgpu_device *adev,
+                                       uint8_t *discovery_bin,
+                                       uint16_t table_id)
 {
+       int r, act_val, exp_val, table_size;
+       uint16_t offset, checksum;
        struct table_info *info;
+       bool check_table = true;
+       char *table_name;
+
+       r = amdgpu_discovery_get_table_info(adev, &info, table_id);
+       if (r)
+               return r;
+       offset = le16_to_cpu(info->offset);
+       checksum = le16_to_cpu(info->checksum);
+
+       switch (table_id) {
+       case IP_DISCOVERY:
+               struct ip_discovery_header *ihdr =
+                       (struct ip_discovery_header *)(discovery_bin + offset);
+               act_val = le32_to_cpu(ihdr->signature);
+               exp_val = DISCOVERY_TABLE_SIGNATURE;
+               table_size = le16_to_cpu(ihdr->size);
+               table_name = "data table";
+               break;
+       case GC:
+               struct gpu_info_header *ghdr =
+                       (struct gpu_info_header *)(discovery_bin + offset);
+               act_val = le32_to_cpu(ghdr->table_id);
+               exp_val = GC_TABLE_ID;
+               table_size = le16_to_cpu(ghdr->size);
+               table_name = "gc table";
+               break;
+       case HARVEST_INFO:
+               struct harvest_info_header *hhdr =
+                       (struct harvest_info_header *)(discovery_bin + offset);
+               act_val = le32_to_cpu(hhdr->signature);
+               exp_val = HARVEST_TABLE_SIGNATURE;
+               table_size = sizeof(struct harvest_table);
+               table_name = "harvest table";
+               break;
+       case VCN_INFO:
+               struct vcn_info_header *vhdr =
+                       (struct vcn_info_header *)(discovery_bin + offset);
+               act_val = le32_to_cpu(vhdr->table_id);
+               exp_val = VCN_INFO_TABLE_ID;
+               table_size = le32_to_cpu(vhdr->size_bytes);
+               table_name = "vcn table";
+               break;
+       case MALL_INFO:
+               struct mall_info_header *mhdr =
+                       (struct mall_info_header *)(discovery_bin + offset);
+               act_val = le32_to_cpu(mhdr->table_id);
+               exp_val = MALL_INFO_TABLE_ID;
+               table_size = le32_to_cpu(mhdr->size_bytes);
+               table_name = "mall table";
+               check_table = false;
+               break;
+       default:
+               dev_err(adev->dev, "invalid ip discovery table id %d specified\n", table_id);
+               check_table = false;
+               break;
+       }
+
+       if (check_table && offset) {
+               if (act_val != exp_val) {
+                       dev_err(adev->dev, "invalid ip discovery %s signature\n", table_name);
+                       return -EINVAL;
+               }
+
+               if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset,
+                                                     table_size, checksum)) {
+                       dev_err(adev->dev, "invalid ip discovery %s checksum\n", table_name);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int amdgpu_discovery_init(struct amdgpu_device *adev)
+{
        struct binary_header *bhdr;
        uint8_t *discovery_bin;
        const char *fw_name;
        uint16_t offset;
        uint16_t size;
        uint16_t checksum;
+       uint16_t table_id;
        int r;
 
        adev->discovery.bin = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL);
@@ -569,128 +649,10 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
                goto out;
        }
 
-       r = amdgpu_discovery_get_table_info(adev, &info, IP_DISCOVERY);
-       if (r)
-               goto out;
-       offset = le16_to_cpu(info->offset);
-       checksum = le16_to_cpu(info->checksum);
-
-       if (offset) {
-               struct ip_discovery_header *ihdr =
-                       (struct ip_discovery_header *)(discovery_bin + offset);
-               if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) {
-                       dev_err(adev->dev, "invalid ip discovery data table signature\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-
-               if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset,
-                                                     le16_to_cpu(ihdr->size),
-                                                     checksum)) {
-                       dev_err(adev->dev, "invalid ip discovery data table checksum\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-       }
-
-       r = amdgpu_discovery_get_table_info(adev, &info, GC);
-       if (r)
-               goto out;
-       offset = le16_to_cpu(info->offset);
-       checksum = le16_to_cpu(info->checksum);
-
-       if (offset) {
-               struct gpu_info_header *ghdr =
-                       (struct gpu_info_header *)(discovery_bin + offset);
-
-               if (le32_to_cpu(ghdr->table_id) != GC_TABLE_ID) {
-                       dev_err(adev->dev, "invalid ip discovery gc table id\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-
-               if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset,
-                                                     le32_to_cpu(ghdr->size),
-                                                     checksum)) {
-                       dev_err(adev->dev, "invalid gc data table checksum\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-       }
-
-       r = amdgpu_discovery_get_table_info(adev, &info, HARVEST_INFO);
-       if (r)
-               goto out;
-       offset = le16_to_cpu(info->offset);
-       checksum = le16_to_cpu(info->checksum);
-
-       if (offset) {
-               struct harvest_info_header *hhdr =
-                       (struct harvest_info_header *)(discovery_bin + offset);
-
-               if (le32_to_cpu(hhdr->signature) != HARVEST_TABLE_SIGNATURE) {
-                       dev_err(adev->dev, "invalid ip discovery harvest table signature\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-
-               if (!amdgpu_discovery_verify_checksum(adev,
-                           discovery_bin + offset,
-                           sizeof(struct harvest_table), checksum)) {
-                       dev_err(adev->dev, "invalid harvest data table checksum\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-       }
-
-       r = amdgpu_discovery_get_table_info(adev, &info, VCN_INFO);
-       if (r)
-               goto out;
-       offset = le16_to_cpu(info->offset);
-       checksum = le16_to_cpu(info->checksum);
-
-       if (offset) {
-               struct vcn_info_header *vhdr =
-                       (struct vcn_info_header *)(discovery_bin + offset);
-
-               if (le32_to_cpu(vhdr->table_id) != VCN_INFO_TABLE_ID) {
-                       dev_err(adev->dev, "invalid ip discovery vcn table id\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-
-               if (!amdgpu_discovery_verify_checksum(adev,
-                           discovery_bin + offset,
-                           le32_to_cpu(vhdr->size_bytes), checksum)) {
-                       dev_err(adev->dev, "invalid vcn data table checksum\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-       }
-
-       r = amdgpu_discovery_get_table_info(adev, &info, MALL_INFO);
-       if (r)
-               goto out;
-       offset = le16_to_cpu(info->offset);
-       checksum = le16_to_cpu(info->checksum);
-
-       if (0 && offset) {
-               struct mall_info_header *mhdr =
-                       (struct mall_info_header *)(discovery_bin + offset);
-
-               if (le32_to_cpu(mhdr->table_id) != MALL_INFO_TABLE_ID) {
-                       dev_err(adev->dev, "invalid ip discovery mall table id\n");
-                       r = -EINVAL;
-                       goto out;
-               }
-
-               if (!amdgpu_discovery_verify_checksum(adev,
-                           discovery_bin + offset,
-                           le32_to_cpu(mhdr->size_bytes), checksum)) {
-                       dev_err(adev->dev, "invalid mall data table checksum\n");
-                       r = -EINVAL;
+       for (table_id = 0; table_id <= MALL_INFO; table_id++) {
+               r = amdgpu_discovery_table_check(adev, discovery_bin, table_id);
+               if (r)
                        goto out;
-               }
        }
 
        return 0;