diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2018-11-20 02:21:47 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-20 05:53:46 +0300 |
commit | 14780c34294f41da8f02d99d7b6ada990e685561 (patch) | |
tree | 70cb8d6c243481b1763d5f66f57cdad376b5afc9 /drivers/net/ethernet | |
parent | 068ceb3555397dbd82593fb505688c5bd200a4ad (diff) | |
download | linux-14780c34294f41da8f02d99d7b6ada990e685561.tar.xz |
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: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: John Hurley <john.hurley@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/abm/ctrl.c | 42 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/abm/main.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/abm/main.h | 6 |
3 files changed, 50 insertions, 3 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/abm/ctrl.c b/drivers/net/ethernet/netronome/nfp/abm/ctrl.c index 10a571b5b565..ef10a2e730bc 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/ctrl.c +++ b/drivers/net/ethernet/netronome/nfp/abm/ctrl.c @@ -33,6 +33,12 @@ #define NFP_Q_STAT_PKTS 0 #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 nfp_abm_ctrl_stat(struct nfp_abm_link *alink, const struct nfp_rtsym *sym, unsigned int stride, unsigned int offset, unsigned int band, @@ -215,10 +221,42 @@ int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm) 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 /= 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 * @@ -273,6 +311,8 @@ int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm) return 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 */ 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 || diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.c b/drivers/net/ethernet/netronome/nfp/abm/main.c index 4f95f7b4430b..aeb0c9a1f260 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.c +++ b/drivers/net/ethernet/netronome/nfp/abm/main.c @@ -315,6 +315,10 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) alink->id = id; 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 * 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) netif_keep_dst(nn->dp.netdev); nfp_abm_vnic_set_mac(app->pf, abm, nn, id); - nfp_abm_ctrl_read_params(alink); INIT_RADIX_TREE(&alink->qdiscs, GFP_KERNEL); return 0; diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.h b/drivers/net/ethernet/netronome/nfp/abm/main.h index 6bb4e60c1ad8..1ca2768cd5a2 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.h +++ b/drivers/net/ethernet/netronome/nfp/abm/main.h @@ -34,9 +34,11 @@ struct nfp_net; * @thresholds: current threshold configuration * @threshold_undef: bitmap of thresholds which have not been set * @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 * in switchdev mode + * * @q_lvls: queue level control area * @qm_stats: queue statistics symbol * @q_stats: basic queue statistics (only in per-band case) @@ -51,8 +53,10 @@ struct nfp_abm { u32 *thresholds; unsigned long *threshold_undef; size_t num_thresholds; + unsigned int prio_map_len; enum devlink_eswitch_mode eswitch_mode; + const struct nfp_rtsym *q_lvls; const struct nfp_rtsym *qm_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, int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink, 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_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, |