Skip to content

Commit

Permalink
octeontx2-pf: devlink params support to set mcam entry count
Browse files Browse the repository at this point in the history
Added support for setting or modifying MCAM entry count at
runtime via devlink params.

commands:
  devlink dev param show
pci/0002:02:00.0:
  name mcam_count type driver-specific
    values:
      cmode runtime value 16

  devlink dev param set pci/0002:02:00.0 name mcam_count
				value 64 cmode runtime

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sunil Goutham authored and David S. Miller committed Aug 17, 2021
1 parent 2e2a812 commit 2da4894
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 17 deletions.
5 changes: 3 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/nic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ obj-$(CONFIG_OCTEONTX2_PF) += rvu_nicpf.o
obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o

rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
otx2_ptp.o otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o
rvu_nicvf-y := otx2_vf.o
otx2_ptp.o otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \
otx2_devlink.o
rvu_nicvf-y := otx2_vf.o otx2_devlink.o

ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
8 changes: 7 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include <linux/timecounter.h>
#include <linux/soc/marvell/octeontx2/asm.h>
#include <net/pkt_cls.h>
#include <net/devlink.h>

#include <mbox.h>
#include <npc.h>
#include "otx2_reg.h"
#include "otx2_txrx.h"
#include "otx2_devlink.h"
#include <rvu_trace.h>

/* PCI device IDs */
Expand Down Expand Up @@ -376,6 +378,9 @@ struct otx2_nic {
struct hwtstamp_config tstamp;

unsigned long rq_bmap;

/* Devlink */
struct otx2_devlink *dl;
};

static inline bool is_otx2_lbkvf(struct pci_dev *pdev)
Expand Down Expand Up @@ -818,7 +823,7 @@ int otx2_set_real_num_queues(struct net_device *netdev,
/* MCAM filter related APIs */
int otx2_mcam_flow_init(struct otx2_nic *pf);
int otx2vf_mcam_flow_init(struct otx2_nic *pfvf);
int otx2_alloc_mcam_entries(struct otx2_nic *pfvf);
int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count);
void otx2_mcam_flow_del(struct otx2_nic *pf);
int otx2_destroy_ntuple_flows(struct otx2_nic *pf);
int otx2_destroy_mcam_flows(struct otx2_nic *pfvf);
Expand All @@ -843,6 +848,7 @@ int otx2_init_tc(struct otx2_nic *nic);
void otx2_shutdown_tc(struct otx2_nic *nic);
int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
void *type_data);
int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic);
/* CGX/RPM DMAC filters support */
int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf);
int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
Expand Down
156 changes: 156 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU PF/VF Netdev Devlink
*
* Copyright (C) 2021 Marvell.
*/

#include "otx2_common.h"

/* Devlink Params APIs */
static int otx2_dl_mcam_count_validate(struct devlink *devlink, u32 id,
union devlink_param_value val,
struct netlink_ext_ack *extack)
{
struct otx2_devlink *otx2_dl = devlink_priv(devlink);
struct otx2_nic *pfvf = otx2_dl->pfvf;
struct otx2_flow_config *flow_cfg;

if (!pfvf->flow_cfg) {
NL_SET_ERR_MSG_MOD(extack,
"pfvf->flow_cfg not initialized");
return -EINVAL;
}

flow_cfg = pfvf->flow_cfg;
if (flow_cfg && flow_cfg->nr_flows) {
NL_SET_ERR_MSG_MOD(extack,
"Cannot modify count when there are active rules");
return -EINVAL;
}

return 0;
}

static int otx2_dl_mcam_count_set(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct otx2_devlink *otx2_dl = devlink_priv(devlink);
struct otx2_nic *pfvf = otx2_dl->pfvf;

if (!pfvf->flow_cfg)
return 0;

otx2_alloc_mcam_entries(pfvf, ctx->val.vu16);
otx2_tc_alloc_ent_bitmap(pfvf);

return 0;
}

static int otx2_dl_mcam_count_get(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct otx2_devlink *otx2_dl = devlink_priv(devlink);
struct otx2_nic *pfvf = otx2_dl->pfvf;
struct otx2_flow_config *flow_cfg;

if (!pfvf->flow_cfg) {
ctx->val.vu16 = 0;
return 0;
}

flow_cfg = pfvf->flow_cfg;
ctx->val.vu16 = flow_cfg->max_flows;

return 0;
}

enum otx2_dl_param_id {
OTX2_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
OTX2_DEVLINK_PARAM_ID_MCAM_COUNT,
};

static const struct devlink_param otx2_dl_params[] = {
DEVLINK_PARAM_DRIVER(OTX2_DEVLINK_PARAM_ID_MCAM_COUNT,
"mcam_count", DEVLINK_PARAM_TYPE_U16,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
otx2_dl_mcam_count_get, otx2_dl_mcam_count_set,
otx2_dl_mcam_count_validate),
};

/* Devlink OPs */
static int otx2_devlink_info_get(struct devlink *devlink,
struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
struct otx2_devlink *otx2_dl = devlink_priv(devlink);
struct otx2_nic *pfvf = otx2_dl->pfvf;

if (is_otx2_vf(pfvf->pcifunc))
return devlink_info_driver_name_put(req, "rvu_nicvf");

return devlink_info_driver_name_put(req, "rvu_nicpf");
}

static const struct devlink_ops otx2_devlink_ops = {
.info_get = otx2_devlink_info_get,
};

int otx2_register_dl(struct otx2_nic *pfvf)
{
struct otx2_devlink *otx2_dl;
struct devlink *dl;
int err;

dl = devlink_alloc(&otx2_devlink_ops,
sizeof(struct otx2_devlink), pfvf->dev);
if (!dl) {
dev_warn(pfvf->dev, "devlink_alloc failed\n");
return -ENOMEM;
}

err = devlink_register(dl);
if (err) {
dev_err(pfvf->dev, "devlink register failed with error %d\n", err);
devlink_free(dl);
return err;
}

otx2_dl = devlink_priv(dl);
otx2_dl->dl = dl;
otx2_dl->pfvf = pfvf;
pfvf->dl = otx2_dl;

err = devlink_params_register(dl, otx2_dl_params,
ARRAY_SIZE(otx2_dl_params));
if (err) {
dev_err(pfvf->dev,
"devlink params register failed with error %d", err);
goto err_dl;
}

devlink_params_publish(dl);

return 0;

err_dl:
devlink_unregister(dl);
devlink_free(dl);
return err;
}

void otx2_unregister_dl(struct otx2_nic *pfvf)
{
struct otx2_devlink *otx2_dl = pfvf->dl;
struct devlink *dl;

if (!otx2_dl || !otx2_dl->dl)
return;

dl = otx2_dl->dl;

devlink_params_unregister(dl, otx2_dl_params,
ARRAY_SIZE(otx2_dl_params));

devlink_unregister(dl);
devlink_free(dl);
}
20 changes: 20 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell RVU PF/VF Netdev Devlink
*
* Copyright (C) 2021 Marvell.
*
*/

#ifndef OTX2_DEVLINK_H
#define OTX2_DEVLINK_H

struct otx2_devlink {
struct devlink *dl;
struct otx2_nic *pfvf;
};

/* Devlink APIs */
int otx2_register_dl(struct otx2_nic *pfvf);
void otx2_unregister_dl(struct otx2_nic *pfvf);

#endif /* RVU_DEVLINK_H */
31 changes: 19 additions & 12 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#define OTX2_DEFAULT_ACTION 0x1

static int otx2_mcam_entry_init(struct otx2_nic *pfvf);

struct otx2_flow {
struct ethtool_rx_flow_spec flow_spec;
struct list_head list;
Expand Down Expand Up @@ -66,7 +68,7 @@ static int mcam_entry_cmp(const void *a, const void *b)
return *(u16 *)a - *(u16 *)b;
}

static int otx2_alloc_ntuple_mcam_entries(struct otx2_nic *pfvf, u16 count)
int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)
{
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
struct npc_mcam_alloc_entry_req *req;
Expand All @@ -81,8 +83,12 @@ static int otx2_alloc_ntuple_mcam_entries(struct otx2_nic *pfvf, u16 count)

flow_cfg->flow_ent = devm_kmalloc_array(pfvf->dev, count,
sizeof(u16), GFP_KERNEL);
if (!flow_cfg->flow_ent)
if (!flow_cfg->flow_ent) {
netdev_err(pfvf->netdev,
"%s: Unable to allocate memory for flow entries\n",
__func__);
return -ENOMEM;
}

mutex_lock(&pfvf->mbox.lock);

Expand Down Expand Up @@ -139,17 +145,20 @@ static int otx2_alloc_ntuple_mcam_entries(struct otx2_nic *pfvf, u16 count)

flow_cfg->max_flows = allocated;

pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
if (allocated) {
pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
}

if (allocated != count)
netdev_info(pfvf->netdev,
"Unable to allocate %d MCAM entries, got only %d\n",
count, allocated);
return allocated;
}
EXPORT_SYMBOL(otx2_alloc_mcam_entries);

int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
{
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
struct npc_mcam_alloc_entry_req *req;
Expand Down Expand Up @@ -209,7 +218,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
mutex_unlock(&pfvf->mbox.lock);

/* Allocate entries for Ntuple filters */
count = otx2_alloc_ntuple_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT);
count = otx2_alloc_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT);
if (count <= 0) {
otx2_clear_ntuple_flow_info(pfvf, flow_cfg);
return 0;
Expand All @@ -223,7 +232,6 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)
{
struct otx2_flow_config *flow_cfg;
int count;

pfvf->flow_cfg = devm_kzalloc(pfvf->dev,
sizeof(struct otx2_flow_config),
Expand All @@ -235,10 +243,6 @@ int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)
INIT_LIST_HEAD(&flow_cfg->flow_list);
flow_cfg->max_flows = 0;

count = otx2_alloc_ntuple_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT);
if (count <= 0)
return -ENOMEM;

return 0;
}
EXPORT_SYMBOL(otx2vf_mcam_flow_init);
Expand All @@ -254,7 +258,10 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)

INIT_LIST_HEAD(&pf->flow_cfg->flow_list);

err = otx2_alloc_mcam_entries(pf);
/* Allocate bare minimum number of MCAM entries needed for
* unicast and ntuple filters.
*/
err = otx2_mcam_entry_init(pf);
if (err)
return err;

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2626,6 +2626,10 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto err_mcam_flow_del;

err = otx2_register_dl(pf);
if (err)
goto err_mcam_flow_del;

/* Initialize SR-IOV resources */
err = otx2_sriov_vfcfg_init(pf);
if (err)
Expand Down Expand Up @@ -2783,6 +2787,7 @@ static void otx2_remove(struct pci_dev *pdev)
/* Disable link notifications */
otx2_cgx_config_linkevents(pf, false);

otx2_unregister_dl(pf);
unregister_netdev(netdev);
otx2_sriov_disable(pf->pdev);
otx2_sriov_vfcfg_cleanup(pf);
Expand Down
8 changes: 6 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ struct otx2_tc_flow {
bool is_act_police;
};

static int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic)
int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic)
{
struct otx2_tc_info *tc = &nic->tc_info;

if (!nic->flow_cfg->max_flows)
if (!nic->flow_cfg->max_flows || is_otx2_vf(nic->pcifunc))
return 0;

/* Max flows changed, free the existing bitmap */
kfree(tc->tc_entries_bitmap);

tc->tc_entries_bitmap =
kcalloc(BITS_TO_LONGS(nic->flow_cfg->max_flows),
sizeof(long), GFP_KERNEL);
Expand All @@ -70,6 +73,7 @@ static int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic)

return 0;
}
EXPORT_SYMBOL(otx2_tc_alloc_ent_bitmap);

static void otx2_get_egress_burst_cfg(u32 burst, u32 *burst_exp,
u32 *burst_mantissa)
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,10 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto err_unreg_netdev;

err = otx2_register_dl(vf);
if (err)
goto err_unreg_netdev;

/* Enable pause frames by default */
vf->flags |= OTX2_FLAG_RX_PAUSE_ENABLED;
vf->flags |= OTX2_FLAG_TX_PAUSE_ENABLED;
Expand Down Expand Up @@ -724,6 +728,7 @@ static void otx2vf_remove(struct pci_dev *pdev)
vf = netdev_priv(netdev);

cancel_work_sync(&vf->reset_task);
otx2_unregister_dl(vf);
unregister_netdev(netdev);
if (vf->otx2_wq)
destroy_workqueue(vf->otx2_wq);
Expand Down

0 comments on commit 2da4894

Please sign in to comment.