Skip to content

Commit f4312e6

Browse files
jahay1anguy11
authored andcommitted
idpf: implement core RDMA auxiliary dev create, init, and destroy
Add the initial idpf_idc.c file with the functions to kick off the IDC initialization, create and initialize a core RDMA auxiliary device, and destroy said device. The RDMA core has a dependency on the vports being created by the control plane before it can be initialized. Therefore, once all the vports are up after a hard reset (either during driver load a function level reset), the core RDMA device info will be created. It is populated with the function type (as distinguished by the IDC initialization function pointer), the core idc_ops function points (just stubs for now), the reserved RDMA MSIX table, and various other info the core RDMA auxiliary driver will need. It is then plugged on to the bus. During a function level reset or driver unload, the device will be unplugged from the bus and destroyed. Reviewed-by: Madhu Chittim <[email protected]> Signed-off-by: Joshua Hay <[email protected]> Signed-off-by: Tatyana Nikolova <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent bfc5cc8 commit f4312e6

File tree

9 files changed

+322
-0
lines changed

9 files changed

+322
-0
lines changed

drivers/net/ethernet/intel/idpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ idpf-y := \
1010
idpf_controlq_setup.o \
1111
idpf_dev.o \
1212
idpf_ethtool.o \
13+
idpf_idc.o \
1314
idpf_lib.o \
1415
idpf_main.o \
1516
idpf_txrx.o \

drivers/net/ethernet/intel/idpf/idpf.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ struct idpf_vport_max_q;
1818
#include <linux/ethtool_netlink.h>
1919
#include <net/gro.h>
2020

21+
#include <linux/net/intel/iidc_rdma.h>
22+
#include <linux/net/intel/iidc_rdma_idpf.h>
23+
2124
#include "virtchnl2.h"
2225
#include "idpf_txrx.h"
2326
#include "idpf_controlq.h"
@@ -206,9 +209,12 @@ struct idpf_reg_ops {
206209
/**
207210
* struct idpf_dev_ops - Device specific operations
208211
* @reg_ops: Register operations
212+
* @idc_init: IDC initialization
209213
*/
210214
struct idpf_dev_ops {
211215
struct idpf_reg_ops reg_ops;
216+
217+
int (*idc_init)(struct idpf_adapter *adapter);
212218
};
213219

214220
/**
@@ -540,6 +546,7 @@ struct idpf_vc_xn_manager;
540546
* @caps: Negotiated capabilities with device
541547
* @vcxn_mngr: Virtchnl transaction manager
542548
* @dev_ops: See idpf_dev_ops
549+
* @cdev_info: IDC core device info pointer
543550
* @num_vfs: Number of allocated VFs through sysfs. PF does not directly talk
544551
* to VFs but is used to initialize them
545552
* @crc_enable: Enable CRC insertion offload
@@ -599,6 +606,7 @@ struct idpf_adapter {
599606
struct idpf_vc_xn_manager *vcxn_mngr;
600607

601608
struct idpf_dev_ops dev_ops;
609+
struct iidc_rdma_core_dev_info *cdev_info;
602610
int num_vfs;
603611
bool crc_enable;
604612
bool req_tx_splitq;
@@ -877,5 +885,9 @@ int idpf_sriov_configure(struct pci_dev *pdev, int num_vfs);
877885

878886
u8 idpf_vport_get_hsplit(const struct idpf_vport *vport);
879887
bool idpf_vport_set_hsplit(const struct idpf_vport *vport, u8 val);
888+
int idpf_idc_init(struct idpf_adapter *adapter);
889+
int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter,
890+
enum iidc_function_type ftype);
891+
void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info);
880892

881893
#endif /* !_IDPF_H_ */

drivers/net/ethernet/intel/idpf/idpf_dev.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ static void idpf_ptp_reg_init(const struct idpf_adapter *adapter)
161161
adapter->ptp->cmd.exec_cmd_mask = PF_GLTSYN_CMD_SYNC_EXEC_CMD_M;
162162
}
163163

164+
/**
165+
* idpf_idc_register - register for IDC callbacks
166+
* @adapter: Driver specific private structure
167+
*
168+
* Return: 0 on success or error code on failure.
169+
*/
170+
static int idpf_idc_register(struct idpf_adapter *adapter)
171+
{
172+
return idpf_idc_init_aux_core_dev(adapter, IIDC_FUNCTION_TYPE_PF);
173+
}
174+
164175
/**
165176
* idpf_reg_ops_init - Initialize register API function pointers
166177
* @adapter: Driver specific private structure
@@ -182,4 +193,6 @@ static void idpf_reg_ops_init(struct idpf_adapter *adapter)
182193
void idpf_dev_ops_init(struct idpf_adapter *adapter)
183194
{
184195
idpf_reg_ops_init(adapter);
196+
197+
adapter->dev_ops.idc_init = idpf_idc_register;
185198
}
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (C) 2025 Intel Corporation */
3+
4+
#include <linux/export.h>
5+
6+
#include "idpf.h"
7+
#include "idpf_virtchnl.h"
8+
9+
static DEFINE_IDA(idpf_idc_ida);
10+
11+
#define IDPF_IDC_MAX_ADEV_NAME_LEN 15
12+
13+
/**
14+
* idpf_idc_init - Called to initialize IDC
15+
* @adapter: driver private data structure
16+
*
17+
* Return: 0 on success or cap not enabled, error code on failure.
18+
*/
19+
int idpf_idc_init(struct idpf_adapter *adapter)
20+
{
21+
int err;
22+
23+
if (!idpf_is_rdma_cap_ena(adapter) ||
24+
!adapter->dev_ops.idc_init)
25+
return 0;
26+
27+
err = adapter->dev_ops.idc_init(adapter);
28+
if (err)
29+
dev_err(&adapter->pdev->dev, "failed to initialize idc: %d\n",
30+
err);
31+
32+
return err;
33+
}
34+
35+
/**
36+
* idpf_core_adev_release - function to be mapped to aux dev's release op
37+
* @dev: pointer to device to free
38+
*/
39+
static void idpf_core_adev_release(struct device *dev)
40+
{
41+
struct iidc_rdma_core_auxiliary_dev *iadev;
42+
43+
iadev = container_of(dev, struct iidc_rdma_core_auxiliary_dev, adev.dev);
44+
kfree(iadev);
45+
iadev = NULL;
46+
}
47+
48+
/**
49+
* idpf_plug_core_aux_dev - allocate and register an Auxiliary device
50+
* @cdev_info: IDC core device info pointer
51+
*
52+
* Return: 0 on success or error code on failure.
53+
*/
54+
static int idpf_plug_core_aux_dev(struct iidc_rdma_core_dev_info *cdev_info)
55+
{
56+
struct iidc_rdma_core_auxiliary_dev *iadev;
57+
char name[IDPF_IDC_MAX_ADEV_NAME_LEN];
58+
struct auxiliary_device *adev;
59+
int ret;
60+
61+
iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
62+
if (!iadev)
63+
return -ENOMEM;
64+
65+
adev = &iadev->adev;
66+
cdev_info->adev = adev;
67+
iadev->cdev_info = cdev_info;
68+
69+
ret = ida_alloc(&idpf_idc_ida, GFP_KERNEL);
70+
if (ret < 0) {
71+
pr_err("failed to allocate unique device ID for Auxiliary driver\n");
72+
goto err_ida_alloc;
73+
}
74+
adev->id = ret;
75+
adev->dev.release = idpf_core_adev_release;
76+
adev->dev.parent = &cdev_info->pdev->dev;
77+
sprintf(name, "%04x.rdma.core", cdev_info->pdev->vendor);
78+
adev->name = name;
79+
80+
ret = auxiliary_device_init(adev);
81+
if (ret)
82+
goto err_aux_dev_init;
83+
84+
ret = auxiliary_device_add(adev);
85+
if (ret)
86+
goto err_aux_dev_add;
87+
88+
return 0;
89+
90+
err_aux_dev_add:
91+
auxiliary_device_uninit(adev);
92+
err_aux_dev_init:
93+
ida_free(&idpf_idc_ida, adev->id);
94+
err_ida_alloc:
95+
cdev_info->adev = NULL;
96+
kfree(iadev);
97+
98+
return ret;
99+
}
100+
101+
/**
102+
* idpf_unplug_aux_dev - unregister and free an Auxiliary device
103+
* @adev: auxiliary device struct
104+
*/
105+
static void idpf_unplug_aux_dev(struct auxiliary_device *adev)
106+
{
107+
auxiliary_device_delete(adev);
108+
auxiliary_device_uninit(adev);
109+
110+
ida_free(&idpf_idc_ida, adev->id);
111+
}
112+
113+
/**
114+
* idpf_idc_vport_dev_ctrl - Called by an Auxiliary Driver
115+
* @cdev_info: IDC core device info pointer
116+
* @up: RDMA core driver status
117+
*
118+
* This callback function is accessed by an Auxiliary Driver to indicate
119+
* whether core driver is ready to support vport driver load or if vport
120+
* drivers need to be taken down.
121+
*
122+
* Return: 0 on success or error code on failure.
123+
*/
124+
int idpf_idc_vport_dev_ctrl(struct iidc_rdma_core_dev_info *cdev_info, bool up)
125+
{
126+
return -EOPNOTSUPP;
127+
}
128+
EXPORT_SYMBOL_GPL(idpf_idc_vport_dev_ctrl);
129+
130+
/**
131+
* idpf_idc_request_reset - Called by an Auxiliary Driver
132+
* @cdev_info: IDC core device info pointer
133+
* @reset_type: function, core or other
134+
*
135+
* This callback function is accessed by an Auxiliary Driver to request a reset
136+
* on the Auxiliary Device.
137+
*
138+
* Return: 0 on success or error code on failure.
139+
*/
140+
int idpf_idc_request_reset(struct iidc_rdma_core_dev_info *cdev_info,
141+
enum iidc_rdma_reset_type __always_unused reset_type)
142+
{
143+
return -EOPNOTSUPP;
144+
}
145+
EXPORT_SYMBOL_GPL(idpf_idc_request_reset);
146+
147+
/**
148+
* idpf_idc_init_msix_data - initialize MSIX data for the cdev_info structure
149+
* @adapter: driver private data structure
150+
*/
151+
static void
152+
idpf_idc_init_msix_data(struct idpf_adapter *adapter)
153+
{
154+
struct iidc_rdma_core_dev_info *cdev_info;
155+
struct iidc_rdma_priv_dev_info *privd;
156+
157+
if (!adapter->rdma_msix_entries)
158+
return;
159+
160+
cdev_info = adapter->cdev_info;
161+
privd = cdev_info->iidc_priv;
162+
163+
privd->msix_entries = adapter->rdma_msix_entries;
164+
privd->msix_count = adapter->num_rdma_msix_entries;
165+
}
166+
167+
/**
168+
* idpf_idc_init_aux_core_dev - initialize Auxiliary Device(s)
169+
* @adapter: driver private data structure
170+
* @ftype: PF or VF
171+
*
172+
* Return: 0 on success or error code on failure.
173+
*/
174+
int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter,
175+
enum iidc_function_type ftype)
176+
{
177+
struct iidc_rdma_core_dev_info *cdev_info;
178+
struct iidc_rdma_priv_dev_info *privd;
179+
int err;
180+
181+
adapter->cdev_info = kzalloc(sizeof(*cdev_info), GFP_KERNEL);
182+
if (!adapter->cdev_info)
183+
return -ENOMEM;
184+
cdev_info = adapter->cdev_info;
185+
186+
privd = kzalloc(sizeof(*privd), GFP_KERNEL);
187+
if (!privd) {
188+
err = -ENOMEM;
189+
goto err_privd_alloc;
190+
}
191+
192+
cdev_info->iidc_priv = privd;
193+
cdev_info->pdev = adapter->pdev;
194+
cdev_info->rdma_protocol = IIDC_RDMA_PROTOCOL_ROCEV2;
195+
privd->ftype = ftype;
196+
197+
idpf_idc_init_msix_data(adapter);
198+
199+
err = idpf_plug_core_aux_dev(cdev_info);
200+
if (err)
201+
goto err_plug_aux_dev;
202+
203+
return 0;
204+
205+
err_plug_aux_dev:
206+
kfree(privd);
207+
err_privd_alloc:
208+
kfree(cdev_info);
209+
adapter->cdev_info = NULL;
210+
211+
return err;
212+
}
213+
214+
/**
215+
* idpf_idc_deinit_core_aux_device - de-initialize Auxiliary Device(s)
216+
* @cdev_info: IDC core device info pointer
217+
*/
218+
void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info)
219+
{
220+
if (!cdev_info)
221+
return;
222+
223+
idpf_unplug_aux_dev(cdev_info->adev);
224+
225+
kfree(cdev_info->iidc_priv);
226+
kfree(cdev_info);
227+
}

drivers/net/ethernet/intel/idpf/idpf_lib.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,10 @@ static int idpf_init_hard_reset(struct idpf_adapter *adapter)
18341834
unlock_mutex:
18351835
mutex_unlock(&adapter->vport_ctrl_lock);
18361836

1837+
/* Wait until all vports are created to init RDMA CORE AUX */
1838+
if (!err)
1839+
err = idpf_idc_init(adapter);
1840+
18371841
return err;
18381842
}
18391843

drivers/net/ethernet/intel/idpf/idpf_vf_dev.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ static void idpf_vf_trigger_reset(struct idpf_adapter *adapter,
147147
idpf_send_mb_msg(adapter, VIRTCHNL2_OP_RESET_VF, 0, NULL, 0);
148148
}
149149

150+
/**
151+
* idpf_idc_vf_register - register for IDC callbacks
152+
* @adapter: Driver specific private structure
153+
*
154+
* Return: 0 on success or error code on failure.
155+
*/
156+
static int idpf_idc_vf_register(struct idpf_adapter *adapter)
157+
{
158+
return idpf_idc_init_aux_core_dev(adapter, IIDC_FUNCTION_TYPE_VF);
159+
}
160+
150161
/**
151162
* idpf_vf_reg_ops_init - Initialize register API function pointers
152163
* @adapter: Driver specific private structure
@@ -167,4 +178,6 @@ static void idpf_vf_reg_ops_init(struct idpf_adapter *adapter)
167178
void idpf_vf_dev_ops_init(struct idpf_adapter *adapter)
168179
{
169180
idpf_vf_reg_ops_init(adapter);
181+
182+
adapter->dev_ops.idc_init = idpf_idc_vf_register;
170183
}

drivers/net/ethernet/intel/idpf/idpf_virtchnl.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/* Copyright (C) 2023 Intel Corporation */
33

4+
#include <linux/export.h>
45
#include <net/libeth/rx.h>
56

67
#include "idpf.h"
@@ -868,6 +869,7 @@ static int idpf_send_get_caps_msg(struct idpf_adapter *adapter)
868869

869870
caps.other_caps =
870871
cpu_to_le64(VIRTCHNL2_CAP_SRIOV |
872+
VIRTCHNL2_CAP_RDMA |
871873
VIRTCHNL2_CAP_MACFILTER |
872874
VIRTCHNL2_CAP_SPLITQ_QSCHED |
873875
VIRTCHNL2_CAP_PROMISC |
@@ -3070,6 +3072,7 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter)
30703072

30713073
idpf_ptp_release(adapter);
30723074
idpf_deinit_task(adapter);
3075+
idpf_idc_deinit_core_aux_device(adapter->cdev_info);
30733076
idpf_intr_rel(adapter);
30743077

30753078
if (remove_in_prog)
@@ -3728,3 +3731,21 @@ int idpf_set_promiscuous(struct idpf_adapter *adapter,
37283731

37293732
return reply_sz < 0 ? reply_sz : 0;
37303733
}
3734+
3735+
/**
3736+
* idpf_idc_rdma_vc_send_sync - virtchnl send callback for IDC registered drivers
3737+
* @cdev_info: IDC core device info pointer
3738+
* @send_msg: message to send
3739+
* @msg_size: size of message to send
3740+
* @recv_msg: message to populate on reception of response
3741+
* @recv_len: length of message copied into recv_msg or 0 on error
3742+
*
3743+
* Return: 0 on success or error code on failure.
3744+
*/
3745+
int idpf_idc_rdma_vc_send_sync(struct iidc_rdma_core_dev_info *cdev_info,
3746+
u8 *send_msg, u16 msg_size,
3747+
u8 *recv_msg, u16 *recv_len)
3748+
{
3749+
return -EOPNOTSUPP;
3750+
}
3751+
EXPORT_SYMBOL_GPL(idpf_idc_rdma_vc_send_sync);

0 commit comments

Comments
 (0)