1 /****************************************************************************
2 * Driver for Solarflare network controllers and boards
3 * Copyright 2015 Solarflare Communications Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation, incorporated herein by reference.
10 #include <linux/module.h>
11 #include "net_driver.h"
12 #include "ef10_sriov.h"
15 #include "mcdi_pcol.h"
17 static int efx_ef10_evb_port_assign(struct efx_nic
*efx
, unsigned int port_id
,
20 MCDI_DECLARE_BUF(inbuf
, MC_CMD_EVB_PORT_ASSIGN_IN_LEN
);
21 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
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
);
28 return efx_mcdi_rpc(efx
, MC_CMD_EVB_PORT_ASSIGN
, inbuf
, sizeof(inbuf
),
32 static int efx_ef10_vport_add_mac(struct efx_nic
*efx
,
33 unsigned int port_id
, u8
*mac
)
35 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN
);
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 return efx_mcdi_rpc(efx
, MC_CMD_VPORT_ADD_MAC_ADDRESS
, inbuf
,
41 sizeof(inbuf
), NULL
, 0, NULL
);
44 static int efx_ef10_vport_del_mac(struct efx_nic
*efx
,
45 unsigned int port_id
, u8
*mac
)
47 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN
);
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
);
52 return efx_mcdi_rpc(efx
, MC_CMD_VPORT_DEL_MAC_ADDRESS
, inbuf
,
53 sizeof(inbuf
), NULL
, 0, NULL
);
56 static int efx_ef10_vswitch_alloc(struct efx_nic
*efx
, unsigned int port_id
,
57 unsigned int vswitch_type
)
59 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VSWITCH_ALLOC_IN_LEN
);
61 MCDI_SET_DWORD(inbuf
, VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID
, port_id
);
62 MCDI_SET_DWORD(inbuf
, VSWITCH_ALLOC_IN_TYPE
, vswitch_type
);
63 MCDI_SET_DWORD(inbuf
, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS
, 0);
64 MCDI_POPULATE_DWORD_1(inbuf
, VSWITCH_ALLOC_IN_FLAGS
,
65 VSWITCH_ALLOC_IN_FLAG_AUTO_PORT
, 0);
67 return efx_mcdi_rpc(efx
, MC_CMD_VSWITCH_ALLOC
, inbuf
, sizeof(inbuf
),
71 static int efx_ef10_vswitch_free(struct efx_nic
*efx
, unsigned int port_id
)
73 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VSWITCH_FREE_IN_LEN
);
75 MCDI_SET_DWORD(inbuf
, VSWITCH_FREE_IN_UPSTREAM_PORT_ID
, port_id
);
77 return efx_mcdi_rpc(efx
, MC_CMD_VSWITCH_FREE
, inbuf
, sizeof(inbuf
),
81 static int efx_ef10_vport_alloc(struct efx_nic
*efx
,
82 unsigned int port_id_in
,
83 unsigned int vport_type
,
84 unsigned int *port_id_out
)
86 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VPORT_ALLOC_IN_LEN
);
87 MCDI_DECLARE_BUF(outbuf
, MC_CMD_VPORT_ALLOC_OUT_LEN
);
91 EFX_WARN_ON_PARANOID(!port_id_out
);
93 MCDI_SET_DWORD(inbuf
, VPORT_ALLOC_IN_UPSTREAM_PORT_ID
, port_id_in
);
94 MCDI_SET_DWORD(inbuf
, VPORT_ALLOC_IN_TYPE
, vport_type
);
95 MCDI_SET_DWORD(inbuf
, VPORT_ALLOC_IN_NUM_VLAN_TAGS
, 0);
96 MCDI_POPULATE_DWORD_1(inbuf
, VPORT_ALLOC_IN_FLAGS
,
97 VPORT_ALLOC_IN_FLAG_AUTO_PORT
, 0);
99 rc
= efx_mcdi_rpc(efx
, MC_CMD_VPORT_ALLOC
, inbuf
, sizeof(inbuf
),
100 outbuf
, sizeof(outbuf
), &outlen
);
103 if (outlen
< MC_CMD_VPORT_ALLOC_OUT_LEN
)
106 *port_id_out
= MCDI_DWORD(outbuf
, VPORT_ALLOC_OUT_VPORT_ID
);
110 static int efx_ef10_vport_free(struct efx_nic
*efx
, unsigned int port_id
)
112 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VPORT_FREE_IN_LEN
);
114 MCDI_SET_DWORD(inbuf
, VPORT_FREE_IN_VPORT_ID
, port_id
);
116 return efx_mcdi_rpc(efx
, MC_CMD_VPORT_FREE
, inbuf
, sizeof(inbuf
),
120 static int efx_ef10_vadaptor_alloc(struct efx_nic
*efx
, unsigned int port_id
)
122 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VADAPTOR_ALLOC_IN_LEN
);
124 MCDI_SET_DWORD(inbuf
, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID
, port_id
);
125 return efx_mcdi_rpc(efx
, MC_CMD_VADAPTOR_ALLOC
, inbuf
, sizeof(inbuf
),
129 static int efx_ef10_vadaptor_free(struct efx_nic
*efx
, unsigned int port_id
)
131 MCDI_DECLARE_BUF(inbuf
, MC_CMD_VADAPTOR_FREE_IN_LEN
);
133 MCDI_SET_DWORD(inbuf
, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID
, port_id
);
134 return efx_mcdi_rpc(efx
, MC_CMD_VADAPTOR_FREE
, inbuf
, sizeof(inbuf
),
138 static void efx_ef10_sriov_free_vf_vports(struct efx_nic
*efx
)
140 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
146 for (i
= 0; i
< efx
->vf_count
; i
++) {
147 struct ef10_vf
*vf
= nic_data
->vf
+ i
;
149 if (vf
->vport_assigned
) {
150 efx_ef10_evb_port_assign(efx
, EVB_PORT_ID_NULL
, i
);
151 vf
->vport_assigned
= 0;
154 if (!is_zero_ether_addr(vf
->mac
)) {
155 efx_ef10_vport_del_mac(efx
, vf
->vport_id
, vf
->mac
);
156 eth_zero_addr(vf
->mac
);
160 efx_ef10_vport_free(efx
, vf
->vport_id
);
166 static void efx_ef10_sriov_free_vf_vswitching(struct efx_nic
*efx
)
168 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
170 efx_ef10_sriov_free_vf_vports(efx
);
175 static int efx_ef10_sriov_assign_vf_vport(struct efx_nic
*efx
,
178 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
179 struct ef10_vf
*vf
= nic_data
->vf
+ vf_i
;
182 if (WARN_ON_ONCE(!nic_data
->vf
))
185 rc
= efx_ef10_vport_alloc(efx
, EVB_PORT_ID_ASSIGNED
,
186 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL
,
191 rc
= efx_ef10_vport_add_mac(efx
, vf
->vport_id
, vf
->mac
);
193 eth_zero_addr(vf
->mac
);
197 rc
= efx_ef10_evb_port_assign(efx
, vf
->vport_id
, vf_i
);
201 vf
->vport_assigned
= 1;
205 static int efx_ef10_sriov_alloc_vf_vswitching(struct efx_nic
*efx
)
207 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
211 nic_data
->vf
= kcalloc(efx
->vf_count
, sizeof(struct ef10_vf
),
216 for (i
= 0; i
< efx
->vf_count
; i
++) {
217 random_ether_addr(nic_data
->vf
[i
].mac
);
219 rc
= efx_ef10_sriov_assign_vf_vport(efx
, i
);
226 efx_ef10_sriov_free_vf_vports(efx
);
232 static int efx_ef10_sriov_restore_vf_vswitching(struct efx_nic
*efx
)
237 for (i
= 0; i
< efx
->vf_count
; i
++) {
238 rc
= efx_ef10_sriov_assign_vf_vport(efx
, i
);
245 efx_ef10_sriov_free_vf_vswitching(efx
);
249 /* On top of the default firmware vswitch setup, create a VEB vswitch and
250 * expansion vport for use by this function.
252 int efx_ef10_vswitching_probe_pf(struct efx_nic
*efx
)
254 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
255 struct net_device
*net_dev
= efx
->net_dev
;
258 if (pci_sriov_get_totalvfs(efx
->pci_dev
) <= 0) {
259 /* vswitch not needed as we have no VFs */
260 efx_ef10_vadaptor_alloc(efx
, nic_data
->vport_id
);
264 rc
= efx_ef10_vswitch_alloc(efx
, EVB_PORT_ID_ASSIGNED
,
265 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB
);
269 rc
= efx_ef10_vport_alloc(efx
, EVB_PORT_ID_ASSIGNED
,
270 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL
,
271 &nic_data
->vport_id
);
275 rc
= efx_ef10_vport_add_mac(efx
, nic_data
->vport_id
, net_dev
->dev_addr
);
278 ether_addr_copy(nic_data
->vport_mac
, net_dev
->dev_addr
);
280 rc
= efx_ef10_vadaptor_alloc(efx
, nic_data
->vport_id
);
286 efx_ef10_vport_del_mac(efx
, nic_data
->vport_id
, nic_data
->vport_mac
);
287 eth_zero_addr(nic_data
->vport_mac
);
289 efx_ef10_vport_free(efx
, nic_data
->vport_id
);
290 nic_data
->vport_id
= EVB_PORT_ID_ASSIGNED
;
292 efx_ef10_vswitch_free(efx
, EVB_PORT_ID_ASSIGNED
);
297 int efx_ef10_vswitching_probe_vf(struct efx_nic
*efx
)
299 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
301 return efx_ef10_vadaptor_alloc(efx
, nic_data
->vport_id
);
304 int efx_ef10_vswitching_restore_pf(struct efx_nic
*efx
)
306 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
309 if (!nic_data
->must_probe_vswitching
)
312 rc
= efx_ef10_vswitching_probe_pf(efx
);
316 rc
= efx_ef10_sriov_restore_vf_vswitching(efx
);
320 nic_data
->must_probe_vswitching
= false;
325 int efx_ef10_vswitching_restore_vf(struct efx_nic
*efx
)
327 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
330 if (!nic_data
->must_probe_vswitching
)
333 rc
= efx_ef10_vadaptor_free(efx
, EVB_PORT_ID_ASSIGNED
);
337 nic_data
->must_probe_vswitching
= false;
341 void efx_ef10_vswitching_remove_pf(struct efx_nic
*efx
)
343 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
345 efx_ef10_sriov_free_vf_vswitching(efx
);
347 efx_ef10_vadaptor_free(efx
, nic_data
->vport_id
);
349 if (nic_data
->vport_id
== EVB_PORT_ID_ASSIGNED
)
350 return; /* No vswitch was ever created */
352 if (!is_zero_ether_addr(nic_data
->vport_mac
)) {
353 efx_ef10_vport_del_mac(efx
, nic_data
->vport_id
,
354 efx
->net_dev
->dev_addr
);
355 eth_zero_addr(nic_data
->vport_mac
);
357 efx_ef10_vport_free(efx
, nic_data
->vport_id
);
358 nic_data
->vport_id
= EVB_PORT_ID_ASSIGNED
;
360 efx_ef10_vswitch_free(efx
, nic_data
->vport_id
);
363 void efx_ef10_vswitching_remove_vf(struct efx_nic
*efx
)
365 efx_ef10_vadaptor_free(efx
, EVB_PORT_ID_ASSIGNED
);
368 static int efx_ef10_pci_sriov_enable(struct efx_nic
*efx
, int num_vfs
)
371 struct pci_dev
*dev
= efx
->pci_dev
;
373 efx
->vf_count
= num_vfs
;
375 rc
= efx_ef10_sriov_alloc_vf_vswitching(efx
);
379 rc
= pci_enable_sriov(dev
, num_vfs
);
385 efx_ef10_sriov_free_vf_vswitching(efx
);
388 netif_err(efx
, probe
, efx
->net_dev
,
389 "Failed to enable SRIOV VFs\n");
393 static int efx_ef10_pci_sriov_disable(struct efx_nic
*efx
)
395 struct pci_dev
*dev
= efx
->pci_dev
;
397 pci_disable_sriov(dev
);
398 efx_ef10_sriov_free_vf_vswitching(efx
);
403 int efx_ef10_sriov_configure(struct efx_nic
*efx
, int num_vfs
)
406 return efx_ef10_pci_sriov_disable(efx
);
408 return efx_ef10_pci_sriov_enable(efx
, num_vfs
);
411 int efx_ef10_sriov_init(struct efx_nic
*efx
)
416 void efx_ef10_sriov_fini(struct efx_nic
*efx
)
418 struct efx_ef10_nic_data
*nic_data
= efx
->nic_data
;
424 rc
= efx_ef10_pci_sriov_disable(efx
);
426 netif_dbg(efx
, drv
, efx
->net_dev
,
427 "Disabling SRIOV was not successful rc=%d\n", rc
);
429 netif_dbg(efx
, drv
, efx
->net_dev
, "SRIOV disabled\n");