Commit bb9a8d03 authored by John Hurley's avatar John Hurley Committed by David S. Miller

nfp: flower: monitor and offload LAG groups

Monitor LAG events via the NETDEV_CHANGEUPPER/NETDEV_CHANGELOWERSTATE
notifiers to maintain a list of offloadable groups. Sync these groups with
HW via a delayed workqueue to prevent excessive re-configuration. When the
workqueue is triggered it may generate multiple control messages for
different groups. These messages are linked via a batch ID and flags to
indicate a new batch and the end of a batch.

Update private data in each repr to track their LAG lower state flags. The
state of a repr is used to determine the active netdevs that can be
offloaded. For example, in active-backup mode, we only offload the netdev
currently active.
Signed-off-by: default avatarJohn Hurley <john.hurley@netronome.com>
Reviewed-by: default avatarPieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f44aa9ef
...@@ -37,6 +37,7 @@ ifeq ($(CONFIG_NFP_APP_FLOWER),y) ...@@ -37,6 +37,7 @@ ifeq ($(CONFIG_NFP_APP_FLOWER),y)
nfp-objs += \ nfp-objs += \
flower/action.o \ flower/action.o \
flower/cmsg.o \ flower/cmsg.o \
flower/lag_conf.o \
flower/main.o \ flower/main.o \
flower/match.o \ flower/match.o \
flower/metadata.o \ flower/metadata.o \
......
This diff is collapsed.
...@@ -575,12 +575,14 @@ static int nfp_flower_init(struct nfp_app *app) ...@@ -575,12 +575,14 @@ static int nfp_flower_init(struct nfp_app *app)
/* Tell the firmware that the driver supports lag. */ /* Tell the firmware that the driver supports lag. */
err = nfp_rtsym_write_le(app->pf->rtbl, err = nfp_rtsym_write_le(app->pf->rtbl,
"_abi_flower_balance_sync_enable", 1); "_abi_flower_balance_sync_enable", 1);
if (!err) if (!err) {
app_priv->flower_ext_feats |= NFP_FL_FEATS_LAG; app_priv->flower_ext_feats |= NFP_FL_FEATS_LAG;
else if (err == -ENOENT) nfp_flower_lag_init(&app_priv->nfp_lag);
} else if (err == -ENOENT) {
nfp_warn(app->cpp, "LAG not supported by FW.\n"); nfp_warn(app->cpp, "LAG not supported by FW.\n");
else } else {
goto err_cleanup_metadata; goto err_cleanup_metadata;
}
return 0; return 0;
...@@ -599,6 +601,9 @@ static void nfp_flower_clean(struct nfp_app *app) ...@@ -599,6 +601,9 @@ static void nfp_flower_clean(struct nfp_app *app)
skb_queue_purge(&app_priv->cmsg_skbs_low); skb_queue_purge(&app_priv->cmsg_skbs_low);
flush_work(&app_priv->cmsg_work); flush_work(&app_priv->cmsg_work);
if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG)
nfp_flower_lag_cleanup(&app_priv->nfp_lag);
nfp_flower_metadata_cleanup(app); nfp_flower_metadata_cleanup(app);
vfree(app->priv); vfree(app->priv);
app->priv = NULL; app->priv = NULL;
...@@ -665,11 +670,29 @@ nfp_flower_repr_change_mtu(struct nfp_app *app, struct net_device *netdev, ...@@ -665,11 +670,29 @@ nfp_flower_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
static int nfp_flower_start(struct nfp_app *app) 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) {
err = nfp_flower_lag_reset(&app_priv->nfp_lag);
if (err)
return err;
err = register_netdevice_notifier(&app_priv->nfp_lag.lag_nb);
if (err)
return err;
}
return nfp_tunnel_config_start(app); return nfp_tunnel_config_start(app);
} }
static void nfp_flower_stop(struct nfp_app *app) static void nfp_flower_stop(struct nfp_app *app)
{ {
struct nfp_flower_priv *app_priv = app->priv;
if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG)
unregister_netdevice_notifier(&app_priv->nfp_lag.lag_nb);
nfp_tunnel_config_stop(app); nfp_tunnel_config_stop(app);
} }
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/idr.h>
struct net_device; struct net_device;
struct nfp_app; struct nfp_app;
...@@ -97,6 +98,30 @@ struct nfp_mtu_conf { ...@@ -97,6 +98,30 @@ struct nfp_mtu_conf {
spinlock_t lock; spinlock_t lock;
}; };
/**
* struct nfp_fl_lag - Flower APP priv data for link aggregation
* @lag_nb: Notifier to track master/slave events
* @work: Work queue for writing configs to the HW
* @lock: Lock to protect lag_group_list
* @group_list: List of all master/slave groups offloaded
* @ida_handle: IDA to handle group ids
* @pkt_num: Incremented for each config packet sent
* @batch_ver: Incremented for each batch of config packets
* @global_inst: Instance allocator for groups
* @rst_cfg: Marker to reset HW LAG config
*/
struct nfp_fl_lag {
struct notifier_block lag_nb;
struct delayed_work work;
struct mutex lock;
struct list_head group_list;
struct ida ida_handle;
unsigned int pkt_num;
unsigned int batch_ver;
u8 global_inst;
bool rst_cfg;
};
/** /**
* struct nfp_flower_priv - Flower APP per-vNIC priv data * struct nfp_flower_priv - Flower APP per-vNIC priv data
* @app: Back pointer to app * @app: Back pointer to app
...@@ -129,6 +154,7 @@ struct nfp_mtu_conf { ...@@ -129,6 +154,7 @@ struct nfp_mtu_conf {
* from firmware for repr reify * from firmware for repr reify
* @reify_wait_queue: wait queue for repr reify response counting * @reify_wait_queue: wait queue for repr reify response counting
* @mtu_conf: Configuration of repr MTU value * @mtu_conf: Configuration of repr MTU value
* @nfp_lag: Link aggregation data block
*/ */
struct nfp_flower_priv { struct nfp_flower_priv {
struct nfp_app *app; struct nfp_app *app;
...@@ -158,6 +184,7 @@ struct nfp_flower_priv { ...@@ -158,6 +184,7 @@ struct nfp_flower_priv {
atomic_t reify_replies; atomic_t reify_replies;
wait_queue_head_t reify_wait_queue; wait_queue_head_t reify_wait_queue;
struct nfp_mtu_conf mtu_conf; struct nfp_mtu_conf mtu_conf;
struct nfp_fl_lag nfp_lag;
}; };
/** /**
...@@ -250,5 +277,8 @@ void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb); ...@@ -250,5 +277,8 @@ void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb); void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb);
int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data, int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data,
void *cb_priv); void *cb_priv);
void nfp_flower_lag_init(struct nfp_fl_lag *lag);
void nfp_flower_lag_cleanup(struct nfp_fl_lag *lag);
int nfp_flower_lag_reset(struct nfp_fl_lag *lag);
#endif #endif
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