Skip to content

Commit

Permalink
Merge branch 'nfp-devlink-capabilities-extensions-and-updates'
Browse files Browse the repository at this point in the history
Jakub Kicinski says:

====================
nfp: devlink, capabilities extensions and updates

This series starts with an improvement to the usability of the device
memory accessors (CPP transactions).  Next few patches are devoted to
fixing the devlink locking.  After recent patches for mlxsw the locking
scheme of devlink ops has to be reworked.  Following patches improve
NFP code dealing with "representors", and expands the error message
printed when driver has no support for loaded FW.

Second part of the series is focused on vNIC capabilities read from
vNIC control memory (often referred to as "BAR0" for historical reasons).
TLV capability format is established and immediately made use of.  The
next patches rework parsing of features for control vNIC which allows
apps to mask out features they don't want enabled.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 19, 2018
2 parents 3c1693f + 81bd5de commit ea8de47
Show file tree
Hide file tree
Showing 19 changed files with 463 additions and 208 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/netronome/nfp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ nfp-objs := \
nfp_hwmon.o \
nfp_main.o \
nfp_net_common.o \
nfp_net_ctrl.o \
nfp_net_debugdump.o \
nfp_net_ethtool.o \
nfp_net_main.o \
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/netronome/nfp/bpf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ const struct nfp_app_type app_bpf = {
.id = NFP_APP_BPF_NIC,
.name = "ebpf",

.ctrl_cap_mask = 0,

.init = nfp_bpf_init,
.clean = nfp_bpf_clean,

Expand Down
47 changes: 28 additions & 19 deletions drivers/net/ethernet/netronome/nfp/flower/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ nfp_flower_repr_get(struct nfp_app *app, u32 port_id)
if (port >= reprs->num_reprs)
return NULL;

return reprs->reprs[port];
return rcu_dereference(reprs->reprs[port]);
}

static int
Expand All @@ -114,15 +114,19 @@ nfp_flower_reprs_reify(struct nfp_app *app, enum nfp_repr_type type,
if (!reprs)
return 0;

for (i = 0; i < reprs->num_reprs; i++)
if (reprs->reprs[i]) {
struct nfp_repr *repr = netdev_priv(reprs->reprs[i]);
for (i = 0; i < reprs->num_reprs; i++) {
struct net_device *netdev;

netdev = nfp_repr_get_locked(app, reprs, i);
if (netdev) {
struct nfp_repr *repr = netdev_priv(netdev);

err = nfp_flower_cmsg_portreify(repr, exists);
if (err)
return err;
count++;
}
}

return count;
}
Expand Down Expand Up @@ -234,19 +238,21 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
return -ENOMEM;

for (i = 0; i < cnt; i++) {
struct net_device *repr;
struct nfp_port *port;
u32 port_id;

reprs->reprs[i] = nfp_repr_alloc(app);
if (!reprs->reprs[i]) {
repr = nfp_repr_alloc(app);
if (!repr) {
err = -ENOMEM;
goto err_reprs_clean;
}
RCU_INIT_POINTER(reprs->reprs[i], repr);

/* For now we only support 1 PF */
WARN_ON(repr_type == NFP_REPR_TYPE_PF && i);

port = nfp_port_alloc(app, port_type, reprs->reprs[i]);
port = nfp_port_alloc(app, port_type, repr);
if (repr_type == NFP_REPR_TYPE_PF) {
port->pf_id = i;
port->vnic = priv->nn->dp.ctrl_bar;
Expand All @@ -257,11 +263,11 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
}

eth_hw_addr_random(reprs->reprs[i]);
eth_hw_addr_random(repr);

port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
i, queue);
err = nfp_repr_init(app, reprs->reprs[i],
err = nfp_repr_init(app, repr,
port_id, port, priv->nn->dp.netdev);
if (err) {
nfp_port_free(port);
Expand All @@ -270,7 +276,7 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,

nfp_info(app->cpp, "%s%d Representor(%s) created\n",
repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
reprs->reprs[i]->name);
repr->name);
}

nfp_app_reprs_set(app, repr_type, reprs);
Expand All @@ -291,7 +297,7 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
err_reprs_remove:
reprs = nfp_app_reprs_set(app, repr_type, NULL);
err_reprs_clean:
nfp_reprs_clean_and_free(reprs);
nfp_reprs_clean_and_free(app, reprs);
return err;
}

Expand Down Expand Up @@ -329,17 +335,18 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)

for (i = 0; i < eth_tbl->count; i++) {
unsigned int phys_port = eth_tbl->ports[i].index;
struct net_device *repr;
struct nfp_port *port;
u32 cmsg_port_id;

reprs->reprs[phys_port] = nfp_repr_alloc(app);
if (!reprs->reprs[phys_port]) {
repr = nfp_repr_alloc(app);
if (!repr) {
err = -ENOMEM;
goto err_reprs_clean;
}
RCU_INIT_POINTER(reprs->reprs[phys_port], repr);

port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT,
reprs->reprs[phys_port]);
port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT, repr);
if (IS_ERR(port)) {
err = PTR_ERR(port);
goto err_reprs_clean;
Expand All @@ -350,11 +357,11 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
goto err_reprs_clean;
}

SET_NETDEV_DEV(reprs->reprs[phys_port], &priv->nn->pdev->dev);
SET_NETDEV_DEV(repr, &priv->nn->pdev->dev);
nfp_net_get_mac_addr(app->pf, port);

cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
err = nfp_repr_init(app, reprs->reprs[phys_port],
err = nfp_repr_init(app, repr,
cmsg_port_id, port, priv->nn->dp.netdev);
if (err) {
nfp_port_free(port);
Expand All @@ -367,7 +374,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
phys_port);

nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
phys_port, reprs->reprs[phys_port]->name);
phys_port, repr->name);
}

nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
Expand Down Expand Up @@ -397,7 +404,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
err_reprs_remove:
reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, NULL);
err_reprs_clean:
nfp_reprs_clean_and_free(reprs);
nfp_reprs_clean_and_free(app, reprs);
err_free_ctrl_skb:
kfree_skb(ctrl_skb);
return err;
Expand Down Expand Up @@ -558,6 +565,8 @@ static void nfp_flower_stop(struct nfp_app *app)
const struct nfp_app_type app_flower = {
.id = NFP_APP_FLOWER_NIC,
.name = "flower",

.ctrl_cap_mask = ~0U,
.ctrl_has_meta = true,

.extra_cap = nfp_flower_extra_cap,
Expand Down
14 changes: 11 additions & 3 deletions drivers/net/ethernet/netronome/nfp/nfp_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
*/

#include <linux/bug.h>
#include <linux/lockdep.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/slab.h>

Expand Down Expand Up @@ -98,14 +100,20 @@ nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority)
return skb;
}

struct nfp_reprs *
nfp_reprs_get_locked(struct nfp_app *app, enum nfp_repr_type type)
{
return rcu_dereference_protected(app->reprs[type],
lockdep_is_held(&app->pf->lock));
}

struct nfp_reprs *
nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
struct nfp_reprs *reprs)
{
struct nfp_reprs *old;

old = rcu_dereference_protected(app->reprs[type],
lockdep_is_held(&app->pf->lock));
old = nfp_reprs_get_locked(app, type);
rcu_assign_pointer(app->reprs[type], reprs);

return old;
Expand All @@ -116,7 +124,7 @@ struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
struct nfp_app *app;

if (id >= ARRAY_SIZE(apps) || !apps[id]) {
nfp_err(pf->cpp, "failed to find app with ID 0x%02hhx\n", id);
nfp_err(pf->cpp, "unknown FW app ID 0x%02hhx, driver too old or support for FW not built in\n", id);
return ERR_PTR(-EINVAL);
}

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ extern const struct nfp_app_type app_flower;
* struct nfp_app_type - application definition
* @id: application ID
* @name: application name
* @ctrl_cap_mask: ctrl vNIC capability mask, allows disabling features like
* IRQMOD which are on by default but counter-productive for
* control messages which are often latency-sensitive
* @ctrl_has_meta: control messages have prepend of type:5/port:CTRL
*
* Callbacks
Expand Down Expand Up @@ -100,6 +103,7 @@ struct nfp_app_type {
enum nfp_app_id id;
const char *name;

u32 ctrl_cap_mask;
bool ctrl_has_meta;

int (*init)(struct nfp_app *app);
Expand Down Expand Up @@ -384,6 +388,8 @@ static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id)

struct nfp_app *nfp_app_from_netdev(struct net_device *netdev);

struct nfp_reprs *
nfp_reprs_get_locked(struct nfp_app *app, enum nfp_repr_type type);
struct nfp_reprs *
nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
struct nfp_reprs *reprs);
Expand Down
12 changes: 1 addition & 11 deletions drivers/net/ethernet/netronome/nfp/nfp_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,8 @@ nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index)
static int nfp_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
{
struct nfp_pf *pf = devlink_priv(devlink);
int ret;

mutex_lock(&pf->lock);
if (!pf->app) {
ret = -EBUSY;
goto out;
}
ret = nfp_app_eswitch_mode_get(pf->app, mode);
out:
mutex_unlock(&pf->lock);

return ret;
return nfp_app_eswitch_mode_get(pf->app, mode);
}

const struct devlink_ops nfp_devlink_ops = {
Expand Down
17 changes: 3 additions & 14 deletions drivers/net/ethernet/netronome/nfp/nfp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,13 +499,9 @@ static int nfp_pci_probe(struct pci_dev *pdev,
if (err)
goto err_hwinfo_free;

err = devlink_register(devlink, &pdev->dev);
if (err)
goto err_hwinfo_free;

err = nfp_nsp_init(pdev, pf);
if (err)
goto err_devlink_unreg;
goto err_hwinfo_free;

pf->mip = nfp_mip_open(pf->cpp);
pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip);
Expand Down Expand Up @@ -549,8 +545,6 @@ static int nfp_pci_probe(struct pci_dev *pdev,
kfree(pf->eth_tbl);
kfree(pf->nspi);
vfree(pf->dumpspec);
err_devlink_unreg:
devlink_unregister(devlink);
err_hwinfo_free:
kfree(pf->hwinfo);
nfp_cpp_free(pf->cpp);
Expand All @@ -571,18 +565,13 @@ static int nfp_pci_probe(struct pci_dev *pdev,
static void nfp_pci_remove(struct pci_dev *pdev)
{
struct nfp_pf *pf = pci_get_drvdata(pdev);
struct devlink *devlink;

nfp_hwmon_unregister(pf);

devlink = priv_to_devlink(pf);

nfp_net_pci_remove(pf);

nfp_pcie_sriov_disable(pdev);
pci_sriov_set_totalvfs(pf->pdev, 0);

devlink_unregister(devlink);
nfp_net_pci_remove(pf);

vfree(pf->dumpspec);
kfree(pf->rtbl);
Expand All @@ -598,7 +587,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
kfree(pf->eth_tbl);
kfree(pf->nspi);
mutex_destroy(&pf->lock);
devlink_free(devlink);
devlink_free(priv_to_devlink(pf));
pci_release_regions(pdev);
pci_disable_device(pdev);
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ struct nfp_net_dp {
* @qcp_cfg: Pointer to QCP queue used for configuration notification
* @tx_bar: Pointer to mapped TX queues
* @rx_bar: Pointer to mapped FL/RX queues
* @tlv_caps: Parsed TLV capabilities
* @debugfs_dir: Device directory in debugfs
* @vnic_list: Entry on device vNIC list
* @pdev: Backpointer to PCI device
Expand Down Expand Up @@ -644,6 +645,8 @@ struct nfp_net {
u8 __iomem *tx_bar;
u8 __iomem *rx_bar;

struct nfp_net_tlv_caps tlv_caps;

struct dentry *debugfs_dir;

struct list_head vnic_list;
Expand Down
Loading

0 comments on commit ea8de47

Please sign in to comment.