Commit 7768c5f4 authored by Haiyang Zhang's avatar Haiyang Zhang Committed by Jakub Kicinski
Browse files

net: mana: Add handler for hardware servicing events



To collaborate with hardware servicing events, upon receiving the special
EQE notification from the HW channel, remove the devices on this bus.
Then, after a waiting period based on the device specs, rescan the parent
bus to recover the devices.

Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: default avatarShradha Gupta <shradhagupta@linux.microsoft.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/1749834034-18498-1-git-send-email-haiyangz@linux.microsoft.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7aa3f991
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
@@ -352,11 +352,59 @@ void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit)
}
EXPORT_SYMBOL_NS(mana_gd_ring_cq, "NET_MANA");

#define MANA_SERVICE_PERIOD 10

struct mana_serv_work {
	struct work_struct serv_work;
	struct pci_dev *pdev;
};

static void mana_serv_func(struct work_struct *w)
{
	struct mana_serv_work *mns_wk;
	struct pci_bus *bus, *parent;
	struct pci_dev *pdev;

	mns_wk = container_of(w, struct mana_serv_work, serv_work);
	pdev = mns_wk->pdev;

	pci_lock_rescan_remove();

	if (!pdev)
		goto out;

	bus = pdev->bus;
	if (!bus) {
		dev_err(&pdev->dev, "MANA service: no bus\n");
		goto out;
	}

	parent = bus->parent;
	if (!parent) {
		dev_err(&pdev->dev, "MANA service: no parent bus\n");
		goto out;
	}

	pci_stop_and_remove_bus_device(bus->self);

	msleep(MANA_SERVICE_PERIOD * 1000);

	pci_rescan_bus(parent);

out:
	pci_unlock_rescan_remove();

	pci_dev_put(pdev);
	kfree(mns_wk);
	module_put(THIS_MODULE);
}

static void mana_gd_process_eqe(struct gdma_queue *eq)
{
	u32 head = eq->head % (eq->queue_size / GDMA_EQE_SIZE);
	struct gdma_context *gc = eq->gdma_dev->gdma_context;
	struct gdma_eqe *eq_eqe_ptr = eq->queue_mem_ptr;
	struct mana_serv_work *mns_wk;
	union gdma_eqe_info eqe_info;
	enum gdma_eqe_type type;
	struct gdma_event event;
@@ -401,6 +449,33 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
		eq->eq.callback(eq->eq.context, eq, &event);
		break;

	case GDMA_EQE_HWC_FPGA_RECONFIG:
		dev_info(gc->dev, "Recv MANA service type:%d\n", type);

		if (gc->in_service) {
			dev_info(gc->dev, "Already in service\n");
			break;
		}

		if (!try_module_get(THIS_MODULE)) {
			dev_info(gc->dev, "Module is unloading\n");
			break;
		}

		mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC);
		if (!mns_wk) {
			module_put(THIS_MODULE);
			break;
		}

		dev_info(gc->dev, "Start MANA service type:%d\n", type);
		gc->in_service = true;
		mns_wk->pdev = to_pci_dev(gc->dev);
		pci_dev_get(mns_wk->pdev);
		INIT_WORK(&mns_wk->serv_work, mana_serv_func);
		schedule_work(&mns_wk->serv_work);
		break;

	default:
		break;
	}
+8 −2
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ enum gdma_eqe_type {
	GDMA_EQE_HWC_INIT_EQ_ID_DB	= 129,
	GDMA_EQE_HWC_INIT_DATA		= 130,
	GDMA_EQE_HWC_INIT_DONE		= 131,
	GDMA_EQE_HWC_SOC_RECONFIG	= 132,
	GDMA_EQE_HWC_FPGA_RECONFIG	= 132,
	GDMA_EQE_HWC_SOC_RECONFIG_DATA	= 133,
	GDMA_EQE_HWC_SOC_SERVICE	= 134,
	GDMA_EQE_RNIC_QP_FATAL		= 176,
@@ -403,6 +403,8 @@ struct gdma_context {
	u32			test_event_eq_id;

	bool			is_pf;
	bool			in_service;

	phys_addr_t		bar0_pa;
	void __iomem		*bar0_va;
	void __iomem		*shm_base;
@@ -578,12 +580,16 @@ enum {
/* Driver can handle holes (zeros) in the device list */
#define GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP BIT(11)

/* Driver can self reset on FPGA Reconfig EQE notification */
#define GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE BIT(17)

#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_DEV_LIST_HOLES_SUP)
	 GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP | \
	 GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE)

#define GDMA_DRV_CAP_FLAGS2 0