nfp: abm: add helpers for configuring queue marking levels

Queue levels for simple ECN marking are stored in _abi_nfd_out_q_lvls_X
symbol, where X is the PCIe PF id.  Find out the location of that symbol
and add helpers for modifying it.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jakub Kicinski 2018-05-25 21:53:28 -07:00 committed by David S. Miller
parent 055ee0d698
commit 25e0036fcd
3 changed files with 88 additions and 0 deletions

View File

@ -35,12 +35,57 @@
#include <linux/kernel.h>
#include "../nfpcore/nfp_cpp.h"
#include "../nfpcore/nfp_nffw.h"
#include "../nfp_app.h"
#include "../nfp_abi.h"
#include "../nfp_main.h"
#include "../nfp_net.h"
#include "main.h"
#define NFP_QLVL_SYM_NAME "_abi_nfd_out_q_lvls_%u"
#define NFP_QLVL_STRIDE 16
#define NFP_QLVL_THRS 8
static unsigned long long
nfp_abm_q_lvl_thrs(struct nfp_abm_link *alink, unsigned int queue)
{
return alink->abm->q_lvls->addr +
(alink->queue_base + queue) * NFP_QLVL_STRIDE + NFP_QLVL_THRS;
}
static int
nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int i, u32 val)
{
struct nfp_cpp *cpp = alink->abm->app->cpp;
u32 muw;
int err;
muw = NFP_CPP_ATOMIC_WR(alink->abm->q_lvls->target,
alink->abm->q_lvls->domain);
err = nfp_cpp_writel(cpp, muw, nfp_abm_q_lvl_thrs(alink, i), val);
if (err) {
nfp_err(cpp, "RED offload setting level failed on vNIC %d queue %d\n",
alink->id, i);
return err;
}
return 0;
}
int nfp_abm_ctrl_set_all_q_lvls(struct nfp_abm_link *alink, u32 val)
{
int i, err;
for (i = 0; i < alink->vnic->max_rx_rings; i++) {
err = nfp_abm_ctrl_set_q_lvl(alink, i, val);
if (err)
return err;
}
return 0;
}
int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm)
{
return nfp_mbox_cmd(abm->app->pf, NFP_MBOX_PCIE_ABM_ENABLE,
@ -59,13 +104,48 @@ void nfp_abm_ctrl_read_params(struct nfp_abm_link *alink)
alink->queue_base /= alink->vnic->stride_rx;
}
static const struct nfp_rtsym *
nfp_abm_ctrl_find_rtsym(struct nfp_pf *pf, const char *name, unsigned int size)
{
const struct nfp_rtsym *sym;
sym = nfp_rtsym_lookup(pf->rtbl, name);
if (!sym) {
nfp_err(pf->cpp, "Symbol '%s' not found\n", name);
return ERR_PTR(-ENOENT);
}
if (sym->size != size) {
nfp_err(pf->cpp,
"Symbol '%s' wrong size: expected %u got %llu\n",
name, size, sym->size);
return ERR_PTR(-EINVAL);
}
return sym;
}
static const struct nfp_rtsym *
nfp_abm_ctrl_find_q_rtsym(struct nfp_pf *pf, const char *name,
unsigned int size)
{
return nfp_abm_ctrl_find_rtsym(pf, name, size * NFP_NET_MAX_RX_RINGS);
}
int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm)
{
struct nfp_pf *pf = abm->app->pf;
const struct nfp_rtsym *sym;
unsigned int pf_id;
char pf_symbol[64];
pf_id = nfp_cppcore_pcie_unit(pf->cpp);
abm->pf_id = pf_id;
snprintf(pf_symbol, sizeof(pf_symbol), NFP_QLVL_SYM_NAME, pf_id);
sym = nfp_abm_ctrl_find_q_rtsym(pf, pf_symbol, NFP_QLVL_STRIDE);
if (IS_ERR(sym))
return PTR_ERR(sym);
abm->q_lvls = sym;
return 0;
}

View File

@ -49,11 +49,13 @@ struct nfp_net;
* @pf_id: ID of our PF link
* @eswitch_mode: devlink eswitch mode, advanced functions only visible
* in switchdev mode
* @q_lvls: queue level control area
*/
struct nfp_abm {
struct nfp_app *app;
unsigned int pf_id;
enum devlink_eswitch_mode eswitch_mode;
const struct nfp_rtsym *q_lvls;
};
/**
@ -72,6 +74,7 @@ struct nfp_abm_link {
void nfp_abm_ctrl_read_params(struct nfp_abm_link *alink);
int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm);
int nfp_abm_ctrl_set_all_q_lvls(struct nfp_abm_link *alink, u32 val);
int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm);
int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm);
#endif

View File

@ -87,6 +87,11 @@ struct resource;
#define NFP_CPP_TARGET_ID_MASK 0x1f
#define NFP_CPP_ATOMIC_RD(target, island) \
NFP_CPP_ISLAND_ID((target), 3, 0, (island))
#define NFP_CPP_ATOMIC_WR(target, island) \
NFP_CPP_ISLAND_ID((target), 4, 0, (island))
/**
* NFP_CPP_ID() - pack target, token, and action into a CPP ID.
* @target: NFP CPP target id