From e09303d3c4d9d9f71657550d61eb00bc84c13859 Mon Sep 17 00:00:00 2001 From: Louis Peens Date: Tue, 19 May 2020 16:15:01 +0200 Subject: [PATCH 1/2] nfp: flower: renaming of feature bits Clean up name aliasing. Some features gets enabled using a slightly different method, but the bitmap for these were stored in the same field. Rename their #defines and move the bitmap to a new variable. Signed-off-by: Louis Peens Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/flower/action.c | 4 ++-- drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 4 ++-- drivers/net/ethernet/netronome/nfp/flower/main.c | 14 +++++++------- drivers/net/ethernet/netronome/nfp/flower/main.h | 9 ++++++--- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index 1c76e1592ca2..ff844e5cc41f 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -209,7 +209,7 @@ nfp_fl_output(struct nfp_app *app, struct nfp_fl_output *output, NFP_FL_OUT_FLAGS_USE_TUN); output->port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type); } else if (netif_is_lag_master(out_dev) && - priv->flower_ext_feats & NFP_FL_FEATS_LAG) { + priv->flower_en_feats & NFP_FL_ENABLE_LAG) { int gid; output->flags = cpu_to_be16(tmp_flags); @@ -956,7 +956,7 @@ nfp_flower_output_action(struct nfp_app *app, *a_len += sizeof(struct nfp_fl_output); - if (priv->flower_ext_feats & NFP_FL_FEATS_LAG) { + if (priv->flower_en_feats & NFP_FL_ENABLE_LAG) { /* nfp_fl_pre_lag returns -err or size of prelag action added. * This will be 0 if it is not egressing to a lag dev. */ diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c index a595ddb92bff..a050cb898782 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c @@ -264,7 +264,7 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) nfp_flower_cmsg_portmod_rx(app, skb); break; case NFP_FLOWER_CMSG_TYPE_MERGE_HINT: - if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) { + if (app_priv->flower_en_feats & NFP_FL_ENABLE_FLOW_MERGE) { nfp_flower_cmsg_merge_hint_rx(app, skb); break; } @@ -285,7 +285,7 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) nfp_flower_stats_rlim_reply(app, skb); break; case NFP_FLOWER_CMSG_TYPE_LAG_CONFIG: - if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) { + if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG) { skb_stored = nfp_flower_lag_unprocessed_msg(app, skb); break; } diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index d8ad9346a26a..62c202307940 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -759,7 +759,7 @@ static int nfp_flower_init(struct nfp_app *app) err = nfp_rtsym_write_le(app->pf->rtbl, "_abi_flower_balance_sync_enable", 1); if (!err) { - app_priv->flower_ext_feats |= NFP_FL_FEATS_LAG; + app_priv->flower_ext_feats |= NFP_FL_ENABLE_LAG; nfp_flower_lag_init(&app_priv->nfp_lag); } else if (err == -ENOENT) { nfp_warn(app->cpp, "LAG not supported by FW.\n"); @@ -772,7 +772,7 @@ static int nfp_flower_init(struct nfp_app *app) err = nfp_rtsym_write_le(app->pf->rtbl, "_abi_flower_merge_hint_enable", 1); if (!err) { - app_priv->flower_ext_feats |= NFP_FL_FEATS_FLOW_MERGE; + app_priv->flower_ext_feats |= NFP_FL_ENABLE_FLOW_MERGE; nfp_flower_internal_port_init(app_priv); } else if (err == -ENOENT) { nfp_warn(app->cpp, "Flow merge not supported by FW.\n"); @@ -793,7 +793,7 @@ static int nfp_flower_init(struct nfp_app *app) return 0; err_lag_clean: - if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) + if (app_priv->flower_ext_feats & NFP_FL_ENABLE_LAG) nfp_flower_lag_cleanup(&app_priv->nfp_lag); err_cleanup_metadata: nfp_flower_metadata_cleanup(app); @@ -813,10 +813,10 @@ static void nfp_flower_clean(struct nfp_app *app) if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM) nfp_flower_qos_cleanup(app); - if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) + if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG) nfp_flower_lag_cleanup(&app_priv->nfp_lag); - if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) + if (app_priv->flower_en_feats & NFP_FL_ENABLE_FLOW_MERGE) nfp_flower_internal_port_cleanup(app_priv); nfp_flower_metadata_cleanup(app); @@ -886,7 +886,7 @@ static int nfp_flower_start(struct nfp_app *app) struct nfp_flower_priv *app_priv = app->priv; int err; - if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) { + if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG) { err = nfp_flower_lag_reset(&app_priv->nfp_lag); if (err) return err; @@ -907,7 +907,7 @@ nfp_flower_netdev_event(struct nfp_app *app, struct net_device *netdev, struct nfp_flower_priv *app_priv = app->priv; int ret; - if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) { + if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG) { ret = nfp_flower_lag_netdev_event(app_priv, netdev, event, ptr); if (ret & NOTIFY_STOP_MASK) return ret; diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index d55d0d33bc45..7db3be0b17e9 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -44,8 +44,9 @@ struct nfp_app; #define NFP_FL_FEATS_FLOW_MOD BIT(5) #define NFP_FL_FEATS_PRE_TUN_RULES BIT(6) #define NFP_FL_FEATS_IPV6_TUN BIT(7) -#define NFP_FL_FEATS_FLOW_MERGE BIT(30) -#define NFP_FL_FEATS_LAG BIT(31) + +#define NFP_FL_ENABLE_FLOW_MERGE BIT(0) +#define NFP_FL_ENABLE_LAG BIT(1) struct nfp_fl_mask_id { struct circ_buf mask_id_free_list; @@ -145,6 +146,7 @@ struct nfp_fl_internal_ports { * @mask_id_seed: Seed used for mask hash table * @flower_version: HW version of flower * @flower_ext_feats: Bitmap of extra features the HW supports + * @flower_en_feats: Bitmap of features enabled by HW * @stats_ids: List of free stats ids * @mask_ids: List of free mask ids * @mask_table: Hash table used to store masks @@ -180,6 +182,7 @@ struct nfp_flower_priv { u32 mask_id_seed; u64 flower_version; u64 flower_ext_feats; + u8 flower_en_feats; struct nfp_fl_stats_id stats_ids; struct nfp_fl_mask_id mask_ids; DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS); @@ -346,7 +349,7 @@ nfp_flower_internal_port_can_offload(struct nfp_app *app, { struct nfp_flower_priv *app_priv = app->priv; - if (!(app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE)) + if (!(app_priv->flower_en_feats & NFP_FL_ENABLE_FLOW_MERGE)) return false; if (!netdev->rtnl_link_ops) return false; From 465957c257f3083785fe8e954724cfac2e5d33e9 Mon Sep 17 00:00:00 2001 From: Louis Peens Date: Tue, 19 May 2020 16:15:02 +0200 Subject: [PATCH 2/2] nfp: flower: inform firmware of flower features For backwards compatibility it may be required for the firmware to disable certain features depending on the features supported by the host. Combine the host feature bits and firmware feature bits and write this back to the firmware. Signed-off-by: Louis Peens Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- .../net/ethernet/netronome/nfp/flower/main.c | 106 +++++++++++++----- .../net/ethernet/netronome/nfp/flower/main.h | 11 ++ 2 files changed, 87 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 62c202307940..d054553c75e0 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -665,6 +665,77 @@ static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn) return err; } +static void nfp_flower_wait_host_bit(struct nfp_app *app) +{ + unsigned long err_at; + u64 feat; + int err; + + /* Wait for HOST_ACK flag bit to propagate */ + err_at = jiffies + msecs_to_jiffies(100); + do { + feat = nfp_rtsym_read_le(app->pf->rtbl, + "_abi_flower_combined_features_global", + &err); + if (time_is_before_eq_jiffies(err_at)) { + nfp_warn(app->cpp, + "HOST_ACK bit not propagated in FW.\n"); + break; + } + usleep_range(1000, 2000); + } while (!err && !(feat & NFP_FL_FEATS_HOST_ACK)); + + if (err) + nfp_warn(app->cpp, + "Could not read global features entry from FW\n"); +} + +static int nfp_flower_sync_feature_bits(struct nfp_app *app) +{ + struct nfp_flower_priv *app_priv = app->priv; + int err; + + /* Tell the firmware of the host supported features. */ + err = nfp_rtsym_write_le(app->pf->rtbl, "_abi_flower_host_mask", + app_priv->flower_ext_feats | + NFP_FL_FEATS_HOST_ACK); + if (!err) + nfp_flower_wait_host_bit(app); + else if (err != -ENOENT) + return err; + + /* Tell the firmware that the driver supports lag. */ + err = nfp_rtsym_write_le(app->pf->rtbl, + "_abi_flower_balance_sync_enable", 1); + if (!err) { + app_priv->flower_ext_feats |= NFP_FL_ENABLE_LAG; + nfp_flower_lag_init(&app_priv->nfp_lag); + } else if (err == -ENOENT) { + nfp_warn(app->cpp, "LAG not supported by FW.\n"); + } else { + return err; + } + + if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MOD) { + /* Tell the firmware that the driver supports flow merging. */ + err = nfp_rtsym_write_le(app->pf->rtbl, + "_abi_flower_merge_hint_enable", 1); + if (!err) { + app_priv->flower_ext_feats |= NFP_FL_ENABLE_FLOW_MERGE; + nfp_flower_internal_port_init(app_priv); + } else if (err == -ENOENT) { + nfp_warn(app->cpp, + "Flow merge not supported by FW.\n"); + } else { + return err; + } + } else { + nfp_warn(app->cpp, "Flow mod/merge not supported by FW.\n"); + } + + return 0; +} + static int nfp_flower_init(struct nfp_app *app) { u64 version, features, ctx_count, num_mems; @@ -753,35 +824,11 @@ static int nfp_flower_init(struct nfp_app *app) if (err) app_priv->flower_ext_feats = 0; else - app_priv->flower_ext_feats = features; + app_priv->flower_ext_feats = features & NFP_FL_FEATS_HOST; - /* Tell the firmware that the driver supports lag. */ - err = nfp_rtsym_write_le(app->pf->rtbl, - "_abi_flower_balance_sync_enable", 1); - if (!err) { - app_priv->flower_ext_feats |= NFP_FL_ENABLE_LAG; - nfp_flower_lag_init(&app_priv->nfp_lag); - } else if (err == -ENOENT) { - nfp_warn(app->cpp, "LAG not supported by FW.\n"); - } else { - goto err_cleanup_metadata; - } - - if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MOD) { - /* Tell the firmware that the driver supports flow merging. */ - err = nfp_rtsym_write_le(app->pf->rtbl, - "_abi_flower_merge_hint_enable", 1); - if (!err) { - app_priv->flower_ext_feats |= NFP_FL_ENABLE_FLOW_MERGE; - nfp_flower_internal_port_init(app_priv); - } else if (err == -ENOENT) { - nfp_warn(app->cpp, "Flow merge not supported by FW.\n"); - } else { - goto err_lag_clean; - } - } else { - nfp_warn(app->cpp, "Flow mod/merge not supported by FW.\n"); - } + err = nfp_flower_sync_feature_bits(app); + if (err) + goto err_cleanup; if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM) nfp_flower_qos_init(app); @@ -792,10 +839,9 @@ static int nfp_flower_init(struct nfp_app *app) return 0; -err_lag_clean: +err_cleanup: if (app_priv->flower_ext_feats & NFP_FL_ENABLE_LAG) nfp_flower_lag_cleanup(&app_priv->nfp_lag); -err_cleanup_metadata: nfp_flower_metadata_cleanup(app); err_free_app_priv: vfree(app->priv); diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 7db3be0b17e9..59abea2a39ad 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -44,10 +44,21 @@ struct nfp_app; #define NFP_FL_FEATS_FLOW_MOD BIT(5) #define NFP_FL_FEATS_PRE_TUN_RULES BIT(6) #define NFP_FL_FEATS_IPV6_TUN BIT(7) +#define NFP_FL_FEATS_HOST_ACK BIT(31) #define NFP_FL_ENABLE_FLOW_MERGE BIT(0) #define NFP_FL_ENABLE_LAG BIT(1) +#define NFP_FL_FEATS_HOST \ + (NFP_FL_FEATS_GENEVE | \ + NFP_FL_NBI_MTU_SETTING | \ + NFP_FL_FEATS_GENEVE_OPT | \ + NFP_FL_FEATS_VLAN_PCP | \ + NFP_FL_FEATS_VF_RLIM | \ + NFP_FL_FEATS_FLOW_MOD | \ + NFP_FL_FEATS_PRE_TUN_RULES | \ + NFP_FL_FEATS_IPV6_TUN) + struct nfp_fl_mask_id { struct circ_buf mask_id_free_list; ktime_t *last_used;