octeontx2-pf: devlink params support to set mcam entry count
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>
This commit is contained in:
Родитель
2e2a8126ff
Коммит
2da4894327
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -139,8 +145,10 @@ exit:
|
|||
|
||||
flow_cfg->max_flows = allocated;
|
||||
|
||||
if (allocated) {
|
||||
pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
|
||||
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
|
||||
}
|
||||
|
||||
if (allocated != count)
|
||||
netdev_info(pfvf->netdev,
|
||||
|
@ -148,8 +156,9 @@ exit:
|
|||
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;
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче