1414#include "nic.h"
1515#include "mcdi_pcol.h"
1616
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 )
1819{
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 ;
2122
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 );
3030}
3131
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 )
3334{
34- struct pci_dev * dev = efx -> pci_dev ;
35+ MCDI_DECLARE_BUF ( inbuf , MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN ) ;
3536
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 );
4039
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 );
4742}
4843
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 )
5046{
51- return 0 ;
52- }
47+ MCDI_DECLARE_BUF (inbuf , MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN );
5348
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 );
5751
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 );
6454}
6555
6656static 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)
127117 NULL , 0 , NULL );
128118}
129119
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+
130231/* On top of the default firmware vswitch setup, create a VEB vswitch and
131232 * expansion vport for use by this function.
132233 */
133234int efx_ef10_vswitching_probe (struct efx_nic * efx )
134235{
135236 struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
237+ struct net_device * net_dev = efx -> net_dev ;
136238 int rc ;
137239
138240 if (pci_sriov_get_totalvfs (efx -> pci_dev ) <= 0 )
@@ -149,7 +251,16 @@ int efx_ef10_vswitching_probe(struct efx_nic *efx)
149251 if (rc )
150252 goto fail2 ;
151253
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+
152260 return 0 ;
261+ fail3 :
262+ efx_ef10_vport_free (efx , nic_data -> vport_id );
263+ nic_data -> vport_id = EVB_PORT_ID_ASSIGNED ;
153264fail2 :
154265 efx_ef10_vswitch_free (efx , EVB_PORT_ID_ASSIGNED );
155266fail1 :
@@ -165,21 +276,98 @@ int efx_ef10_vswitching_restore(struct efx_nic *efx)
165276 return 0 ;
166277
167278 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 ;
168285
169- if (! rc )
170- nic_data -> must_probe_vswitching = false;
286+ nic_data -> must_probe_vswitching = false;
287+ fail :
171288 return rc ;
172289}
173290
174291void efx_ef10_vswitching_remove (struct efx_nic * efx )
175292{
176293 struct efx_ef10_nic_data * nic_data = efx -> nic_data ;
177294
295+ efx_ef10_sriov_free_vf_vswitching (efx );
296+
178297 if (nic_data -> vport_id == EVB_PORT_ID_ASSIGNED )
179298 return ; /* No vswitch was ever created */
180299
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+ }
181305 efx_ef10_vport_free (efx , nic_data -> vport_id );
182306 nic_data -> vport_id = EVB_PORT_ID_ASSIGNED ;
183307
184308 efx_ef10_vswitch_free (efx , nic_data -> vport_id );
185309}
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