Skip to content

Commit

Permalink
nfp: add control message passing capabilities to flower offloads
Browse files Browse the repository at this point in the history
Previously the flower offloads never sends messages to the hardware,
and never registers a handler for receiving messages from hardware.
This patch enables the flower offloads to send control messages to
hardware when adding and removing flow rules. Additionally it
registers a control message rx handler for receiving stats updates
from hardware for each offloaded flow.

Additionally this patch adds 4 control message types; Add, modify and
delete flow, as well as flow stats. It also allows
nfp_flower_cmsg_get_data() to be used outside of cmsg.c.

Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Pieter Jansen van Vuuren authored and David S. Miller committed Jul 1, 2017
1 parent abfcdc1 commit 81f3ddf
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
6 changes: 5 additions & 1 deletion drivers/net/ethernet/netronome/nfp/flower/cmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/skbuff.h>
#include <net/dst_metadata.h>

#include "main.h"
#include "../nfpcore/nfp_cpp.h"
#include "../nfp_net_repr.h"
#include "./cmsg.h"
Expand All @@ -52,7 +53,7 @@ nfp_flower_cmsg_get_hdr(struct sk_buff *skb)
return (struct nfp_flower_cmsg_hdr *)skb->data;
}

static struct sk_buff *
struct sk_buff *
nfp_flower_cmsg_alloc(struct nfp_app *app, unsigned int size,
enum nfp_flower_cmsg_type_port type)
{
Expand Down Expand Up @@ -143,6 +144,9 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
case NFP_FLOWER_CMSG_TYPE_PORT_MOD:
nfp_flower_cmsg_portmod_rx(app, skb);
break;
case NFP_FLOWER_CMSG_TYPE_FLOW_STATS:
nfp_flower_rx_flow_stats(app, skb);
break;
default:
nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n",
type);
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/netronome/nfp/flower/cmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@ struct nfp_flower_cmsg_hdr {

/* Types defined for port related control messages */
enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_FLOW_ADD = 0,
NFP_FLOWER_CMSG_TYPE_FLOW_DEL = 2,
NFP_FLOWER_CMSG_TYPE_PORT_MOD = 8,
NFP_FLOWER_CMSG_TYPE_FLOW_STATS = 15,
NFP_FLOWER_CMSG_TYPE_PORT_ECHO = 16,
NFP_FLOWER_CMSG_TYPE_MAX = 32,
};
Expand Down Expand Up @@ -307,5 +310,8 @@ static inline void *nfp_flower_cmsg_get_data(struct sk_buff *skb)

int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok);
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb);
struct sk_buff *
nfp_flower_cmsg_alloc(struct nfp_app *app, unsigned int size,
enum nfp_flower_cmsg_type_port type);

#endif
59 changes: 59 additions & 0 deletions drivers/net/ethernet/netronome/nfp/flower/offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,52 @@
#include "../nfp_net.h"
#include "../nfp_port.h"

static int
nfp_flower_xmit_flow(struct net_device *netdev,
struct nfp_fl_payload *nfp_flow, u8 mtype)
{
u32 meta_len, key_len, mask_len, act_len, tot_len;
struct nfp_repr *priv = netdev_priv(netdev);
struct sk_buff *skb;
unsigned char *msg;

meta_len = sizeof(struct nfp_fl_rule_metadata);
key_len = nfp_flow->meta.key_len;
mask_len = nfp_flow->meta.mask_len;
act_len = nfp_flow->meta.act_len;

tot_len = meta_len + key_len + mask_len + act_len;

/* Convert to long words as firmware expects
* lengths in units of NFP_FL_LW_SIZ.
*/
nfp_flow->meta.key_len >>= NFP_FL_LW_SIZ;
nfp_flow->meta.mask_len >>= NFP_FL_LW_SIZ;
nfp_flow->meta.act_len >>= NFP_FL_LW_SIZ;

skb = nfp_flower_cmsg_alloc(priv->app, tot_len, mtype);
if (!skb)
return -ENOMEM;

msg = nfp_flower_cmsg_get_data(skb);
memcpy(msg, &nfp_flow->meta, meta_len);
memcpy(&msg[meta_len], nfp_flow->unmasked_data, key_len);
memcpy(&msg[meta_len + key_len], nfp_flow->mask_data, mask_len);
memcpy(&msg[meta_len + key_len + mask_len],
nfp_flow->action_data, act_len);

/* Convert back to bytes as software expects
* lengths in units of bytes.
*/
nfp_flow->meta.key_len <<= NFP_FL_LW_SIZ;
nfp_flow->meta.mask_len <<= NFP_FL_LW_SIZ;
nfp_flow->meta.act_len <<= NFP_FL_LW_SIZ;

nfp_ctrl_tx(priv->app->ctrl, skb);

return 0;
}

static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f)
{
return dissector_uses_key(f->dissector,
Expand Down Expand Up @@ -228,6 +274,11 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
if (err)
goto err_destroy_flow;

err = nfp_flower_xmit_flow(netdev, flow_pay,
NFP_FLOWER_CMSG_TYPE_FLOW_ADD);
if (err)
goto err_destroy_flow;

INIT_HLIST_NODE(&flow_pay->link);
flow_pay->tc_flower_cookie = flow->cookie;
hash_add_rcu(priv->flow_table, &flow_pay->link, flow->cookie);
Expand Down Expand Up @@ -270,7 +321,15 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
return -ENOENT;

err = nfp_modify_flow_metadata(app, nfp_flow);
if (err)
goto err_free_flow;

err = nfp_flower_xmit_flow(netdev, nfp_flow,
NFP_FLOWER_CMSG_TYPE_FLOW_DEL);
if (err)
goto err_free_flow;

err_free_flow:
hash_del_rcu(&nfp_flow->link);
kfree(nfp_flow->action_data);
kfree(nfp_flow->mask_data);
Expand Down

0 comments on commit 81f3ddf

Please sign in to comment.