162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright (C) 2021, Intel Corporation. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci/* Inter-Driver Communication */
562306a36Sopenharmony_ci#include "ice.h"
662306a36Sopenharmony_ci#include "ice_lib.h"
762306a36Sopenharmony_ci#include "ice_dcb_lib.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_cistatic DEFINE_XARRAY_ALLOC1(ice_aux_id);
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/**
1262306a36Sopenharmony_ci * ice_get_auxiliary_drv - retrieve iidc_auxiliary_drv struct
1362306a36Sopenharmony_ci * @pf: pointer to PF struct
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * This function has to be called with a device_lock on the
1662306a36Sopenharmony_ci * pf->adev.dev to avoid race conditions.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_cistatic struct iidc_auxiliary_drv *ice_get_auxiliary_drv(struct ice_pf *pf)
1962306a36Sopenharmony_ci{
2062306a36Sopenharmony_ci	struct auxiliary_device *adev;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	adev = pf->adev;
2362306a36Sopenharmony_ci	if (!adev || !adev->dev.driver)
2462306a36Sopenharmony_ci		return NULL;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	return container_of(adev->dev.driver, struct iidc_auxiliary_drv,
2762306a36Sopenharmony_ci			    adrv.driver);
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/**
3162306a36Sopenharmony_ci * ice_send_event_to_aux - send event to RDMA AUX driver
3262306a36Sopenharmony_ci * @pf: pointer to PF struct
3362306a36Sopenharmony_ci * @event: event struct
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_civoid ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	struct iidc_auxiliary_drv *iadrv;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	if (WARN_ON_ONCE(!in_task()))
4062306a36Sopenharmony_ci		return;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	mutex_lock(&pf->adev_mutex);
4362306a36Sopenharmony_ci	if (!pf->adev)
4462306a36Sopenharmony_ci		goto finish;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	device_lock(&pf->adev->dev);
4762306a36Sopenharmony_ci	iadrv = ice_get_auxiliary_drv(pf);
4862306a36Sopenharmony_ci	if (iadrv && iadrv->event_handler)
4962306a36Sopenharmony_ci		iadrv->event_handler(pf, event);
5062306a36Sopenharmony_ci	device_unlock(&pf->adev->dev);
5162306a36Sopenharmony_cifinish:
5262306a36Sopenharmony_ci	mutex_unlock(&pf->adev_mutex);
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/**
5662306a36Sopenharmony_ci * ice_add_rdma_qset - Add Leaf Node for RDMA Qset
5762306a36Sopenharmony_ci * @pf: PF struct
5862306a36Sopenharmony_ci * @qset: Resource to be allocated
5962306a36Sopenharmony_ci */
6062306a36Sopenharmony_ciint ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS];
6362306a36Sopenharmony_ci	struct ice_vsi *vsi;
6462306a36Sopenharmony_ci	struct device *dev;
6562306a36Sopenharmony_ci	u32 qset_teid;
6662306a36Sopenharmony_ci	u16 qs_handle;
6762306a36Sopenharmony_ci	int status;
6862306a36Sopenharmony_ci	int i;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	if (WARN_ON(!pf || !qset))
7162306a36Sopenharmony_ci		return -EINVAL;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	dev = ice_pf_to_dev(pf);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	if (!ice_is_rdma_ena(pf))
7662306a36Sopenharmony_ci		return -EINVAL;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	vsi = ice_get_main_vsi(pf);
7962306a36Sopenharmony_ci	if (!vsi) {
8062306a36Sopenharmony_ci		dev_err(dev, "RDMA QSet invalid VSI\n");
8162306a36Sopenharmony_ci		return -EINVAL;
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	ice_for_each_traffic_class(i)
8562306a36Sopenharmony_ci		max_rdmaqs[i] = 0;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	max_rdmaqs[qset->tc]++;
8862306a36Sopenharmony_ci	qs_handle = qset->qs_handle;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
9162306a36Sopenharmony_ci				  max_rdmaqs);
9262306a36Sopenharmony_ci	if (status) {
9362306a36Sopenharmony_ci		dev_err(dev, "Failed VSI RDMA Qset config\n");
9462306a36Sopenharmony_ci		return status;
9562306a36Sopenharmony_ci	}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc,
9862306a36Sopenharmony_ci				       &qs_handle, 1, &qset_teid);
9962306a36Sopenharmony_ci	if (status) {
10062306a36Sopenharmony_ci		dev_err(dev, "Failed VSI RDMA Qset enable\n");
10162306a36Sopenharmony_ci		return status;
10262306a36Sopenharmony_ci	}
10362306a36Sopenharmony_ci	vsi->qset_handle[qset->tc] = qset->qs_handle;
10462306a36Sopenharmony_ci	qset->teid = qset_teid;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	return 0;
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_add_rdma_qset);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/**
11162306a36Sopenharmony_ci * ice_del_rdma_qset - Delete leaf node for RDMA Qset
11262306a36Sopenharmony_ci * @pf: PF struct
11362306a36Sopenharmony_ci * @qset: Resource to be freed
11462306a36Sopenharmony_ci */
11562306a36Sopenharmony_ciint ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	struct ice_vsi *vsi;
11862306a36Sopenharmony_ci	u32 teid;
11962306a36Sopenharmony_ci	u16 q_id;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	if (WARN_ON(!pf || !qset))
12262306a36Sopenharmony_ci		return -EINVAL;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	vsi = ice_find_vsi(pf, qset->vport_id);
12562306a36Sopenharmony_ci	if (!vsi) {
12662306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n");
12762306a36Sopenharmony_ci		return -EINVAL;
12862306a36Sopenharmony_ci	}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	q_id = qset->qs_handle;
13162306a36Sopenharmony_ci	teid = qset->teid;
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	vsi->qset_handle[qset->tc] = 0;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id);
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_del_rdma_qset);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/**
14062306a36Sopenharmony_ci * ice_rdma_request_reset - accept request from RDMA to perform a reset
14162306a36Sopenharmony_ci * @pf: struct for PF
14262306a36Sopenharmony_ci * @reset_type: type of reset
14362306a36Sopenharmony_ci */
14462306a36Sopenharmony_ciint ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type)
14562306a36Sopenharmony_ci{
14662306a36Sopenharmony_ci	enum ice_reset_req reset;
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	if (WARN_ON(!pf))
14962306a36Sopenharmony_ci		return -EINVAL;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	switch (reset_type) {
15262306a36Sopenharmony_ci	case IIDC_PFR:
15362306a36Sopenharmony_ci		reset = ICE_RESET_PFR;
15462306a36Sopenharmony_ci		break;
15562306a36Sopenharmony_ci	case IIDC_CORER:
15662306a36Sopenharmony_ci		reset = ICE_RESET_CORER;
15762306a36Sopenharmony_ci		break;
15862306a36Sopenharmony_ci	case IIDC_GLOBR:
15962306a36Sopenharmony_ci		reset = ICE_RESET_GLOBR;
16062306a36Sopenharmony_ci		break;
16162306a36Sopenharmony_ci	default:
16262306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf), "incorrect reset request\n");
16362306a36Sopenharmony_ci		return -EINVAL;
16462306a36Sopenharmony_ci	}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	return ice_schedule_reset(pf, reset);
16762306a36Sopenharmony_ci}
16862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_rdma_request_reset);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/**
17162306a36Sopenharmony_ci * ice_rdma_update_vsi_filter - update main VSI filters for RDMA
17262306a36Sopenharmony_ci * @pf: pointer to struct for PF
17362306a36Sopenharmony_ci * @vsi_id: VSI HW idx to update filter on
17462306a36Sopenharmony_ci * @enable: bool whether to enable or disable filters
17562306a36Sopenharmony_ci */
17662306a36Sopenharmony_ciint ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	struct ice_vsi *vsi;
17962306a36Sopenharmony_ci	int status;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	if (WARN_ON(!pf))
18262306a36Sopenharmony_ci		return -EINVAL;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	vsi = ice_find_vsi(pf, vsi_id);
18562306a36Sopenharmony_ci	if (!vsi)
18662306a36Sopenharmony_ci		return -EINVAL;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable);
18962306a36Sopenharmony_ci	if (status) {
19062306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf), "Failed to  %sable RDMA filtering\n",
19162306a36Sopenharmony_ci			enable ? "en" : "dis");
19262306a36Sopenharmony_ci	} else {
19362306a36Sopenharmony_ci		if (enable)
19462306a36Sopenharmony_ci			vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
19562306a36Sopenharmony_ci		else
19662306a36Sopenharmony_ci			vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
19762306a36Sopenharmony_ci	}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return status;
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter);
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci/**
20462306a36Sopenharmony_ci * ice_get_qos_params - parse QoS params for RDMA consumption
20562306a36Sopenharmony_ci * @pf: pointer to PF struct
20662306a36Sopenharmony_ci * @qos: set of QoS values
20762306a36Sopenharmony_ci */
20862306a36Sopenharmony_civoid ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	struct ice_dcbx_cfg *dcbx_cfg;
21162306a36Sopenharmony_ci	unsigned int i;
21262306a36Sopenharmony_ci	u32 up2tc;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
21562306a36Sopenharmony_ci	up2tc = rd32(&pf->hw, PRTDCB_TUP2TC);
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	qos->num_tc = ice_dcb_get_num_tc(dcbx_cfg);
21862306a36Sopenharmony_ci	for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
21962306a36Sopenharmony_ci		qos->up2tc[i] = (up2tc >> (i * 3)) & 0x7;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
22262306a36Sopenharmony_ci		qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i];
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	qos->pfc_mode = dcbx_cfg->pfc_mode;
22562306a36Sopenharmony_ci	if (qos->pfc_mode == IIDC_DSCP_PFC_MODE)
22662306a36Sopenharmony_ci		for (i = 0; i < IIDC_MAX_DSCP_MAPPING; i++)
22762306a36Sopenharmony_ci			qos->dscp_map[i] = dcbx_cfg->dscp_map[i];
22862306a36Sopenharmony_ci}
22962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_get_qos_params);
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci/**
23262306a36Sopenharmony_ci * ice_alloc_rdma_qvectors - Allocate vector resources for RDMA driver
23362306a36Sopenharmony_ci * @pf: board private structure to initialize
23462306a36Sopenharmony_ci */
23562306a36Sopenharmony_cistatic int ice_alloc_rdma_qvectors(struct ice_pf *pf)
23662306a36Sopenharmony_ci{
23762306a36Sopenharmony_ci	if (ice_is_rdma_ena(pf)) {
23862306a36Sopenharmony_ci		int i;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci		pf->msix_entries = kcalloc(pf->num_rdma_msix,
24162306a36Sopenharmony_ci					   sizeof(*pf->msix_entries),
24262306a36Sopenharmony_ci						  GFP_KERNEL);
24362306a36Sopenharmony_ci		if (!pf->msix_entries)
24462306a36Sopenharmony_ci			return -ENOMEM;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci		/* RDMA is the only user of pf->msix_entries array */
24762306a36Sopenharmony_ci		pf->rdma_base_vector = 0;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci		for (i = 0; i < pf->num_rdma_msix; i++) {
25062306a36Sopenharmony_ci			struct msix_entry *entry = &pf->msix_entries[i];
25162306a36Sopenharmony_ci			struct msi_map map;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci			map = ice_alloc_irq(pf, false);
25462306a36Sopenharmony_ci			if (map.index < 0)
25562306a36Sopenharmony_ci				break;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci			entry->entry = map.index;
25862306a36Sopenharmony_ci			entry->vector = map.virq;
25962306a36Sopenharmony_ci		}
26062306a36Sopenharmony_ci	}
26162306a36Sopenharmony_ci	return 0;
26262306a36Sopenharmony_ci}
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci/**
26562306a36Sopenharmony_ci * ice_free_rdma_qvector - free vector resources reserved for RDMA driver
26662306a36Sopenharmony_ci * @pf: board private structure to initialize
26762306a36Sopenharmony_ci */
26862306a36Sopenharmony_cistatic void ice_free_rdma_qvector(struct ice_pf *pf)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci	int i;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	if (!pf->msix_entries)
27362306a36Sopenharmony_ci		return;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	for (i = 0; i < pf->num_rdma_msix; i++) {
27662306a36Sopenharmony_ci		struct msi_map map;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci		map.index = pf->msix_entries[i].entry;
27962306a36Sopenharmony_ci		map.virq = pf->msix_entries[i].vector;
28062306a36Sopenharmony_ci		ice_free_irq(pf, map);
28162306a36Sopenharmony_ci	}
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	kfree(pf->msix_entries);
28462306a36Sopenharmony_ci	pf->msix_entries = NULL;
28562306a36Sopenharmony_ci}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/**
28862306a36Sopenharmony_ci * ice_adev_release - function to be mapped to AUX dev's release op
28962306a36Sopenharmony_ci * @dev: pointer to device to free
29062306a36Sopenharmony_ci */
29162306a36Sopenharmony_cistatic void ice_adev_release(struct device *dev)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	struct iidc_auxiliary_dev *iadev;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev);
29662306a36Sopenharmony_ci	kfree(iadev);
29762306a36Sopenharmony_ci}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci/**
30062306a36Sopenharmony_ci * ice_plug_aux_dev - allocate and register AUX device
30162306a36Sopenharmony_ci * @pf: pointer to pf struct
30262306a36Sopenharmony_ci */
30362306a36Sopenharmony_ciint ice_plug_aux_dev(struct ice_pf *pf)
30462306a36Sopenharmony_ci{
30562306a36Sopenharmony_ci	struct iidc_auxiliary_dev *iadev;
30662306a36Sopenharmony_ci	struct auxiliary_device *adev;
30762306a36Sopenharmony_ci	int ret;
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	/* if this PF doesn't support a technology that requires auxiliary
31062306a36Sopenharmony_ci	 * devices, then gracefully exit
31162306a36Sopenharmony_ci	 */
31262306a36Sopenharmony_ci	if (!ice_is_rdma_ena(pf))
31362306a36Sopenharmony_ci		return 0;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
31662306a36Sopenharmony_ci	if (!iadev)
31762306a36Sopenharmony_ci		return -ENOMEM;
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	adev = &iadev->adev;
32062306a36Sopenharmony_ci	iadev->pf = pf;
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	adev->id = pf->aux_idx;
32362306a36Sopenharmony_ci	adev->dev.release = ice_adev_release;
32462306a36Sopenharmony_ci	adev->dev.parent = &pf->pdev->dev;
32562306a36Sopenharmony_ci	adev->name = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? "roce" : "iwarp";
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	ret = auxiliary_device_init(adev);
32862306a36Sopenharmony_ci	if (ret) {
32962306a36Sopenharmony_ci		kfree(iadev);
33062306a36Sopenharmony_ci		return ret;
33162306a36Sopenharmony_ci	}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	ret = auxiliary_device_add(adev);
33462306a36Sopenharmony_ci	if (ret) {
33562306a36Sopenharmony_ci		auxiliary_device_uninit(adev);
33662306a36Sopenharmony_ci		return ret;
33762306a36Sopenharmony_ci	}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	mutex_lock(&pf->adev_mutex);
34062306a36Sopenharmony_ci	pf->adev = adev;
34162306a36Sopenharmony_ci	mutex_unlock(&pf->adev_mutex);
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	return 0;
34462306a36Sopenharmony_ci}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci/* ice_unplug_aux_dev - unregister and free AUX device
34762306a36Sopenharmony_ci * @pf: pointer to pf struct
34862306a36Sopenharmony_ci */
34962306a36Sopenharmony_civoid ice_unplug_aux_dev(struct ice_pf *pf)
35062306a36Sopenharmony_ci{
35162306a36Sopenharmony_ci	struct auxiliary_device *adev;
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	mutex_lock(&pf->adev_mutex);
35462306a36Sopenharmony_ci	adev = pf->adev;
35562306a36Sopenharmony_ci	pf->adev = NULL;
35662306a36Sopenharmony_ci	mutex_unlock(&pf->adev_mutex);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	if (adev) {
35962306a36Sopenharmony_ci		auxiliary_device_delete(adev);
36062306a36Sopenharmony_ci		auxiliary_device_uninit(adev);
36162306a36Sopenharmony_ci	}
36262306a36Sopenharmony_ci}
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci/**
36562306a36Sopenharmony_ci * ice_init_rdma - initializes PF for RDMA use
36662306a36Sopenharmony_ci * @pf: ptr to ice_pf
36762306a36Sopenharmony_ci */
36862306a36Sopenharmony_ciint ice_init_rdma(struct ice_pf *pf)
36962306a36Sopenharmony_ci{
37062306a36Sopenharmony_ci	struct device *dev = &pf->pdev->dev;
37162306a36Sopenharmony_ci	int ret;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	if (!ice_is_rdma_ena(pf)) {
37462306a36Sopenharmony_ci		dev_warn(dev, "RDMA is not supported on this device\n");
37562306a36Sopenharmony_ci		return 0;
37662306a36Sopenharmony_ci	}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	ret = xa_alloc(&ice_aux_id, &pf->aux_idx, NULL, XA_LIMIT(1, INT_MAX),
37962306a36Sopenharmony_ci		       GFP_KERNEL);
38062306a36Sopenharmony_ci	if (ret) {
38162306a36Sopenharmony_ci		dev_err(dev, "Failed to allocate device ID for AUX driver\n");
38262306a36Sopenharmony_ci		return -ENOMEM;
38362306a36Sopenharmony_ci	}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	/* Reserve vector resources */
38662306a36Sopenharmony_ci	ret = ice_alloc_rdma_qvectors(pf);
38762306a36Sopenharmony_ci	if (ret < 0) {
38862306a36Sopenharmony_ci		dev_err(dev, "failed to reserve vectors for RDMA\n");
38962306a36Sopenharmony_ci		goto err_reserve_rdma_qvector;
39062306a36Sopenharmony_ci	}
39162306a36Sopenharmony_ci	pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;
39262306a36Sopenharmony_ci	ret = ice_plug_aux_dev(pf);
39362306a36Sopenharmony_ci	if (ret)
39462306a36Sopenharmony_ci		goto err_plug_aux_dev;
39562306a36Sopenharmony_ci	return 0;
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cierr_plug_aux_dev:
39862306a36Sopenharmony_ci	ice_free_rdma_qvector(pf);
39962306a36Sopenharmony_cierr_reserve_rdma_qvector:
40062306a36Sopenharmony_ci	pf->adev = NULL;
40162306a36Sopenharmony_ci	xa_erase(&ice_aux_id, pf->aux_idx);
40262306a36Sopenharmony_ci	return ret;
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci/**
40662306a36Sopenharmony_ci * ice_deinit_rdma - deinitialize RDMA on PF
40762306a36Sopenharmony_ci * @pf: ptr to ice_pf
40862306a36Sopenharmony_ci */
40962306a36Sopenharmony_civoid ice_deinit_rdma(struct ice_pf *pf)
41062306a36Sopenharmony_ci{
41162306a36Sopenharmony_ci	if (!ice_is_rdma_ena(pf))
41262306a36Sopenharmony_ci		return;
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	ice_unplug_aux_dev(pf);
41562306a36Sopenharmony_ci	ice_free_rdma_qvector(pf);
41662306a36Sopenharmony_ci	xa_erase(&ice_aux_id, pf->aux_idx);
41762306a36Sopenharmony_ci}
418