Commit 25414b2a authored by Alejandro Lucero's avatar Alejandro Lucero Committed by Paolo Abeni

sfc: add devlink port support for ef100

Using the data when enumerating mports, create devlink ports just before
netdevs are registered and remove those devlink ports after netdev has
been unregistered.
Signed-off-by: default avatarAlejandro Lucero <alejandro.lucero-palau@amd.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Acked-by: default avatarMartin Habets <habetsm.xilinx@gmail.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 5227adff
...@@ -337,6 +337,7 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data) ...@@ -337,6 +337,7 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)
ef100_unregister_netdev(efx); ef100_unregister_netdev(efx);
#ifdef CONFIG_SFC_SRIOV #ifdef CONFIG_SFC_SRIOV
ef100_pf_unset_devlink_port(efx);
efx_fini_tc(efx); efx_fini_tc(efx);
#endif #endif
...@@ -422,6 +423,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data) ...@@ -422,6 +423,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
rc = ef100_probe_netdev_pf(efx); rc = ef100_probe_netdev_pf(efx);
if (rc) if (rc)
goto fail; goto fail;
#ifdef CONFIG_SFC_SRIOV
ef100_pf_set_devlink_port(efx);
#endif
} }
efx->netdev_notifier.notifier_call = ef100_netdev_event; efx->netdev_notifier.notifier_call = ef100_netdev_event;
...@@ -432,7 +436,13 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data) ...@@ -432,7 +436,13 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
goto fail; goto fail;
} }
efx_probe_devlink_unlock(efx);
return rc;
fail: fail:
#ifdef CONFIG_SFC_SRIOV
/* remove devlink port if does exist */
ef100_pf_unset_devlink_port(efx);
#endif
efx_probe_devlink_unlock(efx); efx_probe_devlink_unlock(efx);
return rc; return rc;
} }
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "mae.h" #include "mae.h"
#include "rx_common.h" #include "rx_common.h"
#include "tc_bindings.h" #include "tc_bindings.h"
#include "efx_devlink.h"
#define EFX_EF100_REP_DRIVER "efx_ef100_rep" #define EFX_EF100_REP_DRIVER "efx_ef100_rep"
...@@ -297,6 +298,7 @@ int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i) ...@@ -297,6 +298,7 @@ int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
i, rc); i, rc);
goto fail1; goto fail1;
} }
ef100_rep_set_devlink_port(efv);
rc = register_netdev(efv->net_dev); rc = register_netdev(efv->net_dev);
if (rc) { if (rc) {
pci_err(efx->pci_dev, pci_err(efx->pci_dev,
...@@ -308,6 +310,7 @@ int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i) ...@@ -308,6 +310,7 @@ int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
efv->net_dev->name); efv->net_dev->name);
return 0; return 0;
fail2: fail2:
ef100_rep_unset_devlink_port(efv);
efx_ef100_deconfigure_rep(efv); efx_ef100_deconfigure_rep(efv);
fail1: fail1:
efx_ef100_rep_destroy_netdev(efv); efx_ef100_rep_destroy_netdev(efv);
...@@ -323,6 +326,7 @@ void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv) ...@@ -323,6 +326,7 @@ void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv)
return; return;
netif_dbg(efx, drv, rep_dev, "Removing VF representor\n"); netif_dbg(efx, drv, rep_dev, "Removing VF representor\n");
unregister_netdev(rep_dev); unregister_netdev(rep_dev);
ef100_rep_unset_devlink_port(efv);
efx_ef100_deconfigure_rep(efv); efx_ef100_deconfigure_rep(efv);
efx_ef100_rep_destroy_netdev(efv); efx_ef100_rep_destroy_netdev(efv);
} }
...@@ -339,6 +343,24 @@ void efx_ef100_fini_vfreps(struct efx_nic *efx) ...@@ -339,6 +343,24 @@ void efx_ef100_fini_vfreps(struct efx_nic *efx)
efx_ef100_vfrep_destroy(efx, efv); efx_ef100_vfrep_destroy(efx, efv);
} }
static bool ef100_mport_is_pcie_vnic(struct mae_mport_desc *mport_desc)
{
return mport_desc->mport_type == MAE_MPORT_DESC_MPORT_TYPE_VNIC &&
mport_desc->vnic_client_type == MAE_MPORT_DESC_VNIC_CLIENT_TYPE_FUNCTION;
}
bool ef100_mport_on_local_intf(struct efx_nic *efx,
struct mae_mport_desc *mport_desc)
{
struct ef100_nic_data *nic_data = efx->nic_data;
bool pcie_func;
pcie_func = ef100_mport_is_pcie_vnic(mport_desc);
return nic_data->have_local_intf && pcie_func &&
mport_desc->interface_idx == nic_data->local_mae_intf;
}
void efx_ef100_init_reps(struct efx_nic *efx) void efx_ef100_init_reps(struct efx_nic *efx)
{ {
struct ef100_nic_data *nic_data = efx->nic_data; struct ef100_nic_data *nic_data = efx->nic_data;
......
...@@ -22,6 +22,8 @@ struct efx_rep_sw_stats { ...@@ -22,6 +22,8 @@ struct efx_rep_sw_stats {
atomic64_t rx_dropped, tx_errors; atomic64_t rx_dropped, tx_errors;
}; };
struct devlink_port;
/** /**
* struct efx_rep - Private data for an Efx representor * struct efx_rep - Private data for an Efx representor
* *
...@@ -39,6 +41,7 @@ struct efx_rep_sw_stats { ...@@ -39,6 +41,7 @@ struct efx_rep_sw_stats {
* @rx_lock: protects @rx_list * @rx_lock: protects @rx_list
* @napi: NAPI control structure * @napi: NAPI control structure
* @stats: software traffic counters for netdev stats * @stats: software traffic counters for netdev stats
* @dl_port: devlink port associated to this netdev representor
*/ */
struct efx_rep { struct efx_rep {
struct efx_nic *parent; struct efx_nic *parent;
...@@ -54,6 +57,7 @@ struct efx_rep { ...@@ -54,6 +57,7 @@ struct efx_rep {
spinlock_t rx_lock; spinlock_t rx_lock;
struct napi_struct napi; struct napi_struct napi;
struct efx_rep_sw_stats stats; struct efx_rep_sw_stats stats;
struct devlink_port *dl_port;
}; };
int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i); int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i);
...@@ -69,4 +73,7 @@ struct efx_rep *efx_ef100_find_rep_by_mport(struct efx_nic *efx, u16 mport); ...@@ -69,4 +73,7 @@ struct efx_rep *efx_ef100_find_rep_by_mport(struct efx_nic *efx, u16 mport);
extern const struct net_device_ops efx_ef100_rep_netdev_ops; extern const struct net_device_ops efx_ef100_rep_netdev_ops;
void efx_ef100_init_reps(struct efx_nic *efx); void efx_ef100_init_reps(struct efx_nic *efx);
void efx_ef100_fini_reps(struct efx_nic *efx); void efx_ef100_fini_reps(struct efx_nic *efx);
struct mae_mport_desc;
bool ef100_mport_on_local_intf(struct efx_nic *efx,
struct mae_mport_desc *mport_desc);
#endif /* EF100_REP_H */ #endif /* EF100_REP_H */
...@@ -14,11 +14,52 @@ ...@@ -14,11 +14,52 @@
#include "mcdi.h" #include "mcdi.h"
#include "mcdi_functions.h" #include "mcdi_functions.h"
#include "mcdi_pcol.h" #include "mcdi_pcol.h"
#ifdef CONFIG_SFC_SRIOV
#include "mae.h"
#include "ef100_rep.h"
#endif
struct efx_devlink { struct efx_devlink {
struct efx_nic *efx; struct efx_nic *efx;
}; };
#ifdef CONFIG_SFC_SRIOV
static void efx_devlink_del_port(struct devlink_port *dl_port)
{
if (!dl_port)
return;
devl_port_unregister(dl_port);
}
static int efx_devlink_add_port(struct efx_nic *efx,
struct mae_mport_desc *mport)
{
bool external = false;
if (!ef100_mport_on_local_intf(efx, mport))
external = true;
switch (mport->mport_type) {
case MAE_MPORT_DESC_MPORT_TYPE_VNIC:
if (mport->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL)
devlink_port_attrs_pci_vf_set(&mport->dl_port, 0, mport->pf_idx,
mport->vf_idx,
external);
else
devlink_port_attrs_pci_pf_set(&mport->dl_port, 0, mport->pf_idx,
external);
break;
default:
/* MAE_MPORT_DESC_MPORT_ALIAS and UNDEFINED */
return 0;
}
mport->dl_port.index = mport->mport_id;
return devl_port_register(efx->devlink, &mport->dl_port, mport->mport_id);
}
#endif
static int efx_devlink_info_nvram_partition(struct efx_nic *efx, static int efx_devlink_info_nvram_partition(struct efx_nic *efx,
struct devlink_info_req *req, struct devlink_info_req *req,
unsigned int partition_type, unsigned int partition_type,
...@@ -475,6 +516,70 @@ static const struct devlink_ops sfc_devlink_ops = { ...@@ -475,6 +516,70 @@ static const struct devlink_ops sfc_devlink_ops = {
.info_get = efx_devlink_info_get, .info_get = efx_devlink_info_get,
}; };
#ifdef CONFIG_SFC_SRIOV
static struct devlink_port *ef100_set_devlink_port(struct efx_nic *efx, u32 idx)
{
struct mae_mport_desc *mport;
u32 id;
int rc;
if (efx_mae_lookup_mport(efx, idx, &id)) {
/* This should not happen. */
if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
pci_warn_once(efx->pci_dev, "No mport ID found for PF.\n");
else
pci_warn_once(efx->pci_dev, "No mport ID found for VF %u.\n",
idx);
return NULL;
}
mport = efx_mae_get_mport(efx, id);
if (!mport) {
/* This should not happen. */
if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
pci_warn_once(efx->pci_dev, "No mport found for PF.\n");
else
pci_warn_once(efx->pci_dev, "No mport found for VF %u.\n",
idx);
return NULL;
}
rc = efx_devlink_add_port(efx, mport);
if (rc) {
if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
pci_warn(efx->pci_dev,
"devlink port creation for PF failed.\n");
else
pci_warn(efx->pci_dev,
"devlink_port creationg for VF %u failed.\n",
idx);
return NULL;
}
return &mport->dl_port;
}
void ef100_rep_set_devlink_port(struct efx_rep *efv)
{
efv->dl_port = ef100_set_devlink_port(efv->parent, efv->idx);
}
void ef100_pf_set_devlink_port(struct efx_nic *efx)
{
efx->dl_port = ef100_set_devlink_port(efx, MAE_MPORT_DESC_VF_IDX_NULL);
}
void ef100_rep_unset_devlink_port(struct efx_rep *efv)
{
efx_devlink_del_port(efv->dl_port);
}
void ef100_pf_unset_devlink_port(struct efx_nic *efx)
{
efx_devlink_del_port(efx->dl_port);
}
#endif
void efx_fini_devlink_lock(struct efx_nic *efx) void efx_fini_devlink_lock(struct efx_nic *efx)
{ {
if (efx->devlink) if (efx->devlink)
......
...@@ -36,4 +36,12 @@ void efx_probe_devlink_unlock(struct efx_nic *efx); ...@@ -36,4 +36,12 @@ void efx_probe_devlink_unlock(struct efx_nic *efx);
void efx_fini_devlink_lock(struct efx_nic *efx); void efx_fini_devlink_lock(struct efx_nic *efx);
void efx_fini_devlink_and_unlock(struct efx_nic *efx); void efx_fini_devlink_and_unlock(struct efx_nic *efx);
#ifdef CONFIG_SFC_SRIOV
struct efx_rep;
void ef100_pf_set_devlink_port(struct efx_nic *efx);
void ef100_rep_set_devlink_port(struct efx_rep *efv);
void ef100_pf_unset_devlink_port(struct efx_nic *efx);
void ef100_rep_unset_devlink_port(struct efx_rep *efv);
#endif
#endif /* _EFX_DEVLINK_H */ #endif /* _EFX_DEVLINK_H */
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define EF100_MAE_H #define EF100_MAE_H
/* MCDI interface for the ef100 Match-Action Engine */ /* MCDI interface for the ef100 Match-Action Engine */
#include <net/devlink.h>
#include "net_driver.h" #include "net_driver.h"
#include "tc.h" #include "tc.h"
#include "mcdi_pcol.h" /* needed for various MC_CMD_MAE_*_NULL defines */ #include "mcdi_pcol.h" /* needed for various MC_CMD_MAE_*_NULL defines */
...@@ -43,6 +44,7 @@ struct mae_mport_desc { ...@@ -43,6 +44,7 @@ struct mae_mport_desc {
}; };
}; };
struct rhash_head linkage; struct rhash_head linkage;
struct devlink_port dl_port;
}; };
int efx_mae_enumerate_mports(struct efx_nic *efx); int efx_mae_enumerate_mports(struct efx_nic *efx);
......
...@@ -998,6 +998,7 @@ struct efx_mae; ...@@ -998,6 +998,7 @@ struct efx_mae;
* @netdev_notifier: Netdevice notifier. * @netdev_notifier: Netdevice notifier.
* @tc: state for TC offload (EF100). * @tc: state for TC offload (EF100).
* @devlink: reference to devlink structure owned by this device * @devlink: reference to devlink structure owned by this device
* @dl_port: devlink port associated with the PF
* @mem_bar: The BAR that is mapped into membase. * @mem_bar: The BAR that is mapped into membase.
* @reg_base: Offset from the start of the bar to the function control window. * @reg_base: Offset from the start of the bar to the function control window.
* @monitor_work: Hardware monitor workitem * @monitor_work: Hardware monitor workitem
...@@ -1185,6 +1186,7 @@ struct efx_nic { ...@@ -1185,6 +1186,7 @@ struct efx_nic {
struct efx_tc_state *tc; struct efx_tc_state *tc;
struct devlink *devlink; struct devlink *devlink;
struct devlink_port *dl_port;
unsigned int mem_bar; unsigned int mem_bar;
u32 reg_base; u32 reg_base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment