Commit 2fc8a346 authored by Haiyang Zhang's avatar Haiyang Zhang Committed by Paolo Abeni
Browse files

net: mana: Support holes in device list reply msg



According to GDMA protocol, holes (zeros) are allowed at the beginning
or middle of the gdma_list_devices_resp message. The existing code
cannot properly handle this, and may miss some devices in the list.

To fix, scan the entire list until the num_of_devs are found, or until
the end of the list.

Cc: stable@vger.kernel.org
Fixes: ca9c54d2 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: default avatarLong Li <longli@microsoft.com>
Reviewed-by: default avatarShradha Gupta <shradhagupta@microsoft.com>
Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Link: https://patch.msgid.link/1741723974-1534-1-git-send-email-haiyangz@microsoft.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 5f079290
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -134,9 +134,10 @@ static int mana_gd_detect_devices(struct pci_dev *pdev)
	struct gdma_list_devices_resp resp = {};
	struct gdma_general_req req = {};
	struct gdma_dev_id dev;
	u32 i, max_num_devs;
	int found_dev = 0;
	u16 dev_type;
	int err;
	u32 i;

	mana_gd_init_req_hdr(&req.hdr, GDMA_LIST_DEVICES, sizeof(req),
			     sizeof(resp));
@@ -148,12 +149,17 @@ static int mana_gd_detect_devices(struct pci_dev *pdev)
		return err ? err : -EPROTO;
	}

	max_num_devs = min_t(u32, MAX_NUM_GDMA_DEVICES, resp.num_of_devs);

	for (i = 0; i < max_num_devs; i++) {
	for (i = 0; i < GDMA_DEV_LIST_SIZE &&
	     found_dev < resp.num_of_devs; i++) {
		dev = resp.devs[i];
		dev_type = dev.type;

		/* Skip empty devices */
		if (dev.as_uint32 == 0)
			continue;

		found_dev++;

		/* HWC is already detected in mana_hwc_create_channel(). */
		if (dev_type == GDMA_DEVICE_HWC)
			continue;
+7 −4
Original line number Diff line number Diff line
@@ -408,8 +408,6 @@ struct gdma_context {
	struct gdma_dev		mana_ib;
};

#define MAX_NUM_GDMA_DEVICES	4

static inline bool mana_gd_is_mana(struct gdma_dev *gd)
{
	return gd->dev_id.type == GDMA_DEVICE_MANA;
@@ -556,11 +554,15 @@ enum {
#define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG BIT(3)
#define GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT BIT(5)

/* Driver can handle holes (zeros) in the device list */
#define GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP BIT(11)

#define GDMA_DRV_CAP_FLAGS1 \
	(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
	 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
	 GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG | \
	 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT)
	 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \
	 GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP)

#define GDMA_DRV_CAP_FLAGS2 0

@@ -621,11 +623,12 @@ struct gdma_query_max_resources_resp {
}; /* HW DATA */

/* GDMA_LIST_DEVICES */
#define GDMA_DEV_LIST_SIZE 64
struct gdma_list_devices_resp {
	struct gdma_resp_hdr hdr;
	u32 num_of_devs;
	u32 reserved;
	struct gdma_dev_id devs[64];
	struct gdma_dev_id devs[GDMA_DEV_LIST_SIZE];
}; /* HW DATA */

/* GDMA_REGISTER_DEVICE */