@@ -32,6 +32,115 @@ int idpf_idc_init(struct idpf_adapter *adapter)
32
32
return err ;
33
33
}
34
34
35
+ /**
36
+ * idpf_vport_adev_release - function to be mapped to aux dev's release op
37
+ * @dev: pointer to device to free
38
+ */
39
+ static void idpf_vport_adev_release (struct device * dev )
40
+ {
41
+ struct iidc_rdma_vport_auxiliary_dev * iadev ;
42
+
43
+ iadev = container_of (dev , struct iidc_rdma_vport_auxiliary_dev , adev .dev );
44
+ kfree (iadev );
45
+ iadev = NULL ;
46
+ }
47
+
48
+ /**
49
+ * idpf_plug_vport_aux_dev - allocate and register a vport Auxiliary device
50
+ * @cdev_info: IDC core device info pointer
51
+ * @vdev_info: IDC vport device info pointer
52
+ *
53
+ * Return: 0 on success or error code on failure.
54
+ */
55
+ static int idpf_plug_vport_aux_dev (struct iidc_rdma_core_dev_info * cdev_info ,
56
+ struct iidc_rdma_vport_dev_info * vdev_info )
57
+ {
58
+ struct iidc_rdma_vport_auxiliary_dev * iadev ;
59
+ char name [IDPF_IDC_MAX_ADEV_NAME_LEN ];
60
+ struct auxiliary_device * adev ;
61
+ int ret ;
62
+
63
+ iadev = kzalloc (sizeof (* iadev ), GFP_KERNEL );
64
+ if (!iadev )
65
+ return - ENOMEM ;
66
+
67
+ adev = & iadev -> adev ;
68
+ vdev_info -> adev = & iadev -> adev ;
69
+ iadev -> vdev_info = vdev_info ;
70
+
71
+ ret = ida_alloc (& idpf_idc_ida , GFP_KERNEL );
72
+ if (ret < 0 ) {
73
+ pr_err ("failed to allocate unique device ID for Auxiliary driver\n" );
74
+ goto err_ida_alloc ;
75
+ }
76
+ adev -> id = ret ;
77
+ adev -> dev .release = idpf_vport_adev_release ;
78
+ adev -> dev .parent = & cdev_info -> pdev -> dev ;
79
+ sprintf (name , "%04x.rdma.vdev" , cdev_info -> pdev -> vendor );
80
+ adev -> name = name ;
81
+
82
+ ret = auxiliary_device_init (adev );
83
+ if (ret )
84
+ goto err_aux_dev_init ;
85
+
86
+ ret = auxiliary_device_add (adev );
87
+ if (ret )
88
+ goto err_aux_dev_add ;
89
+
90
+ return 0 ;
91
+
92
+ err_aux_dev_add :
93
+ auxiliary_device_uninit (adev );
94
+ err_aux_dev_init :
95
+ ida_free (& idpf_idc_ida , adev -> id );
96
+ err_ida_alloc :
97
+ vdev_info -> adev = NULL ;
98
+ kfree (iadev );
99
+
100
+ return ret ;
101
+ }
102
+
103
+ /**
104
+ * idpf_idc_init_aux_vport_dev - initialize vport Auxiliary Device(s)
105
+ * @vport: virtual port data struct
106
+ *
107
+ * Return: 0 on success or error code on failure.
108
+ */
109
+ static int idpf_idc_init_aux_vport_dev (struct idpf_vport * vport )
110
+ {
111
+ struct idpf_adapter * adapter = vport -> adapter ;
112
+ struct iidc_rdma_vport_dev_info * vdev_info ;
113
+ struct iidc_rdma_core_dev_info * cdev_info ;
114
+ struct virtchnl2_create_vport * vport_msg ;
115
+ int err ;
116
+
117
+ vport_msg = (struct virtchnl2_create_vport * )
118
+ adapter -> vport_params_recvd [vport -> idx ];
119
+
120
+ if (!(le16_to_cpu (vport_msg -> vport_flags ) & VIRTCHNL2_VPORT_ENABLE_RDMA ))
121
+ return 0 ;
122
+
123
+ vport -> vdev_info = kzalloc (sizeof (* vdev_info ), GFP_KERNEL );
124
+ if (!vport -> vdev_info )
125
+ return - ENOMEM ;
126
+
127
+ cdev_info = vport -> adapter -> cdev_info ;
128
+
129
+ vdev_info = vport -> vdev_info ;
130
+ vdev_info -> vport_id = vport -> vport_id ;
131
+ vdev_info -> netdev = vport -> netdev ;
132
+ vdev_info -> core_adev = cdev_info -> adev ;
133
+
134
+ err = idpf_plug_vport_aux_dev (cdev_info , vdev_info );
135
+ if (err ) {
136
+ vport -> vdev_info = NULL ;
137
+ kfree (vdev_info );
138
+ return err ;
139
+ }
140
+
141
+ return 0 ;
142
+ }
143
+
35
144
/**
36
145
* idpf_core_adev_release - function to be mapped to aux dev's release op
37
146
* @dev: pointer to device to free
@@ -104,12 +213,60 @@ static int idpf_plug_core_aux_dev(struct iidc_rdma_core_dev_info *cdev_info)
104
213
*/
105
214
static void idpf_unplug_aux_dev (struct auxiliary_device * adev )
106
215
{
216
+ if (!adev )
217
+ return ;
218
+
107
219
auxiliary_device_delete (adev );
108
220
auxiliary_device_uninit (adev );
109
221
110
222
ida_free (& idpf_idc_ida , adev -> id );
111
223
}
112
224
225
+ /**
226
+ * idpf_idc_vport_dev_up - called when CORE is ready for vport aux devs
227
+ * @adapter: private data struct
228
+ *
229
+ * Return: 0 on success or error code on failure.
230
+ */
231
+ static int idpf_idc_vport_dev_up (struct idpf_adapter * adapter )
232
+ {
233
+ int i , err = 0 ;
234
+
235
+ for (i = 0 ; i < adapter -> num_alloc_vports ; i ++ ) {
236
+ struct idpf_vport * vport = adapter -> vports [i ];
237
+
238
+ if (!vport )
239
+ continue ;
240
+
241
+ if (!vport -> vdev_info )
242
+ err = idpf_idc_init_aux_vport_dev (vport );
243
+ else
244
+ err = idpf_plug_vport_aux_dev (vport -> adapter -> cdev_info ,
245
+ vport -> vdev_info );
246
+ }
247
+
248
+ return err ;
249
+ }
250
+
251
+ /**
252
+ * idpf_idc_vport_dev_down - called CORE is leaving vport aux dev support state
253
+ * @adapter: private data struct
254
+ */
255
+ static void idpf_idc_vport_dev_down (struct idpf_adapter * adapter )
256
+ {
257
+ int i ;
258
+
259
+ for (i = 0 ; i < adapter -> num_alloc_vports ; i ++ ) {
260
+ struct idpf_vport * vport = adapter -> vports [i ];
261
+
262
+ if (!vport )
263
+ continue ;
264
+
265
+ idpf_unplug_aux_dev (vport -> vdev_info -> adev );
266
+ vport -> vdev_info -> adev = NULL ;
267
+ }
268
+ }
269
+
113
270
/**
114
271
* idpf_idc_vport_dev_ctrl - Called by an Auxiliary Driver
115
272
* @cdev_info: IDC core device info pointer
@@ -123,7 +280,14 @@ static void idpf_unplug_aux_dev(struct auxiliary_device *adev)
123
280
*/
124
281
int idpf_idc_vport_dev_ctrl (struct iidc_rdma_core_dev_info * cdev_info , bool up )
125
282
{
126
- return - EOPNOTSUPP ;
283
+ struct idpf_adapter * adapter = pci_get_drvdata (cdev_info -> pdev );
284
+
285
+ if (up )
286
+ return idpf_idc_vport_dev_up (adapter );
287
+
288
+ idpf_idc_vport_dev_down (adapter );
289
+
290
+ return 0 ;
127
291
}
128
292
EXPORT_SYMBOL_GPL (idpf_idc_vport_dev_ctrl );
129
293
@@ -225,3 +389,17 @@ void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info)
225
389
kfree (cdev_info -> iidc_priv );
226
390
kfree (cdev_info );
227
391
}
392
+
393
+ /**
394
+ * idpf_idc_deinit_vport_aux_device - de-initialize Auxiliary Device(s)
395
+ * @vdev_info: IDC vport device info pointer
396
+ */
397
+ void idpf_idc_deinit_vport_aux_device (struct iidc_rdma_vport_dev_info * vdev_info )
398
+ {
399
+ if (!vdev_info )
400
+ return ;
401
+
402
+ idpf_unplug_aux_dev (vdev_info -> adev );
403
+
404
+ kfree (vdev_info );
405
+ }
0 commit comments