14
14
#include "nic.h"
15
15
#include "mcdi_pcol.h"
16
16
17
- static int efx_ef10_pci_sriov_enable (struct efx_nic * efx , int num_vfs )
17
+ static int efx_ef10_evb_port_assign (struct efx_nic * efx , unsigned int port_id ,
18
+ unsigned int vf_fn )
18
19
{
19
- int rc = 0 ;
20
- struct pci_dev * dev = efx -> pci_dev ;
20
+ MCDI_DECLARE_BUF ( inbuf , MC_CMD_EVB_PORT_ASSIGN_IN_LEN ) ;
21
+ struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
21
22
22
- efx -> vf_count = num_vfs ;
23
- rc = pci_enable_sriov (dev , num_vfs );
24
- if (rc ) {
25
- efx -> vf_count = 0 ;
26
- netif_err (efx , probe , efx -> net_dev ,
27
- "Failed to enable SRIOV VFs\n" );
28
- }
29
- return rc ;
23
+ MCDI_SET_DWORD (inbuf , EVB_PORT_ASSIGN_IN_PORT_ID , port_id );
24
+ MCDI_POPULATE_DWORD_2 (inbuf , EVB_PORT_ASSIGN_IN_FUNCTION ,
25
+ EVB_PORT_ASSIGN_IN_PF , nic_data -> pf_index ,
26
+ EVB_PORT_ASSIGN_IN_VF , vf_fn );
27
+
28
+ return efx_mcdi_rpc (efx , MC_CMD_EVB_PORT_ASSIGN , inbuf , sizeof (inbuf ),
29
+ NULL , 0 , NULL );
30
30
}
31
31
32
- static int efx_ef10_pci_sriov_disable (struct efx_nic * efx )
32
+ static int efx_ef10_vport_add_mac (struct efx_nic * efx ,
33
+ unsigned int port_id , u8 * mac )
33
34
{
34
- struct pci_dev * dev = efx -> pci_dev ;
35
+ MCDI_DECLARE_BUF ( inbuf , MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN ) ;
35
36
36
- efx -> vf_count = 0 ;
37
- pci_disable_sriov (dev );
38
- return 0 ;
39
- }
37
+ MCDI_SET_DWORD (inbuf , VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID , port_id );
38
+ ether_addr_copy (MCDI_PTR (inbuf , VPORT_ADD_MAC_ADDRESS_IN_MACADDR ), mac );
40
39
41
- int efx_ef10_sriov_configure (struct efx_nic * efx , int num_vfs )
42
- {
43
- if (num_vfs == 0 )
44
- return efx_ef10_pci_sriov_disable (efx );
45
- else
46
- return efx_ef10_pci_sriov_enable (efx , num_vfs );
40
+ return efx_mcdi_rpc (efx , MC_CMD_VPORT_ADD_MAC_ADDRESS , inbuf ,
41
+ sizeof (inbuf ), NULL , 0 , NULL );
47
42
}
48
43
49
- int efx_ef10_sriov_init (struct efx_nic * efx )
44
+ static int efx_ef10_vport_del_mac (struct efx_nic * efx ,
45
+ unsigned int port_id , u8 * mac )
50
46
{
51
- return 0 ;
52
- }
47
+ MCDI_DECLARE_BUF (inbuf , MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN );
53
48
54
- void efx_ef10_sriov_fini (struct efx_nic * efx )
55
- {
56
- int rc ;
49
+ MCDI_SET_DWORD (inbuf , VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID , port_id );
50
+ ether_addr_copy (MCDI_PTR (inbuf , VPORT_DEL_MAC_ADDRESS_IN_MACADDR ), mac );
57
51
58
- rc = efx_ef10_pci_sriov_disable (efx );
59
- if (rc )
60
- netif_dbg (efx , drv , efx -> net_dev ,
61
- "Disabling SRIOV was not successful rc=%d\n" , rc );
62
- else
63
- netif_dbg (efx , drv , efx -> net_dev , "SRIOV disabled\n" );
52
+ return efx_mcdi_rpc (efx , MC_CMD_VPORT_DEL_MAC_ADDRESS , inbuf ,
53
+ sizeof (inbuf ), NULL , 0 , NULL );
64
54
}
65
55
66
56
static int efx_ef10_vswitch_alloc (struct efx_nic * efx , unsigned int port_id ,
@@ -127,12 +117,124 @@ static int efx_ef10_vport_free(struct efx_nic *efx, unsigned int port_id)
127
117
NULL , 0 , NULL );
128
118
}
129
119
120
+ static void efx_ef10_sriov_free_vf_vports (struct efx_nic * efx )
121
+ {
122
+ struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
123
+ int i ;
124
+
125
+ if (!nic_data -> vf )
126
+ return ;
127
+
128
+ for (i = 0 ; i < efx -> vf_count ; i ++ ) {
129
+ struct ef10_vf * vf = nic_data -> vf + i ;
130
+
131
+ if (vf -> vport_assigned ) {
132
+ efx_ef10_evb_port_assign (efx , EVB_PORT_ID_NULL , i );
133
+ vf -> vport_assigned = 0 ;
134
+ }
135
+
136
+ if (!is_zero_ether_addr (vf -> mac )) {
137
+ efx_ef10_vport_del_mac (efx , vf -> vport_id , vf -> mac );
138
+ eth_zero_addr (vf -> mac );
139
+ }
140
+
141
+ if (vf -> vport_id ) {
142
+ efx_ef10_vport_free (efx , vf -> vport_id );
143
+ vf -> vport_id = 0 ;
144
+ }
145
+ }
146
+ }
147
+
148
+ static void efx_ef10_sriov_free_vf_vswitching (struct efx_nic * efx )
149
+ {
150
+ struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
151
+
152
+ efx_ef10_sriov_free_vf_vports (efx );
153
+ kfree (nic_data -> vf );
154
+ nic_data -> vf = NULL ;
155
+ }
156
+
157
+ static int efx_ef10_sriov_assign_vf_vport (struct efx_nic * efx ,
158
+ unsigned int vf_i )
159
+ {
160
+ struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
161
+ struct ef10_vf * vf = nic_data -> vf + vf_i ;
162
+ int rc ;
163
+
164
+ if (WARN_ON_ONCE (!nic_data -> vf ))
165
+ return - EOPNOTSUPP ;
166
+
167
+ rc = efx_ef10_vport_alloc (efx , EVB_PORT_ID_ASSIGNED ,
168
+ MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL ,
169
+ & vf -> vport_id );
170
+ if (rc )
171
+ return rc ;
172
+
173
+ rc = efx_ef10_vport_add_mac (efx , vf -> vport_id , vf -> mac );
174
+ if (rc ) {
175
+ eth_zero_addr (vf -> mac );
176
+ return rc ;
177
+ }
178
+
179
+ rc = efx_ef10_evb_port_assign (efx , vf -> vport_id , vf_i );
180
+ if (rc )
181
+ return rc ;
182
+
183
+ vf -> vport_assigned = 1 ;
184
+ return 0 ;
185
+ }
186
+
187
+ static int efx_ef10_sriov_alloc_vf_vswitching (struct efx_nic * efx )
188
+ {
189
+ struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
190
+ unsigned int i ;
191
+ int rc ;
192
+
193
+ nic_data -> vf = kcalloc (efx -> vf_count , sizeof (struct ef10_vf ),
194
+ GFP_KERNEL );
195
+ if (!nic_data -> vf )
196
+ return - ENOMEM ;
197
+
198
+ for (i = 0 ; i < efx -> vf_count ; i ++ ) {
199
+ random_ether_addr (nic_data -> vf [i ].mac );
200
+
201
+ rc = efx_ef10_sriov_assign_vf_vport (efx , i );
202
+ if (rc )
203
+ goto fail ;
204
+ }
205
+
206
+ return 0 ;
207
+ fail :
208
+ efx_ef10_sriov_free_vf_vports (efx );
209
+ kfree (nic_data -> vf );
210
+ nic_data -> vf = NULL ;
211
+ return rc ;
212
+ }
213
+
214
+ static int efx_ef10_sriov_restore_vf_vswitching (struct efx_nic * efx )
215
+ {
216
+ unsigned int i ;
217
+ int rc ;
218
+
219
+ for (i = 0 ; i < efx -> vf_count ; i ++ ) {
220
+ rc = efx_ef10_sriov_assign_vf_vport (efx , i );
221
+ if (rc )
222
+ goto fail ;
223
+ }
224
+
225
+ return 0 ;
226
+ fail :
227
+ efx_ef10_sriov_free_vf_vswitching (efx );
228
+ return rc ;
229
+ }
230
+
130
231
/* On top of the default firmware vswitch setup, create a VEB vswitch and
131
232
* expansion vport for use by this function.
132
233
*/
133
234
int efx_ef10_vswitching_probe (struct efx_nic * efx )
134
235
{
135
236
struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
237
+ struct net_device * net_dev = efx -> net_dev ;
136
238
int rc ;
137
239
138
240
if (pci_sriov_get_totalvfs (efx -> pci_dev ) <= 0 )
@@ -149,7 +251,16 @@ int efx_ef10_vswitching_probe(struct efx_nic *efx)
149
251
if (rc )
150
252
goto fail2 ;
151
253
254
+ rc = efx_ef10_vport_add_mac (efx , nic_data -> vport_id , net_dev -> dev_addr );
255
+ if (rc )
256
+ goto fail3 ;
257
+
258
+ ether_addr_copy (nic_data -> vport_mac , net_dev -> dev_addr );
259
+
152
260
return 0 ;
261
+ fail3 :
262
+ efx_ef10_vport_free (efx , nic_data -> vport_id );
263
+ nic_data -> vport_id = EVB_PORT_ID_ASSIGNED ;
153
264
fail2 :
154
265
efx_ef10_vswitch_free (efx , EVB_PORT_ID_ASSIGNED );
155
266
fail1 :
@@ -165,21 +276,98 @@ int efx_ef10_vswitching_restore(struct efx_nic *efx)
165
276
return 0 ;
166
277
167
278
rc = efx_ef10_vswitching_probe (efx );
279
+ if (rc )
280
+ goto fail ;
281
+
282
+ rc = efx_ef10_sriov_restore_vf_vswitching (efx );
283
+ if (rc )
284
+ goto fail ;
168
285
169
- if (! rc )
170
- nic_data -> must_probe_vswitching = false;
286
+ nic_data -> must_probe_vswitching = false;
287
+ fail :
171
288
return rc ;
172
289
}
173
290
174
291
void efx_ef10_vswitching_remove (struct efx_nic * efx )
175
292
{
176
293
struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
177
294
295
+ efx_ef10_sriov_free_vf_vswitching (efx );
296
+
178
297
if (nic_data -> vport_id == EVB_PORT_ID_ASSIGNED )
179
298
return ; /* No vswitch was ever created */
180
299
300
+ if (!is_zero_ether_addr (nic_data -> vport_mac )) {
301
+ efx_ef10_vport_del_mac (efx , nic_data -> vport_id ,
302
+ efx -> net_dev -> dev_addr );
303
+ eth_zero_addr (nic_data -> vport_mac );
304
+ }
181
305
efx_ef10_vport_free (efx , nic_data -> vport_id );
182
306
nic_data -> vport_id = EVB_PORT_ID_ASSIGNED ;
183
307
184
308
efx_ef10_vswitch_free (efx , nic_data -> vport_id );
185
309
}
310
+
311
+ static int efx_ef10_pci_sriov_enable (struct efx_nic * efx , int num_vfs )
312
+ {
313
+ int rc = 0 ;
314
+ struct pci_dev * dev = efx -> pci_dev ;
315
+
316
+ efx -> vf_count = num_vfs ;
317
+
318
+ rc = efx_ef10_sriov_alloc_vf_vswitching (efx );
319
+ if (rc )
320
+ goto fail1 ;
321
+
322
+ rc = pci_enable_sriov (dev , num_vfs );
323
+ if (rc )
324
+ goto fail2 ;
325
+
326
+ return 0 ;
327
+ fail2 :
328
+ efx_ef10_sriov_free_vf_vswitching (efx );
329
+ fail1 :
330
+ efx -> vf_count = 0 ;
331
+ netif_err (efx , probe , efx -> net_dev ,
332
+ "Failed to enable SRIOV VFs\n" );
333
+ return rc ;
334
+ }
335
+
336
+ static int efx_ef10_pci_sriov_disable (struct efx_nic * efx )
337
+ {
338
+ struct pci_dev * dev = efx -> pci_dev ;
339
+
340
+ pci_disable_sriov (dev );
341
+ efx_ef10_sriov_free_vf_vswitching (efx );
342
+ efx -> vf_count = 0 ;
343
+ return 0 ;
344
+ }
345
+
346
+ int efx_ef10_sriov_configure (struct efx_nic * efx , int num_vfs )
347
+ {
348
+ if (num_vfs == 0 )
349
+ return efx_ef10_pci_sriov_disable (efx );
350
+ else
351
+ return efx_ef10_pci_sriov_enable (efx , num_vfs );
352
+ }
353
+
354
+ int efx_ef10_sriov_init (struct efx_nic * efx )
355
+ {
356
+ return 0 ;
357
+ }
358
+
359
+ void efx_ef10_sriov_fini (struct efx_nic * efx )
360
+ {
361
+ struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
362
+ int rc ;
363
+
364
+ if (!nic_data -> vf )
365
+ return ;
366
+
367
+ rc = efx_ef10_pci_sriov_disable (efx );
368
+ if (rc )
369
+ netif_dbg (efx , drv , efx -> net_dev ,
370
+ "Disabling SRIOV was not successful rc=%d\n" , rc );
371
+ else
372
+ netif_dbg (efx , drv , efx -> net_dev , "SRIOV disabled\n" );
373
+ }
0 commit comments