Commit 14780c34 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: abm: calculate PRIO map len and check mailbox size

In preparation for PRIO offload calculate how long the prio map
for FW will be and make sure the configuration can be performed
via the vNIC mailbox.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarJohn Hurley <john.hurley@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 068ceb35
...@@ -33,6 +33,12 @@ ...@@ -33,6 +33,12 @@
#define NFP_Q_STAT_PKTS 0 #define NFP_Q_STAT_PKTS 0
#define NFP_Q_STAT_BYTES 8 #define NFP_Q_STAT_BYTES 8
#define NFP_NET_ABM_MBOX_CMD NFP_NET_CFG_MBOX_SIMPLE_CMD
#define NFP_NET_ABM_MBOX_RET NFP_NET_CFG_MBOX_SIMPLE_RET
#define NFP_NET_ABM_MBOX_DATALEN NFP_NET_CFG_MBOX_SIMPLE_VAL
#define NFP_NET_ABM_MBOX_RESERVED (NFP_NET_CFG_MBOX_SIMPLE_VAL + 4)
#define NFP_NET_ABM_MBOX_DATA (NFP_NET_CFG_MBOX_SIMPLE_VAL + 8)
static int static int
nfp_abm_ctrl_stat(struct nfp_abm_link *alink, const struct nfp_rtsym *sym, nfp_abm_ctrl_stat(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
unsigned int stride, unsigned int offset, unsigned int band, unsigned int stride, unsigned int offset, unsigned int band,
...@@ -215,10 +221,42 @@ int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm) ...@@ -215,10 +221,42 @@ int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm)
NULL, 0, NULL, 0); NULL, 0, NULL, 0);
} }
void nfp_abm_ctrl_read_params(struct nfp_abm_link *alink) static int nfp_abm_ctrl_prio_check_params(struct nfp_abm_link *alink)
{
struct nfp_abm *abm = alink->abm;
struct nfp_net *nn = alink->vnic;
unsigned int min_mbox_sz;
if (!nfp_abm_has_prio(alink->abm))
return 0;
min_mbox_sz = NFP_NET_ABM_MBOX_DATA + alink->abm->prio_map_len;
if (nn->tlv_caps.mbox_len < min_mbox_sz) {
nfp_err(abm->app->pf->cpp, "vNIC mailbox too small for prio offload: %u, need: %u\n",
nn->tlv_caps.mbox_len, min_mbox_sz);
return -EINVAL;
}
return 0;
}
int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink)
{ {
alink->queue_base = nn_readl(alink->vnic, NFP_NET_CFG_START_RXQ); alink->queue_base = nn_readl(alink->vnic, NFP_NET_CFG_START_RXQ);
alink->queue_base /= alink->vnic->stride_rx; alink->queue_base /= alink->vnic->stride_rx;
return nfp_abm_ctrl_prio_check_params(alink);
}
static unsigned int nfp_abm_ctrl_prio_map_size(struct nfp_abm *abm)
{
unsigned int size;
size = roundup_pow_of_two(order_base_2(abm->num_bands));
size = DIV_ROUND_UP(size * abm->num_prios, BITS_PER_BYTE);
size = round_up(size, sizeof(u32));
return size;
} }
static const struct nfp_rtsym * static const struct nfp_rtsym *
...@@ -273,6 +311,8 @@ int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm) ...@@ -273,6 +311,8 @@ int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm)
return res; return res;
abm->num_prios = res; abm->num_prios = res;
abm->prio_map_len = nfp_abm_ctrl_prio_map_size(abm);
/* Check values are sane, U16_MAX is arbitrarily chosen as max */ /* Check values are sane, U16_MAX is arbitrarily chosen as max */
if (!is_power_of_2(abm->num_bands) || !is_power_of_2(abm->num_prios) || if (!is_power_of_2(abm->num_bands) || !is_power_of_2(abm->num_prios) ||
abm->num_bands > U16_MAX || abm->num_prios > U16_MAX || abm->num_bands > U16_MAX || abm->num_prios > U16_MAX ||
......
...@@ -315,6 +315,10 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) ...@@ -315,6 +315,10 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
alink->id = id; alink->id = id;
alink->total_queues = alink->vnic->max_rx_rings; alink->total_queues = alink->vnic->max_rx_rings;
err = nfp_abm_ctrl_read_params(alink);
if (err)
goto err_free_alink;
/* This is a multi-host app, make sure MAC/PHY is up, but don't /* This is a multi-host app, make sure MAC/PHY is up, but don't
* make the MAC/PHY state follow the state of any of the ports. * make the MAC/PHY state follow the state of any of the ports.
*/ */
...@@ -325,7 +329,6 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) ...@@ -325,7 +329,6 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
netif_keep_dst(nn->dp.netdev); netif_keep_dst(nn->dp.netdev);
nfp_abm_vnic_set_mac(app->pf, abm, nn, id); nfp_abm_vnic_set_mac(app->pf, abm, nn, id);
nfp_abm_ctrl_read_params(alink);
INIT_RADIX_TREE(&alink->qdiscs, GFP_KERNEL); INIT_RADIX_TREE(&alink->qdiscs, GFP_KERNEL);
return 0; return 0;
......
...@@ -34,9 +34,11 @@ struct nfp_net; ...@@ -34,9 +34,11 @@ struct nfp_net;
* @thresholds: current threshold configuration * @thresholds: current threshold configuration
* @threshold_undef: bitmap of thresholds which have not been set * @threshold_undef: bitmap of thresholds which have not been set
* @num_thresholds: number of @thresholds and bits in @threshold_undef * @num_thresholds: number of @thresholds and bits in @threshold_undef
* @prio_map_len: computed length of FW priority map (in bytes)
* *
* @eswitch_mode: devlink eswitch mode, advanced functions only visible * @eswitch_mode: devlink eswitch mode, advanced functions only visible
* in switchdev mode * in switchdev mode
*
* @q_lvls: queue level control area * @q_lvls: queue level control area
* @qm_stats: queue statistics symbol * @qm_stats: queue statistics symbol
* @q_stats: basic queue statistics (only in per-band case) * @q_stats: basic queue statistics (only in per-band case)
...@@ -51,8 +53,10 @@ struct nfp_abm { ...@@ -51,8 +53,10 @@ struct nfp_abm {
u32 *thresholds; u32 *thresholds;
unsigned long *threshold_undef; unsigned long *threshold_undef;
size_t num_thresholds; size_t num_thresholds;
unsigned int prio_map_len;
enum devlink_eswitch_mode eswitch_mode; enum devlink_eswitch_mode eswitch_mode;
const struct nfp_rtsym *q_lvls; const struct nfp_rtsym *q_lvls;
const struct nfp_rtsym *qm_stats; const struct nfp_rtsym *qm_stats;
const struct nfp_rtsym *q_stats; const struct nfp_rtsym *q_stats;
...@@ -201,7 +205,7 @@ int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink, ...@@ -201,7 +205,7 @@ int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,
int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink, int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink,
struct tc_gred_qopt_offload *opt); struct tc_gred_qopt_offload *opt);
void nfp_abm_ctrl_read_params(struct nfp_abm_link *alink); int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink);
int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm); int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm);
int __nfp_abm_ctrl_set_q_lvl(struct nfp_abm *abm, unsigned int id, u32 val); int __nfp_abm_ctrl_set_q_lvl(struct nfp_abm *abm, unsigned int id, u32 val);
int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int band, int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int band,
......
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