[PATCH/RFC net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-12 Thread Simon Horman
Allow matching on options in tunnel headers.
This makes use of existing tunnel metadata support.

Options are a bytestring of up to 256 bytes.
Tunnel implementations may support less or more options,
or no options at all.

 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev eth0 ingress
 # tc qdisc del dev eth0 ingress; tc qdisc add dev eth0 ingress
 # tc filter add dev eth0 protocol ip parent : \
 flower indev eth0 \
ip_proto udp \
action tunnel_key \
set src_ip 10.0.99.192 \
dst_ip 10.0.99.193 \
dst_port 4789 \
id 11 \
opts 0102800100800022 \
action mirred egress redirect dev geneve0

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 include/net/flow_dissector.h | 13 +
 include/uapi/linux/pkt_cls.h |  3 +++
 net/sched/cls_flower.c   | 35 ++-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index fc3dce730a6b..43f98bf0b349 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -183,6 +183,18 @@ struct flow_dissector_key_ip {
__u8ttl;
 };
 
+/**
+ * struct flow_dissector_key_enc_opts:
+ * @data: data
+ * @len: len
+ */
+struct flow_dissector_key_enc_opts {
+   u8 data[256];   /* Using IP_TUNNEL_OPTS_MAX is desired here
+* but seems difficult to #include
+*/
+   u8 len;
+};
+
 enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
+   FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
 
FLOW_DISSECTOR_KEY_MAX,
 };
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index d5e2bf68d0d4..7a09a28f21e0 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -467,6 +467,9 @@ enum {
TCA_FLOWER_KEY_IP_TTL,  /* u8 */
TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
 
+   TCA_FLOWER_KEY_ENC_OPTS,
+   TCA_FLOWER_KEY_ENC_OPTS_MASK,
+
__TCA_FLOWER_MAX,
 };
 
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 1a267e77c6de..2a8364ef4fd5 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -51,6 +51,7 @@ struct fl_flow_key {
struct flow_dissector_key_mpls mpls;
struct flow_dissector_key_tcp tcp;
struct flow_dissector_key_ip ip;
+   struct flow_dissector_key_enc_opts enc_opts;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. 
*/
 
 struct fl_flow_mask_range {
@@ -181,6 +182,11 @@ static int fl_classify(struct sk_buff *skb, const struct 
tcf_proto *tp,
skb_key.enc_key_id.keyid = tunnel_id_to_key32(key->tun_id);
skb_key.enc_tp.src = key->tp_src;
skb_key.enc_tp.dst = key->tp_dst;
+
+   if (info->options_len) {
+   skb_key.enc_opts.len = info->options_len;
+   ip_tunnel_info_opts_get(skb_key.enc_opts.data, info);
+   }
}
 
skb_key.indev_ifindex = skb->skb_iif;
@@ -421,6 +427,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 
1] = {
[TCA_FLOWER_KEY_IP_TOS_MASK]= { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TTL_MASK]= { .type = NLA_U8 },
+   [TCA_FLOWER_KEY_ENC_OPTS]   = { .type = NLA_BINARY },
+   [TCA_FLOWER_KEY_ENC_OPTS_MASK]  = { .type = NLA_BINARY },
 };
 
 static void fl_set_key_val(struct nlattr **tb,
@@ -712,6 +720,26 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
   >enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
   sizeof(key->enc_tp.dst));
 
+   if (tb[TCA_FLOWER_KEY_ENC_OPTS]) {
+   key->enc_opts.len = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS]);
+
+   if (key->enc_opts.len > sizeof(key->enc_opts.data))
+   return -EINVAL;
+
+   /* enc_opts is variable length.
+* If present ensure the value and mask are the same length.
+*/
+   if (tb[TCA_FLOWER_KEY_ENC_OPTS_MASK] &&
+   nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]) != 
key->enc_opts.len)
+   return -EINVAL;
+
+   mask->enc_opts.len = key->enc_opts.len;
+   fl_set_key_val(tb, key->enc_opts.data, TCA_FLO

[PATCH/RFC net-next 1/2] net/sched: add tunnel option support to act_tunnel_key

2017-09-12 Thread Simon Horman
Allow setting tunnel options using the act_tunnel_key action.

Options are a bitwise maskable bytestring of up to 256 bytes.
Tunnel implementations may support less or more options,
or no options at all.

e.g.
 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc del dev geneve0 ingress
 # tc filter add dev geneve0 protocol ip parent : \
 flower \
   enc_src_ip 10.0.99.192 \
   enc_dst_ip 10.0.99.193 \
   enc_key_id 11 \
   enc_opts 0102800100800020/fff0 \
   ip_proto udp \
   action mirred egress redirect dev eth1

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 include/uapi/linux/tc_act/tc_tunnel_key.h |  1 +
 net/sched/act_tunnel_key.c| 26 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h 
b/include/uapi/linux/tc_act/tc_tunnel_key.h
index afcd4be953e2..e0cb1121d132 100644
--- a/include/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h
@@ -35,6 +35,7 @@ enum {
TCA_TUNNEL_KEY_PAD,
TCA_TUNNEL_KEY_ENC_DST_PORT,/* be16 */
TCA_TUNNEL_KEY_NO_CSUM, /* u8 */
+   TCA_TUNNEL_KEY_ENC_OPTS,
__TCA_TUNNEL_KEY_MAX,
 };
 
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 30c96274c638..77b5890a48b9 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -66,6 +66,7 @@ static const struct nla_policy 
tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
[TCA_TUNNEL_KEY_ENC_KEY_ID]   = { .type = NLA_U32 },
[TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
[TCA_TUNNEL_KEY_NO_CSUM]  = { .type = NLA_U8 },
+   [TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NLA_BINARY },
 };
 
 static int tunnel_key_init(struct net *net, struct nlattr *nla,
@@ -81,9 +82,11 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
struct tcf_tunnel_key *t;
bool exists = false;
__be16 dst_port = 0;
+   int opts_len = 0;
__be64 key_id;
__be16 flags;
int ret = 0;
+   u8 *opts;
int err;
 
if (!nla)
@@ -121,6 +124,11 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
dst_port = 
nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
 
+   if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
+   opts = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
+   opts_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
+   }
+
if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
__be32 saddr;
@@ -131,7 +139,7 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
 
metadata = __ip_tun_set_dst(saddr, daddr, 0, 0,
dst_port, flags,
-   key_id, 0);
+   key_id, opts_len);
} else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
   tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
struct in6_addr saddr;
@@ -142,9 +150,13 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
 
metadata = __ipv6_tun_set_dst(, , 0, 0, 
dst_port,
  0, flags,
- key_id, 0);
+ key_id, opts_len);
}
 
+   if (opts_len)
+   ip_tunnel_info_opts_set(>u.tun_info,
+   opts, opts_len);
+
if (!metadata) {
ret = -EINVAL;
goto err_out;
@@ -264,8 +276,9 @@ static int tunnel_key_dump(struct sk_buff *skb, struct 
tc_action *a,
goto nla_put_failure;
 
if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
-   struct ip_tunnel_key *key =
-   >tcft_enc_metadata->u.tun_info.key;
+   struct ip_tunnel_info *info =
+   >tcft_enc_metadata->u.tun_info;
+   struct ip_tunnel_key *key = >key;
__be32 key_id = tunnel_id_to_key32(key->tun_id);
 
if (nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id) ||
@@ -273,7 +286,10 @@ static int tunnel_key_dump(struct sk_buff *skb, struct 
tc_action *a,
  
>tcft_enc_metadata->u.tun_info) ||
nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT, key->tp_dst) 
||
nla_put_u8(skb, TCA_TUNNEL_KEY_NO_CSUM,

[PATCH net-next 1/7] nfp: add helper to get flower cmsg length

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Add a helper function that returns the length of the cmsg data when given
the cmsg skb

Signed-off-by: John Hurley <john.hur...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 5 +
 drivers/net/ethernet/netronome/nfp/flower/metadata.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index a2ec60344236..7a5ccf0cc7c2 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -323,6 +323,11 @@ static inline void *nfp_flower_cmsg_get_data(struct 
sk_buff *skb)
return (unsigned char *)skb->data + NFP_FLOWER_CMSG_HLEN;
 }
 
+static inline int nfp_flower_cmsg_get_data_len(struct sk_buff *skb)
+{
+   return skb->len - NFP_FLOWER_CMSG_HLEN;
+}
+
 struct sk_buff *
 nfp_flower_cmsg_mac_repr_start(struct nfp_app *app, unsigned int num_ports);
 void
diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c 
b/drivers/net/ethernet/netronome/nfp/flower/metadata.c
index 3226ddc55f99..193520ef23f0 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c
@@ -140,7 +140,7 @@ nfp_flower_update_stats(struct nfp_app *app, struct 
nfp_fl_stats_frame *stats)
 
 void nfp_flower_rx_flow_stats(struct nfp_app *app, struct sk_buff *skb)
 {
-   unsigned int msg_len = skb->len - NFP_FLOWER_CMSG_HLEN;
+   unsigned int msg_len = nfp_flower_cmsg_get_data_len(skb);
struct nfp_fl_stats_frame *stats_frame;
unsigned char *msg;
int i;
-- 
2.1.4



[PATCH net-next 0/7] nfp: flower vxlan tunnel offload

2017-09-25 Thread Simon Horman
From: Simon Horman <simon.hor...@netronome.com>

John says:

This patch set allows offloading of TC flower match and set tunnel fields
to the NFP. The initial focus is on VXLAN traffic. Due to the current
state of the NFP firmware, only VXLAN traffic on well known port 4789 is
handled. The match and action fields must explicity set this value to be
supported. Tunnel end point information is also offloaded to the NFP for
both encapsulation and decapsulation. The NFP expects 3 separate data sets
to be supplied.

For decapsulation, 2 separate lists exist; a list of MAC addresses
referenced by an index comprised of the port number, and a list of IP
addresses. These IP addresses are not connected to a MAC or port. The MAC
addresses can be written as a block or one at a time (because they have an
index, previous values can be overwritten) while the IP addresses are
always written as a list of all the available IPs. Because the MAC address
used as a tunnel end point may be associated with a physical port or may
be a virtual netdev like an OVS bridge, we do not know which addresses
should be offloaded. For this reason, all MAC addresses of active netdevs
are offloaded to the NFP. A notifier checks for changes to any currently
offloaded MACs or any new netdevs that may occur. For IP addresses, the
tunnel end point used in the rules is known as the destination IP address
must be specified in the flower classifier rule. When a new IP address
appears in a rule, the IP address is offloaded. The IP is removed from the
offloaded list when all rules matching on that IP are deleted.

For encapsulation, a next hop table is updated on the NFP that contains
the source/dest IPs, MACs and egress port. These are written individually
when requested. If the NFP tries to encapsulate a packet but does not know
the next hop, then is sends a request to the host. The host carries out a
route lookup and populates the given entry on the NFP table. A notifier
also exists to check for any links changing or going down in the kernel
next hop table. If an offloaded next hop entry is removed from the kernel
then it is also removed on the NFP.

The NFP periodically sends a message to the host telling it which tunnel
ports have packets egressing the system. The host uses this information to
update the used value in the neighbour entry. This means that, rather than
expire when it times out, the kernel will send an ARP to check if the link
is still live. From an NFP perspective, this means that valid entries will
not be removed from its next hop table.

John Hurley (7):
  nfp: add helper to get flower cmsg length
  nfp: compile flower vxlan tunnel metadata match fields
  nfp: compile flower vxlan tunnel set actions
  nfp: offload flower vxlan endpoint MAC addresses
  nfp: offload vxlan IPv4 endpoints of flower rules
  nfp: flower vxlan neighbour offload
  nfp: flower vxlan neighbour keep-alive

 drivers/net/ethernet/netronome/nfp/Makefile|   3 +-
 drivers/net/ethernet/netronome/nfp/flower/action.c | 169 -
 drivers/net/ethernet/netronome/nfp/flower/cmsg.c   |  16 +-
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |  87 ++-
 drivers/net/ethernet/netronome/nfp/flower/main.c   |  13 +
 drivers/net/ethernet/netronome/nfp/flower/main.h   |  35 +
 drivers/net/ethernet/netronome/nfp/flower/match.c  |  75 +-
 .../net/ethernet/netronome/nfp/flower/metadata.c   |   2 +-
 .../net/ethernet/netronome/nfp/flower/offload.c|  74 +-
 .../ethernet/netronome/nfp/flower/tunnel_conf.c| 811 +
 10 files changed, 1243 insertions(+), 42 deletions(-)
 create mode 100644 drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c

-- 
2.1.4



[PATCH net-next 5/7] nfp: offload vxlan IPv4 endpoints of flower rules

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Maintain a list of IPv4 addresses used as the tunnel destination IP match
fields in currently active flower rules. Offload the entire list of
NFP_FL_IPV4_ADDRS_MAX (even if some are unused) when new IPs are added or
removed. The NFP should only be aware of tunnel end points that are
currently used by rules on the device

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Simon Horman <simon.hor...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |   1 +
 drivers/net/ethernet/netronome/nfp/flower/main.h   |   7 ++
 drivers/net/ethernet/netronome/nfp/flower/match.c  |  14 ++-
 .../net/ethernet/netronome/nfp/flower/offload.c|   4 +
 .../ethernet/netronome/nfp/flower/tunnel_conf.c| 120 +
 5 files changed, 143 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index dc248193c996..6540bb1ceefb 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -318,6 +318,7 @@ enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_MAC_REPR = 7,
NFP_FLOWER_CMSG_TYPE_PORT_MOD = 8,
NFP_FLOWER_CMSG_TYPE_TUN_MAC =  11,
+   NFP_FLOWER_CMSG_TYPE_TUN_IPS =  14,
NFP_FLOWER_CMSG_TYPE_FLOW_STATS =   15,
NFP_FLOWER_CMSG_TYPE_PORT_ECHO =16,
NFP_FLOWER_CMSG_TYPE_MAX =  32,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h 
b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 9de375acc254..53306af6cfe8 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -86,8 +86,10 @@ struct nfp_fl_stats_id {
  * @cmsg_skbs: List of skbs for control message processing
  * @nfp_mac_off_list:  List of MAC addresses to offload
  * @nfp_mac_index_list:List of unique 8-bit indexes for non NFP netdevs
+ * @nfp_ipv4_off_list: List of IPv4 addresses to offload
  * @nfp_mac_off_lock:  Lock for the MAC address list
  * @nfp_mac_index_lock:Lock for the MAC index list
+ * @nfp_ipv4_off_lock: Lock for the IPv4 address list
  * @nfp_mac_off_ids:   IDA to manage id assignment for offloaded macs
  * @nfp_mac_off_count: Number of MACs in address list
  * @nfp_tun_mac_nb:Notifier to monitor link state
@@ -105,8 +107,10 @@ struct nfp_flower_priv {
struct sk_buff_head cmsg_skbs;
struct list_head nfp_mac_off_list;
struct list_head nfp_mac_index_list;
+   struct list_head nfp_ipv4_off_list;
struct mutex nfp_mac_off_lock;
struct mutex nfp_mac_index_lock;
+   struct mutex nfp_ipv4_off_lock;
struct ida nfp_mac_off_ids;
int nfp_mac_off_count;
struct notifier_block nfp_tun_mac_nb;
@@ -142,6 +146,7 @@ struct nfp_fl_payload {
struct rcu_head rcu;
spinlock_t lock; /* lock stats */
struct nfp_fl_stats stats;
+   __be32 nfp_tun_ipv4_addr;
char *unmasked_data;
char *mask_data;
char *action_data;
@@ -182,5 +187,7 @@ void nfp_flower_rx_flow_stats(struct nfp_app *app, struct 
sk_buff *skb);
 int nfp_tunnel_config_start(struct nfp_app *app);
 void nfp_tunnel_config_stop(struct nfp_app *app);
 void nfp_tunnel_write_macs(struct nfp_app *app);
+void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4);
+void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4);
 
 #endif
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c 
b/drivers/net/ethernet/netronome/nfp/flower/match.c
index cb3ff6c126e8..865a815ab92a 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -195,7 +195,7 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
 static void
 nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
 struct tc_cls_flower_offload *flow,
-bool mask_version)
+bool mask_version, __be32 *tun_dst)
 {
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
struct flow_dissector_key_ipv4_addrs *vxlan_ips;
@@ -223,6 +223,7 @@ nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
 target);
frame->ip_src = vxlan_ips->src;
frame->ip_dst = vxlan_ips->dst;
+   *tun_dst = vxlan_ips->dst;
}
 }
 
@@ -232,6 +233,7 @@ int nfp_flower_compile_flow_match(struct 
tc_cls_flower_offload *flow,
  struct nfp_fl_payload *nfp_flow)
 {
enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
+   __be32 tun_dst, tun_dst_mask = 0;
struct nfp_repr *netdev_repr;
int er

[PATCH net-next 7/7] nfp: flower vxlan neighbour keep-alive

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Periodically receive messages containing the destination IPs of tunnels
that have recently forwarded traffic. Update the neighbour entries 'used'
value for these IPs next hop.

This prevents the neighbour entry from expiring on timeout but rather
signals an ARP to verify the connection. From an NFP perspective, packets
will not fall back mid-flow unless the link is verified to be down.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Simon Horman <simon.hor...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.c   |  3 +
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |  1 +
 drivers/net/ethernet/netronome/nfp/flower/main.h   |  1 +
 .../ethernet/netronome/nfp/flower/tunnel_conf.c| 64 ++
 4 files changed, 69 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
index 862787daaa68..6b71c719deba 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
@@ -184,6 +184,9 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct 
sk_buff *skb)
case NFP_FLOWER_CMSG_TYPE_NO_NEIGH:
nfp_tunnel_request_route(app, skb);
break;
+   case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
+   nfp_tunnel_keep_alive(app, skb);
+   break;
case NFP_FLOWER_CMSG_TYPE_TUN_NEIGH:
/* Acks from the NFP that the route is added - ignore. */
break;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index 1dc72a1ed577..504ddaa21701 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -319,6 +319,7 @@ enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_PORT_MOD = 8,
NFP_FLOWER_CMSG_TYPE_NO_NEIGH = 10,
NFP_FLOWER_CMSG_TYPE_TUN_MAC =  11,
+   NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS =  12,
NFP_FLOWER_CMSG_TYPE_TUN_NEIGH =13,
NFP_FLOWER_CMSG_TYPE_TUN_IPS =  14,
NFP_FLOWER_CMSG_TYPE_FLOW_STATS =   15,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h 
b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 93ad969c3653..12c319a219d8 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -196,5 +196,6 @@ void nfp_tunnel_write_macs(struct nfp_app *app);
 void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4);
 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4);
 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);
 
 #endif
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c 
b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index 8c6b88a1306b..c495f8f38506 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -36,12 +36,36 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "cmsg.h"
 #include "main.h"
 #include "../nfp_net_repr.h"
 #include "../nfp_net.h"
 
+#define NFP_FL_MAX_ROUTES   32
+
+/**
+ * struct nfp_tun_active_tuns - periodic message of active tunnels
+ * @seq:   sequence number of the message
+ * @count: number of tunnels report in message
+ * @flags: options part of the request
+ * @ipv4:  dest IPv4 address of active route
+ * @egress_port:   port the encapsulated packet egressed
+ * @extra: reserved for future use
+ * @tun_info:  tunnels that have sent traffic in reported period
+ */
+struct nfp_tun_active_tuns {
+   __be32 seq;
+   __be32 count;
+   __be32 flags;
+   struct route_ip_info {
+   __be32 ipv4;
+   __be32 egress_port;
+   __be32 extra[2];
+   } tun_info[];
+};
+
 /**
  * struct nfp_tun_neigh - neighbour/route entry on the NFP
  * @dst_ipv4:  destination IPv4 address
@@ -147,6 +171,46 @@ struct nfp_tun_mac_non_nfp_idx {
struct list_head list;
 };
 
+void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb)
+{
+   struct nfp_tun_active_tuns *payload;
+   struct net_device *netdev;
+   int count, i, pay_len;
+   struct neighbour *n;
+   __be32 ipv4_addr;
+   u32 port;
+
+   payload = nfp_flower_cmsg_get_data(skb);
+   count = be32_to_cpu(payload->count);
+   if (count > NFP_FL_MAX_ROUTES) {
+   nfp_flower_cmsg_warn(app, "Tunnel keep-alive request exceeds 
max routes.\n");
+   return;
+   }
+
+   p

[PATCH net-next 2/7] nfp: compile flower vxlan tunnel metadata match fields

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Compile ovs-tc flower vxlan metadata match fields for offloading. Only
support offload of tunnel data when the VXLAN port specifically matches
well known port 4789.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   | 38 
 drivers/net/ethernet/netronome/nfp/flower/main.h   |  2 +
 drivers/net/ethernet/netronome/nfp/flower/match.c  | 60 +--
 .../net/ethernet/netronome/nfp/flower/offload.c| 70 +++---
 4 files changed, 158 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index 7a5ccf0cc7c2..af9165b3b652 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -83,6 +83,14 @@
 #define NFP_FL_PUSH_VLAN_CFI   BIT(12)
 #define NFP_FL_PUSH_VLAN_VID   GENMASK(11, 0)
 
+/* Tunnel ports */
+#define NFP_FL_PORT_TYPE_TUN   0x5000
+
+enum nfp_flower_tun_type {
+   NFP_FL_TUNNEL_NONE =0,
+   NFP_FL_TUNNEL_VXLAN =   2,
+};
+
 struct nfp_fl_output {
__be16 a_op;
__be16 flags;
@@ -230,6 +238,36 @@ struct nfp_flower_ipv6 {
struct in6_addr ipv6_dst;
 };
 
+/* Flow Frame VXLAN --> Tunnel details (4W/16B)
+ * -
+ *3   2   1
+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ipv4_addr_src |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ipv4_addr_dst |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   tun_flags   |   tos |   ttl |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   gpe_flags   |Reserved   | Next Protocol |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VNI   |   Reserved|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_vxlan {
+   __be32 ip_src;
+   __be32 ip_dst;
+   __be16 tun_flags;
+   u8 tos;
+   u8 ttl;
+   u8 gpe_flags;
+   u8 reserved[2];
+   u8 nxt_proto;
+   __be32 tun_id;
+};
+
+#define NFP_FL_TUN_VNI_OFFSET 8
+
 /* The base header for a control message packet.
  * Defines an 8-bit version, and an 8-bit type, padded
  * to a 32-bit word. Rest of the packet is type-specific.
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h 
b/drivers/net/ethernet/netronome/nfp/flower/main.h
index c20dd00a1cae..cd695eabce02 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -58,6 +58,8 @@ struct nfp_app;
 #define NFP_FL_MASK_REUSE_TIME_NS  4
 #define NFP_FL_MASK_ID_LOCATION1
 
+#define NFP_FL_VXLAN_PORT  4789
+
 struct nfp_fl_mask_id {
struct circ_buf mask_id_free_list;
struct timespec64 *last_used;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c 
b/drivers/net/ethernet/netronome/nfp/flower/match.c
index d25b5038c3a2..1fd1bab0611f 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -77,14 +77,17 @@ nfp_flower_compile_meta(struct nfp_flower_meta_one *frame, 
u8 key_type)
 
 static int
 nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
-   bool mask_version)
+   bool mask_version, enum nfp_flower_tun_type tun_type)
 {
if (mask_version) {
frame->in_port = cpu_to_be32(~0);
return 0;
}
 
-   frame->in_port = cpu_to_be32(cmsg_port);
+   if (tun_type)
+   frame->in_port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type);
+   else
+   frame->in_port = cpu_to_be32(cmsg_port);
 
return 0;
 }
@@ -189,15 +192,53 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
}
 }
 
+static void
+nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
+struct tc_cls_flower_offload *flow,
+bool mask_version)
+{
+   struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
+   struct flow_dissector_key_ipv4_addrs *vxlan_ips;
+   struct flow_dissector_key_keyid *vni;
+
+   /* Wildcard TOS/TTL/GPE_FLAGS/NXT_PROTO for now. */
+   memset(frame, 0, sizeof(struct nfp_flower_vxlan));
+
+   if (dissector_uses_key(flow->dissector,
+

[PATCH net-next 6/7] nfp: flower vxlan neighbour offload

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Receive a request when the NFP does not know the next hop for a packet
that is to be encapsulated in a VXLAN tunnel. Do a route lookup, determine
the next hop entry and update neighbour table on NFP. Monitor the kernel
neighbour table for link changes and update NFP with relevant information.
Overwrite routes with zero values on the NFP when they expire.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Simon Horman <simon.hor...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.c   |   6 +
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |   2 +
 drivers/net/ethernet/netronome/nfp/flower/main.h   |   7 +
 .../ethernet/netronome/nfp/flower/tunnel_conf.c| 253 +
 4 files changed, 268 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
index b756006dba6f..862787daaa68 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
@@ -181,6 +181,12 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct 
sk_buff *skb)
case NFP_FLOWER_CMSG_TYPE_FLOW_STATS:
nfp_flower_rx_flow_stats(app, skb);
break;
+   case NFP_FLOWER_CMSG_TYPE_NO_NEIGH:
+   nfp_tunnel_request_route(app, skb);
+   break;
+   case NFP_FLOWER_CMSG_TYPE_TUN_NEIGH:
+   /* Acks from the NFP that the route is added - ignore. */
+   break;
default:
nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control 
type %u\n",
 type);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index 6540bb1ceefb..1dc72a1ed577 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -317,7 +317,9 @@ enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_FLOW_DEL = 2,
NFP_FLOWER_CMSG_TYPE_MAC_REPR = 7,
NFP_FLOWER_CMSG_TYPE_PORT_MOD = 8,
+   NFP_FLOWER_CMSG_TYPE_NO_NEIGH = 10,
NFP_FLOWER_CMSG_TYPE_TUN_MAC =  11,
+   NFP_FLOWER_CMSG_TYPE_TUN_NEIGH =13,
NFP_FLOWER_CMSG_TYPE_TUN_IPS =  14,
NFP_FLOWER_CMSG_TYPE_FLOW_STATS =   15,
NFP_FLOWER_CMSG_TYPE_PORT_ECHO =16,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h 
b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 53306af6cfe8..93ad969c3653 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -87,12 +87,15 @@ struct nfp_fl_stats_id {
  * @nfp_mac_off_list:  List of MAC addresses to offload
  * @nfp_mac_index_list:List of unique 8-bit indexes for non NFP netdevs
  * @nfp_ipv4_off_list: List of IPv4 addresses to offload
+ * @nfp_neigh_off_list:List of neighbour offloads
  * @nfp_mac_off_lock:  Lock for the MAC address list
  * @nfp_mac_index_lock:Lock for the MAC index list
  * @nfp_ipv4_off_lock: Lock for the IPv4 address list
+ * @nfp_neigh_off_lock:Lock for the neighbour address list
  * @nfp_mac_off_ids:   IDA to manage id assignment for offloaded macs
  * @nfp_mac_off_count: Number of MACs in address list
  * @nfp_tun_mac_nb:Notifier to monitor link state
+ * @nfp_tun_neigh_nb:  Notifier to monitor neighbour state
  */
 struct nfp_flower_priv {
struct nfp_app *app;
@@ -108,12 +111,15 @@ struct nfp_flower_priv {
struct list_head nfp_mac_off_list;
struct list_head nfp_mac_index_list;
struct list_head nfp_ipv4_off_list;
+   struct list_head nfp_neigh_off_list;
struct mutex nfp_mac_off_lock;
struct mutex nfp_mac_index_lock;
struct mutex nfp_ipv4_off_lock;
+   struct mutex nfp_neigh_off_lock;
struct ida nfp_mac_off_ids;
int nfp_mac_off_count;
struct notifier_block nfp_tun_mac_nb;
+   struct notifier_block nfp_tun_neigh_nb;
 };
 
 struct nfp_fl_key_ls {
@@ -189,5 +195,6 @@ void nfp_tunnel_config_stop(struct nfp_app *app);
 void nfp_tunnel_write_macs(struct nfp_app *app);
 void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4);
 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4);
+void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb);
 
 #endif
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c 
b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index 185505140f5e..8c6b88a1306b 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -33,6 +33,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -41,6 +42,44 @@
 #inc

[PATCH net-next 3/7] nfp: compile flower vxlan tunnel set actions

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Compile set tunnel actions for tc flower. Only support VXLAN and ensure a
tunnel destination port of 4789 is used.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/action.c | 169 ++---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |  31 +++-
 2 files changed, 179 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c 
b/drivers/net/ethernet/netronome/nfp/flower/action.c
index db9750695dc7..38f3835ae176 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "cmsg.h"
 #include "main.h"
@@ -80,14 +81,27 @@ nfp_fl_push_vlan(struct nfp_fl_push_vlan *push_vlan,
push_vlan->vlan_tci = cpu_to_be16(tmp_push_vlan_tci);
 }
 
+static bool nfp_fl_netdev_is_tunnel_type(struct net_device *out_dev,
+enum nfp_flower_tun_type tun_type)
+{
+   if (!out_dev->rtnl_link_ops)
+   return false;
+
+   if (!strcmp(out_dev->rtnl_link_ops->kind, "vxlan"))
+   return tun_type == NFP_FL_TUNNEL_VXLAN;
+
+   return false;
+}
+
 static int
 nfp_fl_output(struct nfp_fl_output *output, const struct tc_action *action,
  struct nfp_fl_payload *nfp_flow, bool last,
- struct net_device *in_dev)
+ struct net_device *in_dev, enum nfp_flower_tun_type tun_type,
+ int *tun_out_cnt)
 {
size_t act_size = sizeof(struct nfp_fl_output);
+   u16 tmp_output_op, tmp_flags;
struct net_device *out_dev;
-   u16 tmp_output_op;
int ifindex;
 
/* Set action opcode to output action. */
@@ -97,25 +111,114 @@ nfp_fl_output(struct nfp_fl_output *output, const struct 
tc_action *action,
 
output->a_op = cpu_to_be16(tmp_output_op);
 
-   /* Set action output parameters. */
-   output->flags = cpu_to_be16(last ? NFP_FL_OUT_FLAGS_LAST : 0);
-
ifindex = tcf_mirred_ifindex(action);
out_dev = __dev_get_by_index(dev_net(in_dev), ifindex);
if (!out_dev)
return -EOPNOTSUPP;
 
-   /* Only offload egress ports are on the same device as the ingress
-* port.
+   tmp_flags = last ? NFP_FL_OUT_FLAGS_LAST : 0;
+
+   if (tun_type) {
+   /* Verify the egress netdev matches the tunnel type. */
+   if (!nfp_fl_netdev_is_tunnel_type(out_dev, tun_type))
+   return -EOPNOTSUPP;
+
+   if (*tun_out_cnt)
+   return -EOPNOTSUPP;
+   (*tun_out_cnt)++;
+
+   output->flags = cpu_to_be16(tmp_flags |
+   NFP_FL_OUT_FLAGS_USE_TUN);
+   output->port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type);
+   } else {
+   /* Set action output parameters. */
+   output->flags = cpu_to_be16(tmp_flags);
+
+   /* Only offload if egress ports are on the same device as the
+* ingress port.
+*/
+   if (!switchdev_port_same_parent_id(in_dev, out_dev))
+   return -EOPNOTSUPP;
+
+   output->port = cpu_to_be32(nfp_repr_get_port_id(out_dev));
+   if (!output->port)
+   return -EOPNOTSUPP;
+   }
+   nfp_flow->meta.shortcut = output->port;
+
+   return 0;
+}
+
+static bool nfp_fl_supported_tun_port(const struct tc_action *action)
+{
+   struct ip_tunnel_info *tun = tcf_tunnel_info(action);
+
+   return tun->key.tp_dst == htons(NFP_FL_VXLAN_PORT);
+}
+
+static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char *act_data, int act_len)
+{
+   size_t act_size = sizeof(struct nfp_fl_pre_tunnel);
+   struct nfp_fl_pre_tunnel *pre_tun_act;
+   u16 tmp_pre_tun_op;
+
+   /* Pre_tunnel action must be first on action list.
+* If other actions already exist they need pushed forward.
 */
-   if (!switchdev_port_same_parent_id(in_dev, out_dev))
-   return -EOPNOTSUPP;
+   if (act_len)
+   memmove(act_data + act_size, act_data, act_len);
+
+   pre_tun_act = (struct nfp_fl_pre_tunnel *)act_data;
+
+   memset(pre_tun_act, 0, act_size);
+
+   tmp_pre_tun_op =
+   FIELD_PREP(NFP_FL_ACT_LEN_LW, act_size >> NFP_FL_LW_SIZ) |
+   FIELD_PREP(NFP_FL_ACT_JMP_ID, NFP_FL_ACTION_OPCODE_PRE_TUNNEL);
+
+   pre_tun_act->a_op = cpu_to_be16(tmp_pre_tun_op);
 
-   output->port = cpu_to_be32(nfp_repr_get_port_id(out_dev));
-   if (!output->port)
+   return pre_tun_act;
+}
+
+static int
+nfp_fl_set_vxlan(struct nfp_fl_set_vxlan *set_v

[PATCH net-next 4/7] nfp: offload flower vxlan endpoint MAC addresses

2017-09-25 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Generate a list of MAC addresses of netdevs that could be used as VXLAN
tunnel end points. Give offloaded MACs an index for storage on the NFP in
the ranges:
0x100-0x1ff physical port representors
0x200-0x2ff VF port representors
0x300-0x3ff other offloads (e.g. vxlan netdevs, ovs bridges)

Assign phys and vf indexes based on unique 8 bit values in the port num.
Maintain list of other netdevs to ensure same netdev is not offloaded
twice and each gets a unique ID without exhausting the entries. Because
the IDs are unique but constant for a netdev, any changes are implemented
by overwriting the index on NFP.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/Makefile|   3 +-
 drivers/net/ethernet/netronome/nfp/flower/cmsg.c   |   7 -
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |   9 +
 drivers/net/ethernet/netronome/nfp/flower/main.c   |  13 +
 drivers/net/ethernet/netronome/nfp/flower/main.h   |  18 +
 drivers/net/ethernet/netronome/nfp/flower/match.c  |   7 +
 .../ethernet/netronome/nfp/flower/tunnel_conf.c| 374 +
 7 files changed, 423 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c

diff --git a/drivers/net/ethernet/netronome/nfp/Makefile 
b/drivers/net/ethernet/netronome/nfp/Makefile
index 96e579a15cbe..becaacf1554d 100644
--- a/drivers/net/ethernet/netronome/nfp/Makefile
+++ b/drivers/net/ethernet/netronome/nfp/Makefile
@@ -37,7 +37,8 @@ nfp-objs += \
flower/main.o \
flower/match.o \
flower/metadata.o \
-   flower/offload.o
+   flower/offload.o \
+   flower/tunnel_conf.o
 endif
 
 ifeq ($(CONFIG_BPF_SYSCALL),y)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
index c3ca05d10fe1..b756006dba6f 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
@@ -38,17 +38,10 @@
 #include 
 
 #include "main.h"
-#include "../nfpcore/nfp_cpp.h"
 #include "../nfp_net.h"
 #include "../nfp_net_repr.h"
 #include "./cmsg.h"
 
-#define nfp_flower_cmsg_warn(app, fmt, args...)
\
-   do {\
-   if (net_ratelimit())\
-   nfp_warn((app)->cpp, fmt, ## args); \
-   } while (0)
-
 static struct nfp_flower_cmsg_hdr *
 nfp_flower_cmsg_get_hdr(struct sk_buff *skb)
 {
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index ff42ce8a1e9c..dc248193c996 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -39,6 +39,7 @@
 #include 
 
 #include "../nfp_app.h"
+#include "../nfpcore/nfp_cpp.h"
 
 #define NFP_FLOWER_LAYER_META  BIT(0)
 #define NFP_FLOWER_LAYER_PORT  BIT(1)
@@ -90,6 +91,12 @@
 #define NFP_FL_IPV4_TUNNEL_TYPEGENMASK(7, 4)
 #define NFP_FL_IPV4_PRE_TUN_INDEX  GENMASK(2, 0)
 
+#define nfp_flower_cmsg_warn(app, fmt, args...) \
+   do {\
+   if (net_ratelimit())\
+   nfp_warn((app)->cpp, fmt, ## args); \
+   } while (0)
+
 enum nfp_flower_tun_type {
NFP_FL_TUNNEL_NONE =0,
NFP_FL_TUNNEL_VXLAN =   2,
@@ -310,6 +317,7 @@ enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_FLOW_DEL = 2,
NFP_FLOWER_CMSG_TYPE_MAC_REPR = 7,
NFP_FLOWER_CMSG_TYPE_PORT_MOD = 8,
+   NFP_FLOWER_CMSG_TYPE_TUN_MAC =  11,
NFP_FLOWER_CMSG_TYPE_FLOW_STATS =   15,
NFP_FLOWER_CMSG_TYPE_PORT_ECHO =16,
NFP_FLOWER_CMSG_TYPE_MAX =  32,
@@ -343,6 +351,7 @@ enum nfp_flower_cmsg_port_type {
NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC =  0x0,
NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT =   0x1,
NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT =   0x2,
+   NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT =  0x3,
 };
 
 enum nfp_flower_cmsg_port_vnic_type {
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c 
b/drivers/net/ethernet/netronome/nfp/flower/main.c
index 91fe03617106..e46e7c60d491 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -436,6 +436,16 @@ static void nfp_flower_clean(struct nfp_app *app)
app->priv = NULL;
 }
 
+static int nfp_flower_start(struct nfp_app *app)
+{
+   return nfp_tunnel_config_start(app);
+}
+
+static voi

Re: [Patch net-next] net_sched: use idr to allocate u32 filter handles

2017-09-29 Thread Simon Horman
On Thu, Sep 28, 2017 at 03:19:05PM -0700, Cong Wang wrote:
> On Thu, Sep 28, 2017 at 12:34 AM, Simon Horman
> <simon.hor...@netronome.com> wrote:
> > Hi Cong,
> >
> > this looks like a nice enhancement to me. Did you measure any performance
> > benefit from it.  Perhaps it could be described in the changelog_ I also
> > have a more detailed question below.
> 
> No, I am inspired by commit c15ab236d69d, don't measure it.

Perhaps it would be nice to note that in the changelog.

> >> ---
> >>  net/sched/cls_u32.c | 108 
> >> 
> >>  1 file changed, 67 insertions(+), 41 deletions(-)
> >>
> >> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
> >> index 10b8d851fc6b..316b8a791b13 100644
> >> --- a/net/sched/cls_u32.c
> >> +++ b/net/sched/cls_u32.c
> >> @@ -46,6 +46,7 @@
> >
> > ...
> >
> >> @@ -937,22 +940,33 @@ static int u32_change(struct net *net, struct 
> >> sk_buff *in_skb,
> >>   return -EINVAL;
> >>   if (TC_U32_KEY(handle))
> >>   return -EINVAL;
> >> - if (handle == 0) {
> >> - handle = gen_new_htid(tp->data);
> >> - if (handle == 0)
> >> - return -ENOMEM;
> >> - }
> >>   ht = kzalloc(sizeof(*ht) + divisor*sizeof(void *), 
> >> GFP_KERNEL);
> >>   if (ht == NULL)
> >>   return -ENOBUFS;
> >> + if (handle == 0) {
> >> + handle = gen_new_htid(tp->data, ht);
> >> + if (handle == 0) {
> >> + kfree(ht);
> >> + return -ENOMEM;
> >> + }
> >> + } else {
> >> + err = idr_alloc_ext(_c->handle_idr, ht, NULL,
> >> + handle, handle + 1, GFP_KERNEL);
> >> + if (err) {
> >> + kfree(ht);
> >> + return err;
> >> + }
> >
> > The above seems to check that handle is not already in use and mark it as
> > in use. But I don't see that logic in the code prior to this patch.
> > Am I missing something? If not perhaps this portion should be a separate
> > patch or described in the changelog.
> 
> The logic is in upper layer, tc_ctl_tfilter(). It tries to get a
> filter by handle
> (if non-zero), and errors out if we are creating a new filter with the same
> handle.
> 
> At the point you quote above, 'n' is already NULL and 'handle' is non-zero,
> which means there is no existing filter has same handle, it is safe to just
> mark it as in-use.

Thanks for the clarification, that seems fine to me.

Reviewed-by: Simon Horman <simon.hor...@netronome.com>



[PATCH net-next 2/2] flow_dissector: dissect tunnel info

2017-10-02 Thread Simon Horman
Move dissection of tunnel info from the flower classifier to the flow
dissector where all other dissection occurs.  This should not have any
behavioural affect on other users of the flow dissector.

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 net/core/flow_dissector.c | 100 ++
 net/sched/cls_flower.c|  25 
 2 files changed, 100 insertions(+), 25 deletions(-)

diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 0a977373d003..1f5caafb4492 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -115,6 +116,102 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, 
int thoff, u8 ip_proto,
 }
 EXPORT_SYMBOL(__skb_flow_get_ports);
 
+static void
+skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
+  struct flow_dissector *flow_dissector,
+  void *target_container)
+{
+   struct flow_dissector_key_control *ctrl;
+
+   if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_CONTROL))
+   return;
+
+   ctrl = skb_flow_dissector_target(flow_dissector,
+FLOW_DISSECTOR_KEY_ENC_CONTROL,
+target_container);
+   ctrl->addr_type = type;
+}
+
+static void
+__skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
+  struct flow_dissector *flow_dissector,
+  void *target_container)
+{
+   struct ip_tunnel_info *info;
+   struct ip_tunnel_key *key;
+
+   /* A quick check to see if there might be something to do. */
+   if (!dissector_uses_key(flow_dissector,
+   FLOW_DISSECTOR_KEY_ENC_KEYID) &&
+   !dissector_uses_key(flow_dissector,
+   FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) &&
+   !dissector_uses_key(flow_dissector,
+   FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) &&
+   !dissector_uses_key(flow_dissector,
+   FLOW_DISSECTOR_KEY_ENC_CONTROL) &&
+   !dissector_uses_key(flow_dissector,
+   FLOW_DISSECTOR_KEY_ENC_PORTS))
+   return;
+
+   info = skb_tunnel_info(skb);
+   if (!info)
+   return;
+
+   key = >key;
+
+   switch (ip_tunnel_info_af(info)) {
+   case AF_INET:
+   
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+  flow_dissector,
+  target_container);
+   if (dissector_uses_key(flow_dissector,
+  FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
+   struct flow_dissector_key_ipv4_addrs *ipv4;
+
+   ipv4 = skb_flow_dissector_target(flow_dissector,
+
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
+target_container);
+   ipv4->src = key->u.ipv4.src;
+   ipv4->dst = key->u.ipv4.dst;
+   }
+   break;
+   case AF_INET6:
+   
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+  flow_dissector,
+  target_container);
+   if (dissector_uses_key(flow_dissector,
+  FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
+   struct flow_dissector_key_ipv6_addrs *ipv6;
+
+   ipv6 = skb_flow_dissector_target(flow_dissector,
+
FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS,
+target_container);
+   ipv6->src = key->u.ipv6.src;
+   ipv6->dst = key->u.ipv6.dst;
+   }
+   break;
+   }
+
+   if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
+   struct flow_dissector_key_keyid *keyid;
+
+   keyid = skb_flow_dissector_target(flow_dissector,
+ FLOW_DISSECTOR_KEY_ENC_KEYID,
+ target_container);
+   keyid->keyid = tunnel_id_to_key32(key->tun_id);
+   }
+
+   if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
+   struct flow_dissector_key_ports *tp;
+
+   tp = skb_flow_dissector_target(flow_dissec

[PATCH net-next 0/2] flow_dissector: dissect tunnel info

2017-10-02 Thread Simon Horman
Move dissection of tunnel info from the flower classifier to the flow
dissector where all other dissection occurs.  This should not have any
behavioural affect on other users of the flow dissector.

Simon Horman (2):
  net/dst: Make skb parameter of skb{metadata_dst,tunnel_info}() const
  flow_dissector: dissect tunnel info

 include/net/dst_metadata.h |   5 ++-
 net/core/flow_dissector.c  | 100 +
 net/sched/cls_flower.c |  25 
 3 files changed, 103 insertions(+), 27 deletions(-)

-- 
2.1.4



[PATCH net-next 1/2] net/dst: Make skb parameter of skb{metadata_dst,tunnel_info}() const

2017-10-02 Thread Simon Horman
Make the skb parameter of skb_metadata_dst() and skb_tunnel_info()
const as they are not modified. This is in preparation for using
them in call-sites where skb is const.

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 include/net/dst_metadata.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index a803129a4849..9fba2ebf6dda 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -24,7 +24,7 @@ struct metadata_dst {
} u;
 };
 
-static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
+static inline struct metadata_dst *skb_metadata_dst(const struct sk_buff *skb)
 {
struct metadata_dst *md_dst = (struct metadata_dst *) skb_dst(skb);
 
@@ -34,7 +34,8 @@ static inline struct metadata_dst *skb_metadata_dst(struct 
sk_buff *skb)
return NULL;
 }
 
-static inline struct ip_tunnel_info *skb_tunnel_info(struct sk_buff *skb)
+static inline struct ip_tunnel_info *
+skb_tunnel_info(const struct sk_buff *skb)
 {
struct metadata_dst *md_dst = skb_metadata_dst(skb);
struct dst_entry *dst;
-- 
2.1.4



Re: [PATCH v2 net-next 0/2] net/sched: support tunnel options in cls_flower and act_tunnel_key

2017-10-02 Thread Simon Horman
On Fri, Sep 29, 2017 at 05:54:23AM +0100, David Miller wrote:
> From: Simon Horman <simon.hor...@netronome.com>
> Date: Wed, 27 Sep 2017 10:16:32 +0200
> 
> > Users of options:
> > 
> > * There are eBPF hooks to allow getting on and setting tunnel metadata:
> >   bpf_skb_set_tunnel_opt, bpf_skb_get_tunnel_opt.
> > 
> > * Open vSwitch is able to match and set Geneve and VXLAN-GBP options.
> > 
> > Neither of the above appear to assume any structure for the data.
> 
> I really worry about this.
> 
> These metadata option blobs are internal kernel datastructure which we
> could change at any point in time.  They are not exported to
> userspace as a UAPI.
> 
> It's kinda OK for eBPF programs to access this stuff since they are
> expected to cope with changes to internal data-structures.
> 
> But for anything user facing, this really doesn't work.

Hi Dave, Hi Jiri,

the feedback I got from Jiri is that there needs to be some exposure
of TLVs. What I have in mind is to describe Geneve option TLVs in the
UAPI and for the kernel - most likely cls_flower, possibly using helpers,
to translate between that encoding and the one used internally by the kernel
- which currently happens to be the on-the-wire format.

I believe that in order to avoid per-packet overhead and at the same time
code complexity the TLVs should be described in-order. So matching on
TLV-A,TLV-B,TLV-C would be a different match to TLV-C,TLV-A,TLV-B.  An
order-independent match could be added if desired in future.

This would mean the feature is initially restricted to Geneve but could
be expended to offer a similar feature for other encapsulation protocols
as the need arises.

Would this address your concerns?


Re: [PATCH/RFC net-next] ravb: RX checksum offload

2017-09-28 Thread Simon Horman
On Wed, Sep 13, 2017 at 08:54:00PM +0300, Sergei Shtylyov wrote:
> Hello!
> 
> On 09/12/2017 04:04 PM, Simon Horman wrote:
> 
> >Add support for RX checksum offload. This is enabled by default and
> >may be disabled and re-enabled using ethtool:
> >
> >  # ethtool -K eth0 rx off
> >  # ethtool -K eth0 rx on
> >
> >The RAVB provides a simple checksumming scheme which appears to be
> >completely compatible with CHECKSUM_COMPLETE: a 1's complement sum of
> 
>Hm, the gen2/3 manuals say calculation doesn't involve bit inversion...

Yes, I believe that matches my observation of the values supplied by
the hardware. Empirically this appears to be what the kernel expects.

> >all packet data after the L2 header is appended to packet data; this may
> >be trivially read by the driver and used to update the skb accordingly.
> >
> >In terms of performance throughput is close to gigabit line-rate both with
> >and without RX checksum offload enabled. Perf output, however, appears to
> >indicate that significantly less time is spent in do_csum(). This is as
> >expected.
> 
> [...]
> 
> >By inspection this also appears to be compatible with the ravb found
> >on R-Car Gen 2 SoCs, however, this patch is currently untested on such
> >hardware.
> 
>I probably won't be able to test it on gen2 too...
> 
> >Signed-off-by: Simon Horman <horms+rene...@verge.net.au>
> 
>I'm generally OK with the patch but have some questions/comments below...

Thanks, I will try to address them.

> >---
> >  drivers/net/ethernet/renesas/ravb_main.c | 58 
> > +++-
> >  1 file changed, 57 insertions(+), 1 deletion(-)
> >
> >diff --git a/drivers/net/ethernet/renesas/ravb_main.c 
> >b/drivers/net/ethernet/renesas/ravb_main.c
> >index fdf30bfa403b..7c6438cd7de7 100644
> >--- a/drivers/net/ethernet/renesas/ravb_main.c
> >+++ b/drivers/net/ethernet/renesas/ravb_main.c
> [...]
> >@@ -1842,6 +1859,41 @@ static int ravb_do_ioctl(struct net_device *ndev, 
> >struct ifreq *req, int cmd)
> > return phy_mii_ioctl(phydev, req, cmd);
> >  }
> >+static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
> >+{
> >+struct ravb_private *priv = netdev_priv(ndev);
> >+unsigned long flags;
> >+
> >+spin_lock_irqsave(>lock, flags);
> >+
> >+/* Disable TX and RX */
> >+ravb_rcv_snd_disable(ndev);
> >+
> >+/* Modify RX Checksum setting */
> >+if (enable)
> >+ravb_modify(ndev, ECMR, 0, ECMR_RCSC);
> 
>Please use ECMR_RCSC as the 3rd argument too to conform the common driver
> style.
> 
> >+else
> >+ravb_modify(ndev, ECMR, ECMR_RCSC, 0);
> 
>This *if* can easily be folded into a single ravb_modify() call...

Thanks, something like this?

ravb_modify(ndev, ECMR, ECMR_RCSC, enable ? ECMR_RCSC : 0);

> [...]
> >@@ -2004,6 +2057,9 @@ static int ravb_probe(struct platform_device *pdev)
> > if (!ndev)
> > return -ENOMEM;
> >+ndev->features |= NETIF_F_RXCSUM;
> >+ndev->hw_features |= ndev->features;
> 
>Hum, both fields are 0 before this? Then why not use '=' instead of '|='?
> Even if not, why not just use the same value as both the rvalues?

I don't feel strongly about this, how about?

ndev->features = NETIF_F_RXCSUM;
ndev->hw_features = NETIF_F_RXCSUM;


Re: [PATCH net-next 2/2] flow_dissector: dissect tunnel info

2017-10-03 Thread Simon Horman
On Mon, Oct 02, 2017 at 01:37:55PM -0700, Tom Herbert wrote:
> On Mon, Oct 2, 2017 at 1:41 AM, Simon Horman <simon.hor...@netronome.com> 
> wrote:
> > Move dissection of tunnel info from the flower classifier to the flow
> > dissector where all other dissection occurs.  This should not have any
> > behavioural affect on other users of the flow dissector.

...

Hi Tom,

> Simon,
> 
> I think I'm missing something fundamental here. This code is
> populating flow dissector keys not based on the contents of the packet
> like rest of the flow dissector, but on external meta data related to
> the packet which I believe is constant during the whole flow
> dissection.

Yes, I believe that is correct on all counts.

> Why can't this be handled by the caller?

It certainly can be. And indeed it was before this patch. But it seems odd
for some population of dissector keys to occur in the dissector and some
elsewhere.

I feel that we are circling back the perennial issue of flower using the
flow dissector in a somewhat broader/different way than many/all other
users of the flow dissector.

> Also, if I read this correctly, this code could be called multiple times
> and it seems like it does the exact same thing in each call.

I'm not sure what you are getting at there. If there are flower classifiers
for the same device at different priority levels then the dissection
will be called multiple times and the data in question cannot have changed
as far as I know. But this was also the case before this patch.


Re: [PATCH net-next 0/7] nfp: flower vxlan tunnel offload

2017-09-25 Thread Simon Horman
On Mon, Sep 25, 2017 at 06:25:03PM +0300, Or Gerlitz wrote:
> On Mon, Sep 25, 2017 at 1:23 PM, Simon Horman
> <simon.hor...@netronome.com> wrote:
> > From: Simon Horman <simon.hor...@netronome.com>
> >
> > John says:
> >
> > This patch set allows offloading of TC flower match and set tunnel fields
> > to the NFP. The initial focus is on VXLAN traffic. Due to the current
> > state of the NFP firmware, only VXLAN traffic on well known port 4789 is
> > handled. The match and action fields must explicity set this value to be
> > supported. Tunnel end point information is also offloaded to the NFP for
> > both encapsulation and decapsulation. The NFP expects 3 separate data sets
> > to be supplied.
> 
> > For decapsulation, 2 separate lists exist; a list of MAC addresses
> > referenced by an index comprised of the port number, and a list of IP
> > addresses. These IP addresses are not connected to a MAC or port.
> 
> Do these IP addresses exist on the host kernel SW stack? can the same
> set of TC rules be fully functional and generate the same traffic
> pattern when set to run in SW (skip_hw)?

Hi Or,

I asked John (now CCed) about this and his response was:

The MAC addresses are extracted from the netdevs already loaded in the
kernel and are monitored for any changes. The IP addresses are slightly
different in that they are extracted from the rules themselves. We make the
assumption that, if a packet is decapsulated at the end point and a match
is attempted on the IP address, that this IP address should be recognised
in the kernel. That being the case, the same traffic pattern should be
witnessed if the skip_hw flag is applied.


Re: RFC iproute2 doc files

2017-09-28 Thread Simon Horman
On Wed, Sep 20, 2017 at 08:11:59AM -0700, Stephen Hemminger wrote:
> I noticed that the iproute man pages are up to date but the LaTex 
> documentation
> is very out of date. Rarely updated since the Linux 2.2 days.
> 
> Either someone needs to do a massive editing job on them, or they should just
> be dropped. My preference would be to just drop everything in the doc/ 
> directory.
> The current versions are so old, they can't be helping.

FWIW, removing stale documentation sounds sensible to me.


Re: [Patch net-next] net_sched: use idr to allocate u32 filter handles

2017-09-28 Thread Simon Horman
On Thu, Sep 21, 2017 at 04:43:02PM -0700, Cong Wang wrote:
> Cc: Chris Mi 
> Cc: Jamal Hadi Salim 
> Signed-off-by: Cong Wang 

Hi Cong,

this looks like a nice enhancement to me. Did you measure any performance
benefit from it.  Perhaps it could be described in the changelog_ I also
have a more detailed question below.

> ---
>  net/sched/cls_u32.c | 108 
> 
>  1 file changed, 67 insertions(+), 41 deletions(-)
> 
> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
> index 10b8d851fc6b..316b8a791b13 100644
> --- a/net/sched/cls_u32.c
> +++ b/net/sched/cls_u32.c
> @@ -46,6 +46,7 @@

...

> @@ -937,22 +940,33 @@ static int u32_change(struct net *net, struct sk_buff 
> *in_skb,
>   return -EINVAL;
>   if (TC_U32_KEY(handle))
>   return -EINVAL;
> - if (handle == 0) {
> - handle = gen_new_htid(tp->data);
> - if (handle == 0)
> - return -ENOMEM;
> - }
>   ht = kzalloc(sizeof(*ht) + divisor*sizeof(void *), GFP_KERNEL);
>   if (ht == NULL)
>   return -ENOBUFS;
> + if (handle == 0) {
> + handle = gen_new_htid(tp->data, ht);
> + if (handle == 0) {
> + kfree(ht);
> + return -ENOMEM;
> + }
> + } else {
> + err = idr_alloc_ext(_c->handle_idr, ht, NULL,
> + handle, handle + 1, GFP_KERNEL);
> + if (err) {
> + kfree(ht);
> + return err;
> + }

The above seems to check that handle is not already in use and mark it as
in use. But I don't see that logic in the code prior to this patch.
Am I missing something? If not perhaps this portion should be a separate
patch or described in the changelog.

> + }
>   ht->tp_c = tp_c;
>   ht->refcnt = 1;
>   ht->divisor = divisor;
>   ht->handle = handle;
>   ht->prio = tp->prio;
> + idr_init(>handle_idr);
>  
>   err = u32_replace_hw_hnode(tp, ht, flags);
>   if (err) {
> + idr_remove_ext(_c->handle_idr, handle);
>   kfree(ht);
>   return err;
>   }

...


Re: [PATCH v2 0/5] ARM: dts: rcar-gen2: Convert to new CPG/MSSR bindings

2017-08-21 Thread Simon Horman
On Fri, Aug 18, 2017 at 11:11:33AM +0200, Geert Uytterhoeven wrote:
>   Hi Simon, Magnus,
> 
> Currently Renesas R-Car Gen2 SoCs use the common clk-rcar-gen2,
> clk-mstp, and clk-div6 drivers, which depend on most clocks being
> described in DT.  Especially the module (MSTP) clocks are cumbersome and
> error prone, due to 3 arrays (clocks, clock-indices, and
> clock-output-names) to be kept in sync. In addition, the clk-mstp driver
> cannot be extended easily to also support module resets, which are
> provided by the same hardware module.
> 
> Hence when developing support for R-Car Gen3 SoCs, another approach was
> chosen, which led to the CPG/MSSR driver core, and SoC-specific
> subdrivers (initially for R-Car Gen3, but later also for RZ/G1).
> 
> This series converts the various R-Car Gen2 DTSes to migrate to the new
> CPG/MSSR drivers that were added in v4.13-rc1.
> 
> Note that module reset descriptions will be added later.
> 
> Changes compared to v1:
>   - Rebased.
> 
> Dependencies:
>   - renesas-devel-20170818-v4.13-rc5.
> 
> Known issues:
>   - The CPG/MSSR driver is initialized later than the old clk-rcar-gen2
> driver, causing changes of initialization order for other drivers.
> 
> Currently the PHY subsystem does not support probe deferral
> 
>   +irq: no irq domain found for /interrupt-controller@e61c !
> 
>   -Micrel KSZ8041RNLI ee70.ethernet-:01: attached PHY driver 
> [Micrel KSZ8041RNLI] (mii_bus:phy_addr=ee70.ethernet-:01, irq=182)
>   +Micrel KSZ8041RNLI ee70.ethernet-:01: attached PHY driver 
> [Micrel KSZ8041RNLI] (mii_bus:phy_addr=ee70.ethernet-:01, irq=-1)
> 
> leading to the Ethernet PHY falling back to polling instead of using an
> interrupt.  This can be remedied by "of_mdio: Fix broken PHY IRQ in
> case of probe deferral" (https://patchwork.kernel.org/patch/9734175/),
> which is still pending approval.
> 
> Fortunately the impact of this is limited to a small delay in the
> detection of cable (un)plugging.
> Note that when using the PHY interrupt, cable unplugging is reported
> instantaneous, but plugging takes ca. 1.5-1.8 seconds.  Hence when
> using polling with the standard interval of 1 second, the link comes up
> in about the same time.
> 
> For your convenience, this series is also available in the
> topic/rcar2-cpg-mssr-dt-v2 branch of my renesas-drivers git repository at
> git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git.
> 
> This has been tested on r8a7790/lager, r8a7791/koelsch, r8a7792/blanche,
> r8a7793/gose, and r8a7794/alt.  /sys/kernel/debug/clk/clk_summary has
> been compared before and after the conversion.
> 
> Thanks for applying!

Thanks, applied for v4.15.


Re: [patch net-next 2/3] net/sched: Change cls_flower to use IDR

2017-08-28 Thread Simon Horman
On Mon, Aug 28, 2017 at 02:41:16AM -0400, Chris Mi wrote:
> Currently, all filters with the same priority are linked in a doubly
> linked list. Every filter should have a unique handle. To make the
> handle unique, we need to iterate the list every time to see if the
> handle exists or not when inserting a new filter. It is time-consuming.
> For example, it takes about 5m3.169s to insert 64K rules.
> 
> This patch changes cls_flower to use IDR. With this patch, it
> takes about 0m1.127s to insert 64K rules. The improvement is huge.

Very nice :)

> But please note that in this testing, all filters share the same action.
> If every filter has a unique action, that is another bottleneck.
> Follow-up patch in this patchset addresses that.
> 
> Signed-off-by: Chris Mi 
> Signed-off-by: Jiri Pirko 
> ---
>  net/sched/cls_flower.c | 55 
> +-
>  1 file changed, 23 insertions(+), 32 deletions(-)
> 
> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
> index bd9dab4..3d041d2 100644
> --- a/net/sched/cls_flower.c
> +++ b/net/sched/cls_flower.c

...

> @@ -890,6 +870,7 @@ static int fl_change(struct net *net, struct sk_buff 
> *in_skb,
>   struct cls_fl_filter *fnew;
>   struct nlattr **tb;
>   struct fl_flow_mask mask = {};
> + unsigned long idr_index;
>   int err;
>  
>   if (!tca[TCA_OPTIONS])
> @@ -920,13 +901,21 @@ static int fl_change(struct net *net, struct sk_buff 
> *in_skb,
>   goto errout;
>  
>   if (!handle) {
> - handle = fl_grab_new_handle(tp, head);
> - if (!handle) {
> - err = -EINVAL;
> + err = idr_alloc_ext(>handle_idr, fnew, _index,
> + 1, 0x8000, GFP_KERNEL);
> + if (err)
>   goto errout;
> - }
> + fnew->handle = idr_index;
> + }
> +
> + /* user specifies a handle and it doesn't exist */
> + if (handle && !fold) {
> + err = idr_alloc_ext(>handle_idr, fnew, _index,
> + handle, handle + 1, GFP_KERNEL);
> + if (err)
> + goto errout;
> + fnew->handle = idr_index;
>   }
> - fnew->handle = handle;
>  
>   if (tb[TCA_FLOWER_FLAGS]) {
>   fnew->flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
> @@ -980,6 +969,8 @@ static int fl_change(struct net *net, struct sk_buff 
> *in_skb,
>   *arg = fnew;
>  
>   if (fold) {
> + fnew->handle = handle;

Can it be the case that fold is non-NULL and handle is zero?
The handling of that case seem to have changed in this patch.

> + idr_replace_ext(>handle_idr, fnew, fnew->handle);
>   list_replace_rcu(>list, >list);
>   tcf_unbind_filter(tp, >res);
>   call_rcu(>rcu, fl_destroy_filter);
> -- 
> 1.8.3.1
> 


Re: [PATCH net 0/2] netfilter: ipvs: some fixes in sctp_conn_schedule

2017-08-31 Thread Simon Horman
On Mon, Aug 28, 2017 at 06:17:32PM +0200, Pablo Neira Ayuso wrote:
> On Sun, Aug 20, 2017 at 01:38:06PM +0800, Xin Long wrote:
> > Patch 1/2 fixes the regression introduced by commit 5e26b1b3abce.
> > Patch 2/2 makes ipvs not create conn for sctp ABORT packet.
> 
> Will wait for Julian and Simon to tell me what I should do with this.

Hi Pablo,

could you take these directly with Julian's Ack and the following?

Signed-off-by: Simon Horman <ho...@verge.net.au>



Re: [PATCH net-next 2/2] flow_dissector: Add limits for encapsulation and EH

2017-09-01 Thread Simon Horman
On Thu, Aug 31, 2017 at 03:22:39PM -0700, Tom Herbert wrote:
> In flow dissector there are no limits to the number of nested
> encapsulations that might be dissected which makes for a nice DOS
> attack. This patch limits for dissecting nested encapsulations
> as well as for dissecting over extension headers.
> 
> Reported-by: Hannes Frederic Sowa 
> Signed-off-by: Tom Herbert 
> ---
>  net/core/flow_dissector.c | 48 
> ---
>  1 file changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index 5110180a3e96..1bca748de27d 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -396,6 +396,35 @@ __skb_flow_dissect_ipv6(const struct sk_buff *skb,
>   key_ip->ttl = iph->hop_limit;
>  }
>  
> +/* Maximum number of nested encapsulations that can be processed in
> + * __skb_flow_dissect
> + */
> +#define MAX_FLOW_DISSECT_ENCAPS  5
> +
> +static bool skb_flow_dissect_encap_allowed(int *num_encaps, unsigned int 
> *flags)
> +{
> + ++*num_encaps;
> +
> + if (*num_encaps >= MAX_FLOW_DISSECT_ENCAPS) {
> + if (*num_encaps == MAX_FLOW_DISSECT_ENCAPS) {
> + /* Allow one more pass but ignore disregard

It seems that 'ignore' or 'disregard' should be dropped from the text above.

> +  * further encapsulations
> +  */
> + *flags |= FLOW_DISSECTOR_F_STOP_AT_ENCAP;
> + } else {
> + /* Max encaps reached */
> + return  false;

There are two spaces between 'return' and 'false'.

...


Re: [PATCH net-next 1/2] flow_dissector: Cleanup control flow

2017-09-01 Thread Simon Horman
Hi Tom,

On Thu, Aug 31, 2017 at 03:22:38PM -0700, Tom Herbert wrote:
> __skb_flow_dissect is riddled with gotos that make discerning the flow,
> debugging, and extending the capability difficult. This patch
> reorganizes things so that we only perform goto's after the two main
> switch statements (no gotos within the cases now). It also eliminates
> several goto labels so that there are only two labels that can be target
> for goto.

I agree that the flow of __skb_flow_dissect() is difficult to follow
but its not obvious that this significant change in terms of loc
takes us to a better place.

Maybe it makes follow-up work easier. If so perhaps it should be motivated
along those lines.

In any case I won't stand in the way of this change but I did want to throw
my 2c worth in.

> 
> Reported-by: Alexander Popov 
> Signed-off-by: Tom Herbert 
> ---
>  include/net/flow_dissector.h |   9 ++
>  net/core/flow_dissector.c| 225 
> ---
>  2 files changed, 156 insertions(+), 78 deletions(-)
> 
> diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> index e2663e900b0a..c358c3ff6acc 100644
> --- a/include/net/flow_dissector.h
> +++ b/include/net/flow_dissector.h
> @@ -19,6 +19,15 @@ struct flow_dissector_key_control {
>  #define FLOW_DIS_FIRST_FRAG  BIT(1)
>  #define FLOW_DIS_ENCAPSULATION   BIT(2)
>  
> +enum flow_dissect_ret {
> + FLOW_DISSECT_RET_OUT_GOOD,
> + FLOW_DISSECT_RET_OUT_BAD,
> + FLOW_DISSECT_RET_PROTO_AGAIN,
> + FLOW_DISSECT_RET_IPPROTO_AGAIN,
> + FLOW_DISSECT_RET_IPPROTO_AGAIN_EH,
> + FLOW_DISSECT_RET_CONTINUE,
> +};

Minor nit:

My reading is that this patch does not seem to differentiate between the
handling of FLOW_DISSECT_RET_IPPROTO_AGAIN and
FLOW_DISSECT_RET_IPPROTO_AGAIN_EH.  Perhaps it would be better to add
FLOW_DISSECT_RET_IPPROTO_AGAIN_EH in the following patch where it is used.

> +
>  /**
>   * struct flow_dissector_key_basic:
>   * @thoff: Transport header offset

...


[PATCH iproute2/master] tc actions: store and dump correct length of user cookies

2017-09-05 Thread Simon Horman
Correct two errors which cancel each other out:
* Do not send twice the length of the actual provided by the user to the kernel
* Do not dump half the length of the cookie provided by the kernel

As the cookie is now stored in the kernel at its correct length rather
than double the that length cookies of up to the maximum size of 16 bytes
may now be stored rather than a maximum of half that length.

Output of dump is the same before and after this change,
but the data stored in the kernel is now exactly the cookie
rather than the cookie + as many trailing zeros.

Before:
 # tc filter add dev eth0 protocol ip parent : \
   flower ip_proto udp action drop \
   cookie 0123456789abcdef0123456789abcdef
 RTNETLINK answers: Invalid argument

After:
 # tc filter add dev eth0 protocol ip parent : \
   flower ip_proto udp action drop \
   cookie 0123456789abcdef0123456789abcdef
 # tc filter show dev eth0 ingress
   eth_type ipv4
   ip_proto udp
   not_in_hw
 action order 1: gact action drop
  random type none pass val 0
  index 1 ref 1 bind 1 installed 1 sec used 1 sec
 Action statistics:
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
 cookie len 16 0123456789abcdef0123456789abcdef

Fixes: fd8b3d2c1b9b ("actions: Add support for user cookies")
Cc: Jamal Hadi Salim <j...@mojatatu.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 tc/m_action.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tc/m_action.c b/tc/m_action.c
index 6ebe85e1cbe3..397e9c5d4a7b 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -242,7 +242,7 @@ done0:
invarg("cookie must be a hex string\n",
   *argv);
 
-   act_ck_len = slen;
+   act_ck_len = slen / 2;
argc--;
argv++;
}
@@ -307,7 +307,7 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg)
print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL);
if (tb[TCA_ACT_COOKIE]) {
int strsz = RTA_PAYLOAD(tb[TCA_ACT_COOKIE]);
-   char b1[strsz+1];
+   char b1[strsz * 2 + 1];
 
fprintf(f, "\n\tcookie len %d %s ", strsz,
hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]),
-- 
2.1.4



Re: [PATCH 13/14] netfilter/ipvs: Use %pS printk format for direct addresses

2017-10-08 Thread Simon Horman
On Wed, Sep 06, 2017 at 10:28:00PM +0200, Helge Deller wrote:
> The debug and error printk functions in ipvs uses wrongly the %pF instead of
> the %pS printk format specifier for printing symbols for the address returned
> by _builtin_return_address(0). Fix it for the ia64, ppc64 and parisc64
> architectures.
> 
> Signed-off-by: Helge Deller <del...@gmx.de>
> Cc: Wensong Zhang <wens...@linux-vs.org>
> Cc: netdev@vger.kernel.org
> Cc: lvs-de...@vger.kernel.org
> Cc: netfilter-de...@vger.kernel.org

Sorry for the delay in processing this.

Acked-by: Simon Horman <ho...@verge.net.au>

Pablo, could you take this through the nf-next tree directly?


Re: [PATCH net-next 2/2] flow_dissector: dissect tunnel info

2017-10-04 Thread Simon Horman
On Wed, Oct 04, 2017 at 08:07:15PM +0200, Jiri Pirko wrote:
> Wed, Oct 04, 2017 at 05:52:54PM CEST, t...@herbertland.com wrote:
> >On Wed, Oct 4, 2017 at 1:15 AM, Jiri Pirko <j...@resnulli.us> wrote:
> >> Wed, Oct 04, 2017 at 10:08:57AM CEST, simon.hor...@netronome.com wrote:
> >>>On Tue, Oct 03, 2017 at 11:17:46AM -0700, Tom Herbert wrote:
> >>>> On Tue, Oct 3, 2017 at 2:40 AM, Simon Horman 
> >>>> <simon.hor...@netronome.com> wrote:
> >>>> > On Mon, Oct 02, 2017 at 01:37:55PM -0700, Tom Herbert wrote:
> >>>> >> On Mon, Oct 2, 2017 at 1:41 AM, Simon Horman 
> >>>> >> <simon.hor...@netronome.com> wrote:
> >>>> >> > Move dissection of tunnel info from the flower classifier to the 
> >>>> >> > flow
> >>>> >> > dissector where all other dissection occurs.  This should not have 
> >>>> >> > any
> >>>> >> > behavioural affect on other users of the flow dissector.
> >>>> >
> >>>> > ...
> >>>>
> >>>> > I feel that we are circling back the perennial issue of flower using 
> >>>> > the
> >>>> > flow dissector in a somewhat broader/different way than many/all other
> >>>> > users of the flow dissector.
> >>>> >
> >>>> Simon,
> >>>>
> >>>> It's more like __skb_flow_dissect is already an incredibly complex
> >>>> function and because of that it's difficult to maintain. We need to
> >>>> measure changes against that fact. For this patch, there is precisely
> >>>> one user (cls_flower.c) and it's not at all clear to me if there will
> >>>> be ever any more (e.g. for hashing we don't need tunnel info). IMO, it
> >>>> should be just as easy and less convolution for everyone to have
> >>>> flower call __skb_flow_dissect_tunnel_info directly and not call if
> >>>> from __skb_flow_dissect.
> >>>
> >>>Hi Tom,
> >>>
> >>>my original suggestion was just that, but Jiri indicated a strong 
> >>>preference
> >>>for the approach taken by this patch. I think we need to widen the
> >>>participants in this discussion.
> >>
> >> I like the __skb_flow_dissect to be the function to call and it will do
> >> the job according to the configuration. I don't like to split in
> >> multiple calls.
> >
> >Those are not technical arguments. As I already mentioned, I don't
> >like it when we add stuff for the benefit of a 1% use case that
> >negatively impacts the rest of the 99% cases which is what I believe
> >is happening here.
> 
> Yeah. I just wanted the flow dissector to stay compact. But if needed,
> could be split. I just fear that it will become a mess that's all.
> 
> 
> >
> >> Does not make sense in the most of the cases as the
> >> dissection state would have to be carried in between calls.
> >
> >Please elaborate. This code is being moved into __skb_flow_dissect, so
> >the functionality was already there. I don't see any description in
> >this discussion that things were broken and that this patch is a
> >necessary fix.
> 
> Yeah, you are right.

Hi Tom, Hi Jiri,

I'm happy to make a patch to move the call to
__skb_flow_dissect_tunnel_info() from __skb_flow_dissect() to
fl_classify(). It seems that approach has been agreed on above.


Re: [PATCH net-next 0/7] nfp: flower vxlan tunnel offload

2017-09-27 Thread Simon Horman
On Tue, Sep 26, 2017 at 09:29:03PM -0700, David Miller wrote:
> From: Simon Horman <simon.hor...@netronome.com>
> Date: Mon, 25 Sep 2017 12:23:34 +0200
> 
> > From: Simon Horman <simon.hor...@netronome.com>
> > 
> > John says:
> > 
> > This patch set allows offloading of TC flower match and set tunnel fields
> > to the NFP. The initial focus is on VXLAN traffic. Due to the current
> > state of the NFP firmware, only VXLAN traffic on well known port 4789 is
> > handled. The match and action fields must explicity set this value to be
> > supported. Tunnel end point information is also offloaded to the NFP for
> > both encapsulation and decapsulation. The NFP expects 3 separate data sets
> > to be supplied.
>  ...
> 
> Series applied, thanks.
> 
> I see there is some discussion about ipv6 flow dissector key handling
> and ND keepalives, but those should be addressable in follow-on changes.

Thanks Dave,

I'll make sure that discussion is brought to a satisfactory conclusion.


[PATCH v2 net-next 0/2] net/sched: support tunnel options in cls_flower and act_tunnel_key

2017-09-27 Thread Simon Horman
Allow the flower classifier to match on tunnel options and the
tunnel key action to set them.

Tunnel options are a bytestring of up to 256 bytes.
The flower classifier matching with an optional bitwise mask.
Tunnel implementations may support more or less options,
or none at all.


Discussion stemming from review of RFC:

This feature is to be used in conjunction with tunnels in collect metadata
(external) mode. As I understand it there are three tunnel netdevs that use
options metadata in the kernel at this time.

* Geneve

  In the case of Geneve options are TLVs[1]. My reading is that in collect
  metadata mode the kernel does not appear to do anything other than pass
  them around as a bytestring.

  [1] https://tools.ietf.org/html/draft-ietf-nvo3-geneve-05#section-3.5

* VXLAN-GBP

  In the case of VXLAN-GBP on RX in collect metadata mode options are used
  to carry information parsed in vxlan_parse_gbp_hdr() from the VXLAN Group
  Based Policy Extension[2]. On RX the options data is used to create an
  extension (header) by vxlan_build_gbp_hdr().

  [2] https://tools.ietf.org/html/draft-smith-vxlan-group-policy-03#section-2.1

* ERSPAN (GRE)

  In the case of ERSPAN, which is a variant of GRE, on RX in collect
  metadata mode options are used to carry the index parsed from the ERSPAN
  Type II feature header[3] in erspan_rcv().  The converse is true on TX
  and is handled by erspan_fb_xmit().

  [3] https://tools.ietf.org/html/draft-foschiano-erspan-03#section-4.2

Users of options:

* There are eBPF hooks to allow getting on and setting tunnel metadata:
  bpf_skb_set_tunnel_opt, bpf_skb_get_tunnel_opt.

* Open vSwitch is able to match and set Geneve and VXLAN-GBP options.

Neither of the above appear to assume any structure for the data.


Changes since RFC:
* Drop RFC prefix
* Correct changelogs and enhance cover letter.


Simon Horman (2):
  net/sched: add tunnel option support to act_tunnel_key
  net/sched: allow flower to match tunnel options

 include/net/flow_dissector.h  | 13 
 include/uapi/linux/pkt_cls.h  |  3 +++
 include/uapi/linux/tc_act/tc_tunnel_key.h |  1 +
 net/sched/act_tunnel_key.c| 26 ++-
 net/sched/cls_flower.c| 35 ++-
 5 files changed, 72 insertions(+), 6 deletions(-)

-- 
2.1.4



[PATCH v2 net-next 1/2] net/sched: add tunnel option support to act_tunnel_key

2017-09-27 Thread Simon Horman
Allow setting tunnel options using the act_tunnel_key action.

Options are a bitwise maskable bytestring of up to 256 bytes.
Tunnel implementations may support less or more options,
or no options at all.

 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev eth0 ingress
 # tc filter add dev eth0 protocol ip parent : \
 flower indev eth0 \
ip_proto udp \
action tunnel_key \
set src_ip 10.0.99.192 \
dst_ip 10.0.99.193 \
dst_port 6081 \
id 11 \
opts 0102800100800022 \
action mirred egress redirect dev geneve0

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
v2
* Correct example which was incorrectly described matching rather
  than setting tunnel options
---
 include/uapi/linux/tc_act/tc_tunnel_key.h |  1 +
 net/sched/act_tunnel_key.c| 26 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h 
b/include/uapi/linux/tc_act/tc_tunnel_key.h
index afcd4be953e2..e0cb1121d132 100644
--- a/include/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h
@@ -35,6 +35,7 @@ enum {
TCA_TUNNEL_KEY_PAD,
TCA_TUNNEL_KEY_ENC_DST_PORT,/* be16 */
TCA_TUNNEL_KEY_NO_CSUM, /* u8 */
+   TCA_TUNNEL_KEY_ENC_OPTS,
__TCA_TUNNEL_KEY_MAX,
 };
 
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 30c96274c638..77b5890a48b9 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -66,6 +66,7 @@ static const struct nla_policy 
tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
[TCA_TUNNEL_KEY_ENC_KEY_ID]   = { .type = NLA_U32 },
[TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
[TCA_TUNNEL_KEY_NO_CSUM]  = { .type = NLA_U8 },
+   [TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NLA_BINARY },
 };
 
 static int tunnel_key_init(struct net *net, struct nlattr *nla,
@@ -81,9 +82,11 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
struct tcf_tunnel_key *t;
bool exists = false;
__be16 dst_port = 0;
+   int opts_len = 0;
__be64 key_id;
__be16 flags;
int ret = 0;
+   u8 *opts;
int err;
 
if (!nla)
@@ -121,6 +124,11 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
dst_port = 
nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
 
+   if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
+   opts = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
+   opts_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
+   }
+
if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
__be32 saddr;
@@ -131,7 +139,7 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
 
metadata = __ip_tun_set_dst(saddr, daddr, 0, 0,
dst_port, flags,
-   key_id, 0);
+   key_id, opts_len);
} else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
   tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
struct in6_addr saddr;
@@ -142,9 +150,13 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
 
metadata = __ipv6_tun_set_dst(, , 0, 0, 
dst_port,
  0, flags,
- key_id, 0);
+ key_id, opts_len);
}
 
+   if (opts_len)
+   ip_tunnel_info_opts_set(>u.tun_info,
+   opts, opts_len);
+
if (!metadata) {
ret = -EINVAL;
goto err_out;
@@ -264,8 +276,9 @@ static int tunnel_key_dump(struct sk_buff *skb, struct 
tc_action *a,
goto nla_put_failure;
 
if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
-   struct ip_tunnel_key *key =
-   >tcft_enc_metadata->u.tun_info.key;
+   struct ip_tunnel_info *info =
+   >tcft_enc_metadata->u.tun_info;
+   struct ip_tunnel_key *key = >key;
__be32 key_id = tunnel_id_to_key32(key->tun_id);
 
if (nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id) ||
@@ -273,7 +286,10 @@ static int tunnel_key_dump(struct sk_buff *skb, struct 
tc_action *a,
  
>tcft_enc_metadata->u.tun_info) ||
   

[PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
Allow matching on options in tunnel headers.
This makes use of existing tunnel metadata support.

Options are a bytestring of up to 256 bytes.
Tunnel implementations may support less or more options,
or no options at all.

e.g.
 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev geneve0 ingress
 # tc filter add dev geneve0 protocol ip parent : \
 flower \
   enc_src_ip 10.0.99.192 \
   enc_dst_ip 10.0.99.193 \
   enc_key_id 11 \
   enc_opts 0102800100800020/fff0 \
   ip_proto udp \
   action mirred egress redirect dev eth1

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>

---
v2
* Correct example which was incorrectly described setting rather
  than matching tunnel options
---
 include/net/flow_dissector.h | 13 +
 include/uapi/linux/pkt_cls.h |  3 +++
 net/sched/cls_flower.c   | 35 ++-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index fc3dce730a6b..43f98bf0b349 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -183,6 +183,18 @@ struct flow_dissector_key_ip {
__u8ttl;
 };
 
+/**
+ * struct flow_dissector_key_enc_opts:
+ * @data: data
+ * @len: len
+ */
+struct flow_dissector_key_enc_opts {
+   u8 data[256];   /* Using IP_TUNNEL_OPTS_MAX is desired here
+* but seems difficult to #include
+*/
+   u8 len;
+};
+
 enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
+   FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
 
FLOW_DISSECTOR_KEY_MAX,
 };
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index d5e2bf68d0d4..7a09a28f21e0 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -467,6 +467,9 @@ enum {
TCA_FLOWER_KEY_IP_TTL,  /* u8 */
TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
 
+   TCA_FLOWER_KEY_ENC_OPTS,
+   TCA_FLOWER_KEY_ENC_OPTS_MASK,
+
__TCA_FLOWER_MAX,
 };
 
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index d230cb4c8094..e72a17c46f07 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -51,6 +51,7 @@ struct fl_flow_key {
struct flow_dissector_key_mpls mpls;
struct flow_dissector_key_tcp tcp;
struct flow_dissector_key_ip ip;
+   struct flow_dissector_key_enc_opts enc_opts;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. 
*/
 
 struct fl_flow_mask_range {
@@ -181,6 +182,11 @@ static int fl_classify(struct sk_buff *skb, const struct 
tcf_proto *tp,
skb_key.enc_key_id.keyid = tunnel_id_to_key32(key->tun_id);
skb_key.enc_tp.src = key->tp_src;
skb_key.enc_tp.dst = key->tp_dst;
+
+   if (info->options_len) {
+   skb_key.enc_opts.len = info->options_len;
+   ip_tunnel_info_opts_get(skb_key.enc_opts.data, info);
+   }
}
 
skb_key.indev_ifindex = skb->skb_iif;
@@ -421,6 +427,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 
1] = {
[TCA_FLOWER_KEY_IP_TOS_MASK]= { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TTL_MASK]= { .type = NLA_U8 },
+   [TCA_FLOWER_KEY_ENC_OPTS]   = { .type = NLA_BINARY },
+   [TCA_FLOWER_KEY_ENC_OPTS_MASK]  = { .type = NLA_BINARY },
 };
 
 static void fl_set_key_val(struct nlattr **tb,
@@ -712,6 +720,26 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
   >enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
   sizeof(key->enc_tp.dst));
 
+   if (tb[TCA_FLOWER_KEY_ENC_OPTS]) {
+   key->enc_opts.len = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS]);
+
+   if (key->enc_opts.len > sizeof(key->enc_opts.data))
+   return -EINVAL;
+
+   /* enc_opts is variable length.
+* If present ensure the value and mask are the same length.
+*/
+   if (tb[TCA_FLOWER_KEY_ENC_OPTS_MASK] &&
+   nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]) != 
key->enc_opts.len)
+   return -EINVAL;
+
+   mask->enc_opts.len = key->enc_opts.len;
+   fl_set_key_val(tb, key->enc_opts.data, TCA_FLO

Re: [PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
On Wed, Sep 27, 2017 at 11:10:05AM +0200, Jiri Pirko wrote:
> Wed, Sep 27, 2017 at 10:16:34AM CEST, simon.hor...@netronome.com wrote:
> >Allow matching on options in tunnel headers.
> >This makes use of existing tunnel metadata support.
> >
> >Options are a bytestring of up to 256 bytes.
> >Tunnel implementations may support less or more options,
> >or no options at all.
> >
> >e.g.
> > # ip link add name geneve0 type geneve dstport 0 external
> > # tc qdisc add dev geneve0 ingress
> > # tc filter add dev geneve0 protocol ip parent : \
> > flower \
> >   enc_src_ip 10.0.99.192 \
> >   enc_dst_ip 10.0.99.193 \
> >   enc_key_id 11 \
> >   enc_opts 0102800100800020/fff0 \
> >   ip_proto udp \
> >   action mirred egress redirect dev eth1
> >
> >Signed-off-by: Simon Horman <simon.hor...@netronome.com>
> >Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
> >
> >---
> >v2
> >* Correct example which was incorrectly described setting rather
> >  than matching tunnel options
> >---
> > include/net/flow_dissector.h | 13 +
> > include/uapi/linux/pkt_cls.h |  3 +++
> > net/sched/cls_flower.c   | 35 ++-
> > 3 files changed, 50 insertions(+), 1 deletion(-)
> >
> >diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> >index fc3dce730a6b..43f98bf0b349 100644
> >--- a/include/net/flow_dissector.h
> >+++ b/include/net/flow_dissector.h
> >@@ -183,6 +183,18 @@ struct flow_dissector_key_ip {
> > __u8ttl;
> > };
> > 
> >+/**
> >+ * struct flow_dissector_key_enc_opts:
> >+ * @data: data
> >+ * @len: len
> >+ */
> >+struct flow_dissector_key_enc_opts {
> >+u8 data[256];   /* Using IP_TUNNEL_OPTS_MAX is desired here
> >+ * but seems difficult to #include
> >+ */
> >+u8 len;
> >+};
> >+
> > enum flow_dissector_key_id {
> > FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
> > FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> >@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
> > FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
> > FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
> > FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
> >+FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
> 
> I don't see the actual dissection implementation. Where is it?
> Did you test the patchset?

Yes, I did test it. But it is also possible something went astray along the
way and I will retest.

I think that the code you are looking for is in
fl_classify() in this patch.


Re: [PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
On Wed, Sep 27, 2017 at 01:08:22PM +0200, Jiri Pirko wrote:
> Wed, Sep 27, 2017 at 11:27:33AM CEST, simon.hor...@netronome.com wrote:
> >On Wed, Sep 27, 2017 at 11:10:05AM +0200, Jiri Pirko wrote:
> >> Wed, Sep 27, 2017 at 10:16:34AM CEST, simon.hor...@netronome.com wrote:
> >> >Allow matching on options in tunnel headers.
> >> >This makes use of existing tunnel metadata support.
> >> >
> >> >Options are a bytestring of up to 256 bytes.
> >> >Tunnel implementations may support less or more options,
> >> >or no options at all.
> >> >
> >> >e.g.
> >> > # ip link add name geneve0 type geneve dstport 0 external
> >> > # tc qdisc add dev geneve0 ingress
> >> > # tc filter add dev geneve0 protocol ip parent : \
> >> > flower \
> >> >   enc_src_ip 10.0.99.192 \
> >> >   enc_dst_ip 10.0.99.193 \
> >> >   enc_key_id 11 \
> >> >   enc_opts 0102800100800020/fff0 \
> >> >   ip_proto udp \
> >> >   action mirred egress redirect dev eth1
> >> >
> >> >Signed-off-by: Simon Horman <simon.hor...@netronome.com>
> >> >Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
> >> >
> >> >---
> >> >v2
> >> >* Correct example which was incorrectly described setting rather
> >> >  than matching tunnel options
> >> >---
> >> > include/net/flow_dissector.h | 13 +
> >> > include/uapi/linux/pkt_cls.h |  3 +++
> >> > net/sched/cls_flower.c   | 35 ++-
> >> > 3 files changed, 50 insertions(+), 1 deletion(-)
> >> >
> >> >diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> >> >index fc3dce730a6b..43f98bf0b349 100644
> >> >--- a/include/net/flow_dissector.h
> >> >+++ b/include/net/flow_dissector.h
> >> >@@ -183,6 +183,18 @@ struct flow_dissector_key_ip {
> >> >  __u8ttl;
> >> > };
> >> > 
> >> >+/**
> >> >+ * struct flow_dissector_key_enc_opts:
> >> >+ * @data: data
> >> >+ * @len: len
> >> >+ */
> >> >+struct flow_dissector_key_enc_opts {
> >> >+ u8 data[256];   /* Using IP_TUNNEL_OPTS_MAX is desired here
> >> >+  * but seems difficult to #include
> >> >+  */
> >> >+ u8 len;
> >> >+};
> >> >+
> >> > enum flow_dissector_key_id {
> >> >  FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
> >> >  FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> >> >@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
> >> >  FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
> >> >  FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
> >> >  FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
> >> >+ FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
> >> 
> >> I don't see the actual dissection implementation. Where is it?
> >> Did you test the patchset?
> >
> >Yes, I did test it. But it is also possible something went astray along the
> >way and I will retest.
> >
> >I think that the code you are looking for is in
> >fl_classify() in this patch.
> 
> The dissection should be done in the flow_dissector. That's the whole
> point in having it generic. You should move it there.
> 

Thanks, will do.


Re: [PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
On Wed, Sep 27, 2017 at 01:08:22PM +0200, Jiri Pirko wrote:
> Wed, Sep 27, 2017 at 11:27:33AM CEST, simon.hor...@netronome.com wrote:
> >On Wed, Sep 27, 2017 at 11:10:05AM +0200, Jiri Pirko wrote:
> >> Wed, Sep 27, 2017 at 10:16:34AM CEST, simon.hor...@netronome.com wrote:

...

> >> > enum flow_dissector_key_id {
> >> >  FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
> >> >  FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> >> >@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
> >> >  FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
> >> >  FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
> >> >  FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
> >> >+ FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
> >> 
> >> I don't see the actual dissection implementation. Where is it?
> >> Did you test the patchset?
> >
> >Yes, I did test it. But it is also possible something went astray along the
> >way and I will retest.
> >
> >I think that the code you are looking for is in
> >fl_classify() in this patch.
> 
> The dissection should be done in the flow_dissector. That's the whole
> point in having it generic. You should move it there.

Coming back to this after lunch, I believe what I have done in this patch
is consistent with handling of other enc fields, which are set in
fl_classify() rather than the dissector. In particular the ip_tunnel_info,
which is used by this patch, is already used in fl_classify().

Without this patch I see:


static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
   struct tcf_result *res)
{
...
struct ip_tunnel_info *info;

...

info = skb_tunnel_info(skb);
if (info) {
struct ip_tunnel_key *key = >key;

switch (ip_tunnel_info_af(info)) {
case AF_INET:
skb_key.enc_control.addr_type =
FLOW_DISSECTOR_KEY_IPV4_ADDRS;
skb_key.enc_ipv4.src = key->u.ipv4.src;
skb_key.enc_ipv4.dst = key->u.ipv4.dst;
break;
case AF_INET6:
skb_key.enc_control.addr_type =
FLOW_DISSECTOR_KEY_IPV6_ADDRS;
skb_key.enc_ipv6.src = key->u.ipv6.src;
skb_key.enc_ipv6.dst = key->u.ipv6.dst;
break;
}

skb_key.enc_key_id.keyid = tunnel_id_to_key32(key->tun_id);
skb_key.enc_tp.src = key->tp_src;
skb_key.enc_tp.dst = key->tp_dst;
}

...
}

This patch adds the following inside the if() clause above:

if (info->options_len) {
skb_key.enc_opts.len = info->options_len;
ip_tunnel_info_opts_get(skb_key.enc_opts.data, info);
}




Re: [PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
On Wed, Sep 27, 2017 at 02:56:03PM +0200, Jiri Pirko wrote:
> Wed, Sep 27, 2017 at 02:52:06PM CEST, simon.hor...@netronome.com wrote:
> >On Wed, Sep 27, 2017 at 01:08:22PM +0200, Jiri Pirko wrote:
> >> Wed, Sep 27, 2017 at 11:27:33AM CEST, simon.hor...@netronome.com wrote:
> >> >On Wed, Sep 27, 2017 at 11:10:05AM +0200, Jiri Pirko wrote:
> >> >> Wed, Sep 27, 2017 at 10:16:34AM CEST, simon.hor...@netronome.com wrote:
> >
> >...
> >
> >> >> > enum flow_dissector_key_id {
> >> >> >   FLOW_DISSECTOR_KEY_CONTROL, /* struct 
> >> >> > flow_dissector_key_control */
> >> >> >   FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> >> >> >@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
> >> >> >   FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
> >> >> >   FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
> >> >> >   FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
> >> >> >+  FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct 
> >> >> >flow_dissector_key_enc_opts */
> >> >> 
> >> >> I don't see the actual dissection implementation. Where is it?
> >> >> Did you test the patchset?
> >> >
> >> >Yes, I did test it. But it is also possible something went astray along 
> >> >the
> >> >way and I will retest.
> >> >
> >> >I think that the code you are looking for is in
> >> >fl_classify() in this patch.
> >> 
> >> The dissection should be done in the flow_dissector. That's the whole
> >> point in having it generic. You should move it there.
> >
> >Coming back to this after lunch, I believe what I have done in this patch
> >is consistent with handling of other enc fields, which are set in
> >fl_classify() rather than the dissector. In particular the ip_tunnel_info,
> >which is used by this patch, is already used in fl_classify().
> 
> That means the current code is wrong. The dissection should be done in
> flow_dissector, not in fl_classify.

Would an better approach be to move the fl_classify() below into, say,
skb_flow_dissect_tunnel_info() and call that from fl_classify().

The reason I suggest this rather than moving the code into
__skb_flow_dissect() is that currently flower assumes that tunnel_info
is used if present. While I assume other users of () assume tunnel_info
is not used even if present.

> >Without this patch I see:
> >
> >
> >static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
> >   struct tcf_result *res)
> >{
> >...
> >struct ip_tunnel_info *info;
> >
> >...
> >
> >info = skb_tunnel_info(skb);
> >if (info) {
> >struct ip_tunnel_key *key = >key;
> >
> >switch (ip_tunnel_info_af(info)) {
> >case AF_INET:
> >skb_key.enc_control.addr_type =
> >FLOW_DISSECTOR_KEY_IPV4_ADDRS;
> >skb_key.enc_ipv4.src = key->u.ipv4.src;
> >skb_key.enc_ipv4.dst = key->u.ipv4.dst;
> >break;
> >case AF_INET6:
> >skb_key.enc_control.addr_type =
> >FLOW_DISSECTOR_KEY_IPV6_ADDRS;
> >skb_key.enc_ipv6.src = key->u.ipv6.src;
> >skb_key.enc_ipv6.dst = key->u.ipv6.dst;
> >break;
> >}
> >
> >skb_key.enc_key_id.keyid = tunnel_id_to_key32(key->tun_id);
> >skb_key.enc_tp.src = key->tp_src;
> >skb_key.enc_tp.dst = key->tp_dst;
> >}
> >
> > ...
> >}
> >
> >This patch adds the following inside the if() clause above:
> >
> > if (info->options_len) {
> > skb_key.enc_opts.len = info->options_len;
> > ip_tunnel_info_opts_get(skb_key.enc_opts.data, info);
> > }
> >
> >


Re: [PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
On Wed, Sep 27, 2017 at 03:47:50PM +0200, Jiri Pirko wrote:
> Wed, Sep 27, 2017 at 03:37:33PM CEST, simon.hor...@netronome.com wrote:
> >On Wed, Sep 27, 2017 at 02:56:03PM +0200, Jiri Pirko wrote:
> >> Wed, Sep 27, 2017 at 02:52:06PM CEST, simon.hor...@netronome.com wrote:
> >> >On Wed, Sep 27, 2017 at 01:08:22PM +0200, Jiri Pirko wrote:
> >> >> Wed, Sep 27, 2017 at 11:27:33AM CEST, simon.hor...@netronome.com wrote:
> >> >> >On Wed, Sep 27, 2017 at 11:10:05AM +0200, Jiri Pirko wrote:
> >> >> >> Wed, Sep 27, 2017 at 10:16:34AM CEST, simon.hor...@netronome.com 
> >> >> >> wrote:
> >> >
> >> >...
> >> >
> >> >> >> > enum flow_dissector_key_id {
> >> >> >> >FLOW_DISSECTOR_KEY_CONTROL, /* struct 
> >> >> >> > flow_dissector_key_control */
> >> >> >> >FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> >> >> >> >@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
> >> >> >> >FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
> >> >> >> >FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
> >> >> >> >FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
> >> >> >> >+   FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct 
> >> >> >> >flow_dissector_key_enc_opts */
> >> >> >> 
> >> >> >> I don't see the actual dissection implementation. Where is it?
> >> >> >> Did you test the patchset?
> >> >> >
> >> >> >Yes, I did test it. But it is also possible something went astray 
> >> >> >along the
> >> >> >way and I will retest.
> >> >> >
> >> >> >I think that the code you are looking for is in
> >> >> >fl_classify() in this patch.
> >> >> 
> >> >> The dissection should be done in the flow_dissector. That's the whole
> >> >> point in having it generic. You should move it there.
> >> >
> >> >Coming back to this after lunch, I believe what I have done in this patch
> >> >is consistent with handling of other enc fields, which are set in
> >> >fl_classify() rather than the dissector. In particular the ip_tunnel_info,
> >> >which is used by this patch, is already used in fl_classify().
> >> 
> >> That means the current code is wrong. The dissection should be done in
> >> flow_dissector, not in fl_classify.
> >
> >Would an better approach be to move the fl_classify() below into, say,
> >skb_flow_dissect_tunnel_info() and call that from fl_classify().
> 
> No. There is one flow dissection function and you just set it up in a
> way you need it. Makes no sense to me to split it up in any way.
> 
> 
> >
> >The reason I suggest this rather than moving the code into
> >__skb_flow_dissect() is that currently flower assumes that tunnel_info
> >is used if present. While I assume other users of () assume tunnel_info
> >is not used even if present.
> 
> __skb_flow_dissect should look at what caller wants, then check 
> skb_tunnel_info
> only in case it is needed.

Ok, do you think it is sufficient for __skb_flow_dissect to look at the
tunnel keys, say FLOW_DISSECTOR_KEY_ENC_*? I am a bit concerned this may
break flower as it look at the tunnel info unconditionally.


Re: [PATCH v2 net-next 2/2] net/sched: allow flower to match tunnel options

2017-09-27 Thread Simon Horman
On Wed, Sep 27, 2017 at 04:00:11PM +0200, Jiri Pirko wrote:
> Wed, Sep 27, 2017 at 03:50:44PM CEST, simon.hor...@netronome.com wrote:
> >On Wed, Sep 27, 2017 at 03:47:50PM +0200, Jiri Pirko wrote:
> >> Wed, Sep 27, 2017 at 03:37:33PM CEST, simon.hor...@netronome.com wrote:
> >> >On Wed, Sep 27, 2017 at 02:56:03PM +0200, Jiri Pirko wrote:
> >> >> Wed, Sep 27, 2017 at 02:52:06PM CEST, simon.hor...@netronome.com wrote:
> >> >> >On Wed, Sep 27, 2017 at 01:08:22PM +0200, Jiri Pirko wrote:
> >> >> >> Wed, Sep 27, 2017 at 11:27:33AM CEST, simon.hor...@netronome.com 
> >> >> >> wrote:
> >> >> >> >On Wed, Sep 27, 2017 at 11:10:05AM +0200, Jiri Pirko wrote:
> >> >> >> >> Wed, Sep 27, 2017 at 10:16:34AM CEST, simon.hor...@netronome.com 
> >> >> >> >> wrote:
> >> >> >
> >> >> >...
> >> >> >
> >> >> >> >> > enum flow_dissector_key_id {
> >> >> >> >> > FLOW_DISSECTOR_KEY_CONTROL, /* struct 
> >> >> >> >> > flow_dissector_key_control */
> >> >> >> >> > FLOW_DISSECTOR_KEY_BASIC, /* struct 
> >> >> >> >> > flow_dissector_key_basic */
> >> >> >> >> >@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
> >> >> >> >> > FLOW_DISSECTOR_KEY_MPLS, /* struct 
> >> >> >> >> > flow_dissector_key_mpls */
> >> >> >> >> > FLOW_DISSECTOR_KEY_TCP, /* struct 
> >> >> >> >> > flow_dissector_key_tcp */
> >> >> >> >> > FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip 
> >> >> >> >> > */
> >> >> >> >> >+FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct 
> >> >> >> >> >flow_dissector_key_enc_opts */
> >> >> >> >> 
> >> >> >> >> I don't see the actual dissection implementation. Where is it?
> >> >> >> >> Did you test the patchset?
> >> >> >> >
> >> >> >> >Yes, I did test it. But it is also possible something went astray 
> >> >> >> >along the
> >> >> >> >way and I will retest.
> >> >> >> >
> >> >> >> >I think that the code you are looking for is in
> >> >> >> >fl_classify() in this patch.
> >> >> >> 
> >> >> >> The dissection should be done in the flow_dissector. That's the whole
> >> >> >> point in having it generic. You should move it there.
> >> >> >
> >> >> >Coming back to this after lunch, I believe what I have done in this 
> >> >> >patch
> >> >> >is consistent with handling of other enc fields, which are set in
> >> >> >fl_classify() rather than the dissector. In particular the 
> >> >> >ip_tunnel_info,
> >> >> >which is used by this patch, is already used in fl_classify().
> >> >> 
> >> >> That means the current code is wrong. The dissection should be done in
> >> >> flow_dissector, not in fl_classify.
> >> >
> >> >Would an better approach be to move the fl_classify() below into, say,
> >> >skb_flow_dissect_tunnel_info() and call that from fl_classify().
> >> 
> >> No. There is one flow dissection function and you just set it up in a
> >> way you need it. Makes no sense to me to split it up in any way.
> >> 
> >> 
> >> >
> >> >The reason I suggest this rather than moving the code into
> >> >__skb_flow_dissect() is that currently flower assumes that tunnel_info
> >> >is used if present. While I assume other users of () assume tunnel_info
> >> >is not used even if present.
> >> 
> >> __skb_flow_dissect should look at what caller wants, then check 
> >> skb_tunnel_info
> >> only in case it is needed.
> >
> >Ok, do you think it is sufficient for __skb_flow_dissect to look at the
> >tunnel keys, say FLOW_DISSECTOR_KEY_ENC_*? I am a bit concerned this may
> >break flower as it look at the tunnel info unconditionally.
> 
> yeah. When flower needs that, it will get that from the flow dissector.
> I don't see why it would break anything. Again, existing code is wrong:

I understand that you think the existing code is wrong.
But I also want to try not to add new bugs.

I am concerned about the case where none of FLOW_DISSECTOR_KEY_ENC_* are
set but flower currently dissects the tunnel info anyway. If I make
dissection of tunnel info dependent on FLOW_DISSECTOR_KEY_ENC_*
that may change things.


Re: [PATCH net-next 0/7] nfp: extend match and action for flower offload

2017-10-09 Thread Simon Horman
On Fri, Oct 06, 2017 at 08:34:59AM -0700, Tom Herbert wrote:
> Simon,
> 
> Maybe a bit off topic, but I had the impression netronome would
> support BPF so that filters could be programmed for arbitrary
> protocols and fields. Is that true? If so, what is the relationship
> between that functionality and these patches?

Hi Tom,

you are correct in thinking that Netronome is supporting BPF offload
in its nfp driver. That support continues to be enhanced and supported.

This patch-set relates to a different set of functionality, offload of the
TC flower classifier. At this point there is no relationship between the
two sets of functionality and they cannot be used at the same time;
different firmware images are required and the driver initiates itself
according to the firmware loaded.

In future it may be possible to use both BPF and TC flower offloads at the
same time but that is not the case at this time.

Does that answer your question?


[PATCH net-next v2 1/3] dt-bindings: net: sh_eth: add R-Car Gen[12] fallback compatibility strings

2017-10-18 Thread Simon Horman
Add fallback compatibility strings for R-Car Gen 1 and 2.

In the case of Renesas R-Car hardware we know that there are generations of
SoCs, f.e. Gen 1 and 2. But beyond that its not clear what the relationship
between IP blocks might be. For example, I believe that r8a7790 is older
than r8a7791 but that doesn't imply that the latter is a descendant of the
former or vice versa.

We can, however, by examining the documentation and behaviour of the
hardware at run-time observe that the current driver implementation appears
to be compatible with the IP blocks on SoCs within a given generation.

For the above reasons and convenience when enabling new SoCs a
per-generation fallback compatibility string scheme is being adopted for
drivers for Renesas SoCs.

Note that R-Car Gen2 and RZ/G1 have many compatible IP blocks.  The
approach that has been consistently taken for other IP blocks is to name
common code, compatibility strings and so on after R-Car Gen2.

Signed-off-by: Simon Horman <horms+rene...@verge.net.au>
Reviewed-by: Geert Uytterhoeven <geert+rene...@glider.be>
Reviewed-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>
---
v2
* Corrected typos in changelog
* Collected review tags
* Made whitespace usage consistent with existing text
* Add comma to "When compatible with the generic version, nodes must list"
---
 Documentation/devicetree/bindings/net/sh_eth.txt | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/sh_eth.txt 
b/Documentation/devicetree/bindings/net/sh_eth.txt
index 0115c85a2425..5172799a7f1a 100644
--- a/Documentation/devicetree/bindings/net/sh_eth.txt
+++ b/Documentation/devicetree/bindings/net/sh_eth.txt
@@ -4,7 +4,8 @@ This file provides information on what the device node for the 
SH EtherMAC
 interface contains.
 
 Required properties:
-- compatible: "renesas,gether-r8a7740" if the device is a part of R8A7740 SoC.
+- compatible: Must contain one or more of the following:
+ "renesas,gether-r8a7740" if the device is a part of R8A7740 SoC.
  "renesas,ether-r8a7743"  if the device is a part of R8A7743 SoC.
  "renesas,ether-r8a7745"  if the device is a part of R8A7745 SoC.
  "renesas,ether-r8a7778"  if the device is a part of R8A7778 SoC.
@@ -14,6 +15,14 @@ Required properties:
  "renesas,ether-r8a7793"  if the device is a part of R8A7793 SoC.
  "renesas,ether-r8a7794"  if the device is a part of R8A7794 SoC.
  "renesas,ether-r7s72100" if the device is a part of R7S72100 SoC.
+ "renesas,rcar-gen1-ether" for a generic R-Car Gen1 device.
+ "renesas,rcar-gen2-ether" for a generic R-Car Gen2 or RZ/G1
+   device.
+
+ When compatible with the generic version, nodes must list
+ the SoC-specific version corresponding to the platform
+ first followed by the generic version.
+
 - reg: offset and length of (1) the E-DMAC/feLic register block (required),
(2) the TSU register block (optional).
 - interrupts: interrupt specifier for the sole interrupt.
@@ -36,7 +45,8 @@ Optional properties:
 Example (Lager board):
 
ethernet@ee70 {
-   compatible = "renesas,ether-r8a7790";
+   compatible = "renesas,ether-r8a7790",
+"renesas,rcar-gen2-ether";
reg = <0 0xee70 0 0x400>;
interrupt-parent = <>;
interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.11.0



[PATCH net-next v2 3/3] net: sh_eth: implement R-Car Gen[12] fallback compatibility strings

2017-10-18 Thread Simon Horman
Implement fallback compatibility strings for R-Car Gen 1 and 2.

In the case of Renesas R-Car hardware we know that there are generations of
SoCs, f.e. Gen 1 and 2. But beyond that its not clear what the relationship
between IP blocks might be. For example, I believe that r8a7790 is older
than r8a7791 but that doesn't imply that the latter is a descendant of the
former or vice versa.

We can, however, by examining the documentation and behaviour of the
hardware at run-time observe that the current driver implementation appears
to be compatible with the IP blocks on SoCs within a given generation.

For the above reasons and convenience when enabling new SoCs a
per-generation fallback compatibility string scheme is being adopted for
drivers for Renesas SoCs.

Note that R-Car Gen2 and RZ/G1 have many compatible IP blocks.  The
approach that has been consistently taken for other IP blocks is to name
common code, compatibility strings and so on after R-Car Gen2.

Signed-off-by: Simon Horman <horms+rene...@verge.net.au>
Reviewed-by: Geert Uytterhoeven <geert+rene...@glider.be>
Acked-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>
---
v2
* Corrected typos in changelog
* Collected review tags
---
 drivers/net/ethernet/renesas/sh_eth.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/renesas/sh_eth.c 
b/drivers/net/ethernet/renesas/sh_eth.c
index c9f92fc8555e..7e060aa9fbed 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -3095,6 +3095,8 @@ static const struct of_device_id sh_eth_match_table[] = {
{ .compatible = "renesas,ether-r8a7793", .data = _gen2_data },
{ .compatible = "renesas,ether-r8a7794", .data = _gen2_data },
{ .compatible = "renesas,ether-r7s72100", .data = _data },
+   { .compatible = "renesas,rcar-gen1-ether", .data = _gen1_data },
+   { .compatible = "renesas,rcar-gen2-ether", .data = _gen2_data },
{ }
 };
 MODULE_DEVICE_TABLE(of, sh_eth_match_table);
-- 
2.11.0



[PATCH net-next v2 0/3] net: sh_eth: add R-Car Gen[12] fallback compatibility strings

2017-10-18 Thread Simon Horman
Add fallback compatibility strings for R-Car Gen 1 and 2.

In the case of Renesas R-Car hardware we know that there are generations of
SoCs, f.e. Gen 1 and 2. But beyond that its not clear what the relationship
between IP blocks might be. For example, I believe that r8a7790 is older
than r8a7791 but that doesn't imply that the latter is a descendant of the
former or vice versa.

We can, however, by examining the documentation and behaviour of the
hardware at run-time observe that the current driver implementation appears
to be compatible with the IP blocks on SoCs within a given generation.

For the above reasons and convenience when enabling new SoCs a
per-generation fallback compatibility string scheme is being adopted for
drivers for Renesas SoCs.

Changes since v1:
* Correct typos in changelogs
* Consistently use tabs for indentation in bindings document
* Enhance readability of description of bindings usage

Simon Horman (3):
  dt-bindings: net: sh_eth: add R-Car Gen[12] fallback compatibility
strings
  net: sh_eth: rename name structures as rcar_gen[12]_*
  net: sh_eth: implement R-Car Gen[12] fallback compatibility strings

 Documentation/devicetree/bindings/net/sh_eth.txt | 14 +--
 drivers/net/ethernet/renesas/sh_eth.c| 32 +---
 2 files changed, 29 insertions(+), 17 deletions(-)

-- 
2.11.0



[PATCH net-next v2 2/3] net: sh_eth: rename name structures as rcar_gen[12]_*

2017-10-18 Thread Simon Horman
Rename structures describing R-Car SoCs as rcar_gen[12]_*
rather than r8a77[79]x_*. This seems a little easier on the
eyes. And will make things slightly cleaner in a follow-up
patch that adds fallback-compatibility strings for these SoCs.

Note that R-Car Gen2 and RZ/G1 have many compatible IP blocks.  The
approach that has been consistently taken for other IP blocks is to name
common code, compatibility strings and so on after R-Car Gen2.

Also rename sh_eth_set_rate_r8a777x as sh_eth_set_rate_rcar as
it it is used by the R-Car generations supported by the driver.

This patch should have no run-time effect and
is compile-tested only.

Signed-off-by: Simon Horman <horms+rene...@verge.net.au>
Reviewed-by: Geert Uytterhoeven <geert+rene...@glider.be>
Acked-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>
---
v2
* Updated changelog
* Collected review tags
---
 drivers/net/ethernet/renesas/sh_eth.c | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/renesas/sh_eth.c 
b/drivers/net/ethernet/renesas/sh_eth.c
index d2e88a30f57b..c9f92fc8555e 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -594,7 +594,7 @@ static struct sh_eth_cpu_data r8a7740_data = {
 };
 
 /* There is CPU dependent code */
-static void sh_eth_set_rate_r8a777x(struct net_device *ndev)
+static void sh_eth_set_rate_rcar(struct net_device *ndev)
 {
struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -608,10 +608,10 @@ static void sh_eth_set_rate_r8a777x(struct net_device 
*ndev)
}
 }
 
-/* R8A7778/9 */
-static struct sh_eth_cpu_data r8a777x_data = {
+/* R-Car Gen1 */
+static struct sh_eth_cpu_data rcar_gen1_data = {
.set_duplex = sh_eth_set_duplex,
-   .set_rate   = sh_eth_set_rate_r8a777x,
+   .set_rate   = sh_eth_set_rate_rcar,
 
.register_type  = SH_ETH_REG_FAST_RCAR,
 
@@ -635,10 +635,10 @@ static struct sh_eth_cpu_data r8a777x_data = {
.hw_swap= 1,
 };
 
-/* R8A7790/1 */
-static struct sh_eth_cpu_data r8a779x_data = {
+/* R-Car Gen2 and RZ/G1 */
+static struct sh_eth_cpu_data rcar_gen2_data = {
.set_duplex = sh_eth_set_duplex,
-   .set_rate   = sh_eth_set_rate_r8a777x,
+   .set_rate   = sh_eth_set_rate_rcar,
 
.register_type  = SH_ETH_REG_FAST_RCAR,
 
@@ -3086,14 +3086,14 @@ static struct sh_eth_plat_data *sh_eth_parse_dt(struct 
device *dev)
 
 static const struct of_device_id sh_eth_match_table[] = {
{ .compatible = "renesas,gether-r8a7740", .data = _data },
-   { .compatible = "renesas,ether-r8a7743", .data = _data },
-   { .compatible = "renesas,ether-r8a7745", .data = _data },
-   { .compatible = "renesas,ether-r8a7778", .data = _data },
-   { .compatible = "renesas,ether-r8a7779", .data = _data },
-   { .compatible = "renesas,ether-r8a7790", .data = _data },
-   { .compatible = "renesas,ether-r8a7791", .data = _data },
-   { .compatible = "renesas,ether-r8a7793", .data = _data },
-   { .compatible = "renesas,ether-r8a7794", .data = _data },
+   { .compatible = "renesas,ether-r8a7743", .data = _gen2_data },
+   { .compatible = "renesas,ether-r8a7745", .data = _gen2_data },
+   { .compatible = "renesas,ether-r8a7778", .data = _gen1_data },
+   { .compatible = "renesas,ether-r8a7779", .data = _gen1_data },
+   { .compatible = "renesas,ether-r8a7790", .data = _gen2_data },
+   { .compatible = "renesas,ether-r8a7791", .data = _gen2_data },
+   { .compatible = "renesas,ether-r8a7793", .data = _gen2_data },
+   { .compatible = "renesas,ether-r8a7794", .data = _gen2_data },
{ .compatible = "renesas,ether-r7s72100", .data = _data },
{ }
 };
-- 
2.11.0



Re: [PATCH net-next 0/3] net: sh_eth: add R-Car Gen[12] fallback compatibility strings

2017-10-18 Thread Simon Horman
On Tue, Oct 17, 2017 at 09:47:44AM +0200, Simon Horman wrote:
> Add fallback compatibility strings for R-Car Gen 1 and 2.
> 
> In the case of Renesas R-Car hardware we know that there are generations of
> SoCs, f.e. Gen 1 and 2. But beyond that its not clear what the relationship
> between IP blocks might be. For example, I believe that r8a7790 is older
> than r8a7791 but that doesn't imply that the latter is a descendant of the
> former or vice versa.
> 
> We can, however, by examining the documentation and behaviour of the
> hardware at run-time observe that the current driver implementation appears
> to be compatible with the IP blocks on SoCs within a given generation.
> 
> For the above reasons and convenience when enabling new SoCs a
> per-generation fallback compatibility string scheme being adopted for
> drivers for Renesas SoCs.
> 
> Simon Horman (3):
>   dt-bindings: net: sh_eth: add R-Car Gen[12] fallback compatibility
> strings
>   net: sh_eth: rename name structures as rcar_gen[12]_*
>   net: sh_eth: implement R-Car Gen[12] fallback compatibility strings

There have been a few comments on this series, I will post v2.


Re: [PATCH v2] netfilter: mark expected switch fall-throughs

2017-11-13 Thread Simon Horman
On Tue, Nov 07, 2017 at 08:19:29AM -0600, Gustavo A. R. Silva wrote:
> In preparation to enabling -Wimplicit-fallthrough, mark switch cases
> where we are expecting to fall through.
> 
> Addresses-Coverity-ID: 1128839
> Addresses-Coverity-ID: 1128840
> Addresses-Coverity-ID: 115120
> Addresses-Coverity-ID: 115121
> Signed-off-by: Gustavo A. R. Silva <garsi...@embeddedor.com>

Signed-off-by: Simon Horman <ho...@verge.net.au>

Pablo, could you take this one directly?


[PATCH net-next 08/10] nfp: dump firmware name

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

Dump FW name as TLV, based on dump specification.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 36 ++
 1 file changed, 36 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index 833036715ca0..1e57dab60abf 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -45,6 +45,7 @@
 enum nfp_dumpspec_type {
NFP_DUMPSPEC_TYPE_RTSYM = 4,
NFP_DUMPSPEC_TYPE_HWINFO = 5,
+   NFP_DUMPSPEC_TYPE_FWNAME = 6,
NFP_DUMPSPEC_TYPE_HWINFO_FIELD = 7,
NFP_DUMPSPEC_TYPE_PROLOG = 1,
NFP_DUMPSPEC_TYPE_ERROR = 10001,
@@ -198,6 +199,13 @@ static int nfp_dump_error_tlv_size(struct nfp_dump_tl 
*spec)
  be32_to_cpu(spec->length));
 }
 
+static int nfp_calc_fwname_tlv_size(struct nfp_pf *pf)
+{
+   u32 fwname_len = strlen(nfp_mip_name(pf->mip));
+
+   return sizeof(struct nfp_dump_tl) + ALIGN8(fwname_len + 1);
+}
+
 static int nfp_calc_hwinfo_field_sz(struct nfp_pf *pf, struct nfp_dump_tl 
*spec)
 {
u32 tl_len, key_len;
@@ -244,6 +252,9 @@ nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, 
void *param)
u32 hwinfo_size;
 
switch (be32_to_cpu(tl->type)) {
+   case NFP_DUMPSPEC_TYPE_FWNAME:
+   *size += nfp_calc_fwname_tlv_size(pf);
+   break;
case NFP_DUMPSPEC_TYPE_RTSYM:
*size += nfp_calc_rtsym_dump_sz(pf, tl);
break;
@@ -333,6 +344,26 @@ nfp_dump_error_tlv(struct nfp_dump_tl *spec, int error,
return 0;
 }
 
+static int nfp_dump_fwname(struct nfp_pf *pf, struct nfp_dump_state *dump)
+{
+   struct nfp_dump_tl *dump_header = dump->p;
+   u32 fwname_len, total_size;
+   const char *fwname;
+   int err;
+
+   fwname = nfp_mip_name(pf->mip);
+   fwname_len = strlen(fwname);
+   total_size = sizeof(*dump_header) + ALIGN8(fwname_len + 1);
+
+   err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_FWNAME, total_size, dump);
+   if (err)
+   return err;
+
+   memcpy(dump_header->data, fwname, fwname_len);
+
+   return 0;
+}
+
 static int
 nfp_dump_hwinfo(struct nfp_pf *pf, struct nfp_dump_tl *spec,
struct nfp_dump_state *dump)
@@ -451,6 +482,11 @@ nfp_dump_for_tlv(struct nfp_pf *pf, struct nfp_dump_tl 
*tl, void *param)
int err;
 
switch (be32_to_cpu(tl->type)) {
+   case NFP_DUMPSPEC_TYPE_FWNAME:
+   err = nfp_dump_fwname(pf, dump);
+   if (err)
+   return err;
+   break;
case NFP_DUMPSPEC_TYPE_RTSYM:
spec_rtsym = (struct nfp_dumpspec_rtsym *)tl;
err = nfp_dump_single_rtsym(pf, spec_rtsym, dump);
-- 
2.11.0



[PATCH net-next 03/10] nfp: dump prolog

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- Use a TLV structure, with the typed chunks aligned to 8-byte sizes.
- Dump numeric fields as big-endian.
- Prolog contains the dump level.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 88 +-
 1 file changed, 86 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index 15b6623ef0b2..f05566fd12a2 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -40,6 +40,37 @@
 
 #define NFP_DUMP_SPEC_RTSYM"_abi_dump_spec"
 
+#define ALIGN8(x)  ALIGN(x, 8)
+
+enum nfp_dumpspec_type {
+   NFP_DUMPSPEC_TYPE_PROLOG = 1,
+};
+
+/* The following structs must be carefully aligned so that they can be used to
+ * interpret the binary dumpspec and populate the dump data in a deterministic
+ * way.
+ */
+
+/* generic type plus length */
+struct nfp_dump_tl {
+   __be32 type;
+   __be32 length;  /* chunk length to follow, aligned to 8 bytes */
+   char data[0];
+};
+
+struct nfp_dump_prolog {
+   struct nfp_dump_tl tl;
+   __be32 dump_level;
+};
+
+/* to track state during debug dump creation TLV traversal */
+struct nfp_dump_state {
+   u32 requested_level;/* input param */
+   u32 dumped_size;/* adds up to size of dumped data */
+   u32 buf_size;   /* size of buffer pointer to by p */
+   void *p;/* current point in dump buffer */
+};
+
 struct nfp_dumpspec *
 nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
 {
@@ -76,11 +107,64 @@ nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct 
nfp_rtsym_table *rtbl)
 s64 nfp_net_dump_calculate_size(struct nfp_pf *pf, struct nfp_dumpspec *spec,
u32 flag)
 {
-   return -EOPNOTSUPP;
+   return ALIGN8(sizeof(struct nfp_dump_prolog));
+}
+
+static int nfp_add_tlv(u32 type, u32 total_tlv_sz, struct nfp_dump_state *dump)
+{
+   struct nfp_dump_tl *tl = dump->p;
+
+   if (total_tlv_sz > dump->buf_size)
+   return -ENOSPC;
+
+   if (dump->buf_size - total_tlv_sz < dump->dumped_size)
+   return -ENOSPC;
+
+   tl->type = cpu_to_be32(type);
+   tl->length = cpu_to_be32(total_tlv_sz - sizeof(*tl));
+
+   dump->dumped_size += total_tlv_sz;
+   dump->p += total_tlv_sz;
+
+   return 0;
+}
+
+static int nfp_dump_populate_prolog(struct nfp_dump_state *dump)
+{
+   struct nfp_dump_prolog *prolog = dump->p;
+   u32 total_size;
+   int err;
+
+   total_size = ALIGN8(sizeof(*prolog));
+
+   err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_PROLOG, total_size, dump);
+   if (err)
+   return err;
+
+   prolog->dump_level = cpu_to_be32(dump->requested_level);
+
+   return 0;
 }
 
 int nfp_net_dump_populate_buffer(struct nfp_pf *pf, struct nfp_dumpspec *spec,
 struct ethtool_dump *dump_param, void *dest)
 {
-   return -EOPNOTSUPP;
+   struct nfp_dump_state dump;
+   int err;
+
+   dump.requested_level = dump_param->flag;
+   dump.dumped_size = 0;
+   dump.p = dest;
+   dump.buf_size = dump_param->len;
+
+   err = nfp_dump_populate_prolog();
+   if (err)
+   return err;
+
+   /* Set size of actual dump, to trigger warning if different from
+* calculated size.
+*/
+   dump_param->len = dump.dumped_size;
+
+   return 0;
 }
-- 
2.11.0



[PATCH net-next 09/10] nfp: dump CPP, XPB and direct ME CSRs

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- The spec defines CSR address ranges for these types.
- Dump each TLV chunk in the spec as a chunk that includes the spec and
  the data over the defined address range.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 102 +
 1 file changed, 102 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index 1e57dab60abf..b23e2e0570af 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -43,6 +43,9 @@
 #define ALIGN8(x)  ALIGN(x, 8)
 
 enum nfp_dumpspec_type {
+   NFP_DUMPSPEC_TYPE_CPP_CSR = 0,
+   NFP_DUMPSPEC_TYPE_XPB_CSR = 1,
+   NFP_DUMPSPEC_TYPE_ME_CSR = 2,
NFP_DUMPSPEC_TYPE_RTSYM = 4,
NFP_DUMPSPEC_TYPE_HWINFO = 5,
NFP_DUMPSPEC_TYPE_FWNAME = 6,
@@ -77,11 +80,27 @@ struct nfp_dump_common_cpp {
__be32 dump_length; /* total bytes to dump, aligned to reg size */
 };
 
+/* CSR dumpables */
+struct nfp_dumpspec_csr {
+   struct nfp_dump_tl tl;
+   struct nfp_dump_common_cpp cpp;
+   __be32 register_width;  /* in bits */
+};
+
 struct nfp_dumpspec_rtsym {
struct nfp_dump_tl tl;
char rtsym[0];
 };
 
+/* header for register dumpable */
+struct nfp_dump_csr {
+   struct nfp_dump_tl tl;
+   struct nfp_dump_common_cpp cpp;
+   __be32 register_width;  /* in bits */
+   __be32 error;   /* error code encountered while reading */
+   __be32 error_offset;/* offset being read when error occurred */
+};
+
 struct nfp_dump_rtsym {
struct nfp_dump_tl tl;
struct nfp_dump_common_cpp cpp;
@@ -223,6 +242,20 @@ static int nfp_calc_hwinfo_field_sz(struct nfp_pf *pf, 
struct nfp_dump_tl *spec)
return sizeof(struct nfp_dump_tl) + ALIGN8(key_len + strlen(value) + 2);
 }
 
+static bool nfp_csr_spec_valid(struct nfp_dumpspec_csr *spec_csr)
+{
+   u32 required_read_sz = sizeof(*spec_csr) - sizeof(spec_csr->tl);
+   u32 available_sz = be32_to_cpu(spec_csr->tl.length);
+   u32 reg_width;
+
+   if (available_sz < required_read_sz)
+   return false;
+
+   reg_width = be32_to_cpu(spec_csr->register_width);
+
+   return reg_width == 32 || reg_width == 64;
+}
+
 static int
 nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
 {
@@ -248,6 +281,7 @@ nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct 
nfp_dump_tl *spec)
 static int
 nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, void *param)
 {
+   struct nfp_dumpspec_csr *spec_csr;
u32 *size = param;
u32 hwinfo_size;
 
@@ -255,6 +289,16 @@ nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl 
*tl, void *param)
case NFP_DUMPSPEC_TYPE_FWNAME:
*size += nfp_calc_fwname_tlv_size(pf);
break;
+   case NFP_DUMPSPEC_TYPE_CPP_CSR:
+   case NFP_DUMPSPEC_TYPE_XPB_CSR:
+   case NFP_DUMPSPEC_TYPE_ME_CSR:
+   spec_csr = (struct nfp_dumpspec_csr *)tl;
+   if (!nfp_csr_spec_valid(spec_csr))
+   *size += nfp_dump_error_tlv_size(tl);
+   else
+   *size += ALIGN8(sizeof(struct nfp_dump_csr)) +
+ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length));
+   break;
case NFP_DUMPSPEC_TYPE_RTSYM:
*size += nfp_calc_rtsym_dump_sz(pf, tl);
break;
@@ -418,6 +462,55 @@ static int nfp_dump_hwinfo_field(struct nfp_pf *pf, struct 
nfp_dump_tl *spec,
 }
 
 static int
+nfp_dump_csr_range(struct nfp_pf *pf, struct nfp_dumpspec_csr *spec_csr,
+  struct nfp_dump_state *dump)
+{
+   struct nfp_dump_csr *dump_header = dump->p;
+   u32 reg_sz, header_size, total_size;
+   u32 cpp_rd_addr, max_rd_addr;
+   int bytes_read;
+   void *dest;
+   u32 cpp_id;
+   int err;
+
+   if (!nfp_csr_spec_valid(spec_csr))
+   return nfp_dump_error_tlv(_csr->tl, -EINVAL, dump);
+
+   reg_sz = be32_to_cpu(spec_csr->register_width) / BITS_PER_BYTE;
+   header_size = ALIGN8(sizeof(*dump_header));
+   total_size = header_size +
+ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length));
+   dest = dump->p + header_size;
+
+   err = nfp_add_tlv(be32_to_cpu(spec_csr->tl.type), total_size, dump);
+   if (err)
+   return err;
+
+   dump_header->cpp = spec_csr->cpp;
+   dump_header->register_width = spec_csr->register_width;
+
+   cpp_id = nfp_get_numeric_cpp_id(_csr->cpp.cpp_id);
+   cpp_rd_addr = be32_to_cpu(spec_csr->cpp.offset)

[PATCH net-next 10/10] nfp: dump indirect ME CSRs

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- The spec defines CSR address ranges for indirect ME CSRs. For Each TLV
  chunk in the spec, dump a chunk that includes the spec and the data
  over the defined address range.
- Each indirect CSR has 8 contexts. To read one context, first write the
  context to a specific derived address, read it back, and then read the
  register value.
- For each address, read and dump all 8 contexts in this manner.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_asm.h   |  10 ++
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 113 +
 2 files changed, 123 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.h 
b/drivers/net/ethernet/netronome/nfp/nfp_asm.h
index 98803f9f40b6..3387e6926eb0 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_asm.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.h
@@ -262,6 +262,7 @@ enum lcsr_wr_src {
 #define OP_CARB_BASE   0x0e0ULL
 #define OP_CARB_OR 0x001ULL
 
+#define NFP_CSR_CTX_PTR0x20
 #define NFP_CSR_ACT_LM_ADDR0   0x64
 #define NFP_CSR_ACT_LM_ADDR1   0x6c
 #define NFP_CSR_ACT_LM_ADDR2   0x94
@@ -382,4 +383,13 @@ int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg,
 int nfp_ustore_check_valid_no_ecc(u64 insn);
 u64 nfp_ustore_calc_ecc_insn(u64 insn);
 
+#define NFP_IND_ME_REFL_WR_SIG_INIT3
+#define NFP_IND_ME_CTX_PTR_BASE_MASK   GENMASK(9, 0)
+#define NFP_IND_NUM_CONTEXTS   8
+
+static inline u32 nfp_get_ind_csr_ctx_ptr_offs(u32 read_offset)
+{
+   return (read_offset & ~NFP_IND_ME_CTX_PTR_BASE_MASK) | NFP_CSR_CTX_PTR;
+}
+
 #endif
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index b23e2e0570af..cb74602f0907 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 
+#include "nfp_asm.h"
 #include "nfp_main.h"
 #include "nfpcore/nfp.h"
 #include "nfpcore/nfp_nffw.h"
@@ -46,6 +47,7 @@ enum nfp_dumpspec_type {
NFP_DUMPSPEC_TYPE_CPP_CSR = 0,
NFP_DUMPSPEC_TYPE_XPB_CSR = 1,
NFP_DUMPSPEC_TYPE_ME_CSR = 2,
+   NFP_DUMPSPEC_TYPE_INDIRECT_ME_CSR = 3,
NFP_DUMPSPEC_TYPE_RTSYM = 4,
NFP_DUMPSPEC_TYPE_HWINFO = 5,
NFP_DUMPSPEC_TYPE_FWNAME = 6,
@@ -299,6 +301,15 @@ nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl 
*tl, void *param)
*size += ALIGN8(sizeof(struct nfp_dump_csr)) +
 ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length));
break;
+   case NFP_DUMPSPEC_TYPE_INDIRECT_ME_CSR:
+   spec_csr = (struct nfp_dumpspec_csr *)tl;
+   if (!nfp_csr_spec_valid(spec_csr))
+   *size += nfp_dump_error_tlv_size(tl);
+   else
+   *size += ALIGN8(sizeof(struct nfp_dump_csr)) +
+ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length) *
+   NFP_IND_NUM_CONTEXTS);
+   break;
case NFP_DUMPSPEC_TYPE_RTSYM:
*size += nfp_calc_rtsym_dump_sz(pf, tl);
break;
@@ -510,6 +521,102 @@ nfp_dump_csr_range(struct nfp_pf *pf, struct 
nfp_dumpspec_csr *spec_csr,
return 0;
 }
 
+/* Write context to CSRCtxPtr, then read from it. Then the value can be read
+ * from IndCtxStatus.
+ */
+static int
+nfp_read_indirect_csr(struct nfp_cpp *cpp,
+ struct nfp_dumpspec_cpp_isl_id cpp_params, u32 offset,
+ u32 reg_sz, u32 context, void *dest)
+{
+   u32 csr_ctx_ptr_offs;
+   u32 cpp_id;
+   int result;
+
+   csr_ctx_ptr_offs = nfp_get_ind_csr_ctx_ptr_offs(offset);
+   cpp_id = NFP_CPP_ISLAND_ID(cpp_params.target,
+  NFP_IND_ME_REFL_WR_SIG_INIT,
+  cpp_params.token, cpp_params.island);
+   result = nfp_cpp_writel(cpp, cpp_id, csr_ctx_ptr_offs, context);
+   if (result != sizeof(context))
+   return result < 0 ? result : -EIO;
+
+   cpp_id = nfp_get_numeric_cpp_id(_params);
+   result = nfp_cpp_read(cpp, cpp_id, csr_ctx_ptr_offs, dest, reg_sz);
+   if (result != reg_sz)
+   return result < 0 ? result : -EIO;
+
+   result = nfp_cpp_read(cpp, cpp_id, offset, dest, reg_sz);
+   if (result != reg_sz)
+   return result < 0 ? result : -EIO;
+
+   return 0;
+}
+
+static int
+nfp_read_all_indirect_csr_ctx(struct nfp_cpp *cpp,
+ struct nfp_dumpspec_csr *spec_csr, u32 address,
+ u32 r

[PATCH net-next 04/10] nfp: dumpspec TLV traversal

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- Perform dumpspec traversals for calculating size and populating the
  dump.
- Initially, wrap all spec TLVs in dump error TLVs (changed by later
  patches in the series).

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 154 -
 1 file changed, 153 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index f05566fd12a2..d52e01ca6621 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -44,6 +44,7 @@
 
 enum nfp_dumpspec_type {
NFP_DUMPSPEC_TYPE_PROLOG = 1,
+   NFP_DUMPSPEC_TYPE_ERROR = 10001,
 };
 
 /* The following structs must be carefully aligned so that they can be used to
@@ -63,6 +64,19 @@ struct nfp_dump_prolog {
__be32 dump_level;
 };
 
+struct nfp_dump_error {
+   struct nfp_dump_tl tl;
+   __be32 error;
+   char padding[4];
+   char spec[0];
+};
+
+/* to track state through debug size calculation TLV traversal */
+struct nfp_level_size {
+   u32 requested_level;/* input */
+   u32 total_size; /* output */
+};
+
 /* to track state during debug dump creation TLV traversal */
 struct nfp_dump_state {
u32 requested_level;/* input param */
@@ -71,6 +85,43 @@ struct nfp_dump_state {
void *p;/* current point in dump buffer */
 };
 
+typedef int (*nfp_tlv_visit)(struct nfp_pf *pf, struct nfp_dump_tl *tl,
+void *param);
+
+static int
+nfp_traverse_tlvs(struct nfp_pf *pf, void *data, u32 data_length, void *param,
+ nfp_tlv_visit tlv_visit)
+{
+   long long remaining = data_length;
+   struct nfp_dump_tl *tl;
+   u32 total_tlv_size;
+   void *p = data;
+   int err;
+
+   while (remaining >= sizeof(*tl)) {
+   tl = p;
+   if (!tl->type && !tl->length)
+   break;
+
+   if (be32_to_cpu(tl->length) > remaining - sizeof(*tl))
+   return -EINVAL;
+
+   total_tlv_size = sizeof(*tl) + be32_to_cpu(tl->length);
+
+   /* Spec TLVs should be aligned to 4 bytes. */
+   if (total_tlv_size % 4 != 0)
+   return -EINVAL;
+
+   p += total_tlv_size;
+   remaining -= total_tlv_size;
+   err = tlv_visit(pf, tl, param);
+   if (err)
+   return err;
+   }
+
+   return 0;
+}
+
 struct nfp_dumpspec *
 nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
 {
@@ -104,10 +155,55 @@ nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct 
nfp_rtsym_table *rtbl)
return dumpspec;
 }
 
+static int nfp_dump_error_tlv_size(struct nfp_dump_tl *spec)
+{
+   return ALIGN8(sizeof(struct nfp_dump_error) + sizeof(*spec) +
+ be32_to_cpu(spec->length));
+}
+
+static int
+nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, void *param)
+{
+   u32 *size = param;
+
+   switch (be32_to_cpu(tl->type)) {
+   default:
+   *size += nfp_dump_error_tlv_size(tl);
+   break;
+   }
+
+   return 0;
+}
+
+static int
+nfp_calc_specific_level_size(struct nfp_pf *pf, struct nfp_dump_tl *dump_level,
+void *param)
+{
+   struct nfp_level_size *lev_sz = param;
+
+   if (be32_to_cpu(dump_level->type) != lev_sz->requested_level)
+   return 0;
+
+   return nfp_traverse_tlvs(pf, dump_level->data,
+be32_to_cpu(dump_level->length),
+_sz->total_size, nfp_add_tlv_size);
+}
+
 s64 nfp_net_dump_calculate_size(struct nfp_pf *pf, struct nfp_dumpspec *spec,
u32 flag)
 {
-   return ALIGN8(sizeof(struct nfp_dump_prolog));
+   struct nfp_level_size lev_sz;
+   int err;
+
+   lev_sz.requested_level = flag;
+   lev_sz.total_size = ALIGN8(sizeof(struct nfp_dump_prolog));
+
+   err = nfp_traverse_tlvs(pf, spec->data, spec->size, _sz,
+   nfp_calc_specific_level_size);
+   if (err)
+   return err;
+
+   return lev_sz.total_size;
 }
 
 static int nfp_add_tlv(u32 type, u32 total_tlv_sz, struct nfp_dump_state *dump)
@@ -129,6 +225,57 @@ static int nfp_add_tlv(u32 type, u32 total_tlv_sz, struct 
nfp_dump_state *dump)
return 0;
 }
 
+static int
+nfp_dump_error_tlv(struct nfp_dump_tl *spec, int error,
+  struct nfp_dump_state *dump)
+{
+   struct nfp_dump_error *du

[PATCH net-next 07/10] nfp: dump single hwinfo field by key

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- Add spec TLV for hwinfo field, containing key string as data.
- Add dump TLV for hwinfo field, with data being key and value as packed
  zero-terminated strings.
- If specified hwinfo field is not found, dump the spec TLV as -ENOENT
  error.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 57 ++
 1 file changed, 57 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index 449cf0a3a158..833036715ca0 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -45,6 +45,7 @@
 enum nfp_dumpspec_type {
NFP_DUMPSPEC_TYPE_RTSYM = 4,
NFP_DUMPSPEC_TYPE_HWINFO = 5,
+   NFP_DUMPSPEC_TYPE_HWINFO_FIELD = 7,
NFP_DUMPSPEC_TYPE_PROLOG = 1,
NFP_DUMPSPEC_TYPE_ERROR = 10001,
 };
@@ -197,6 +198,23 @@ static int nfp_dump_error_tlv_size(struct nfp_dump_tl 
*spec)
  be32_to_cpu(spec->length));
 }
 
+static int nfp_calc_hwinfo_field_sz(struct nfp_pf *pf, struct nfp_dump_tl 
*spec)
+{
+   u32 tl_len, key_len;
+   const char *value;
+
+   tl_len = be32_to_cpu(spec->length);
+   key_len = strnlen(spec->data, tl_len);
+   if (key_len == tl_len)
+   return nfp_dump_error_tlv_size(spec);
+
+   value = nfp_hwinfo_lookup(pf->hwinfo, spec->data);
+   if (!value)
+   return nfp_dump_error_tlv_size(spec);
+
+   return sizeof(struct nfp_dump_tl) + ALIGN8(key_len + strlen(value) + 2);
+}
+
 static int
 nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
 {
@@ -233,6 +251,9 @@ nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, 
void *param)
hwinfo_size = nfp_hwinfo_get_packed_str_size(pf->hwinfo);
*size += sizeof(struct nfp_dump_tl) + ALIGN8(hwinfo_size);
break;
+   case NFP_DUMPSPEC_TYPE_HWINFO_FIELD:
+   *size += nfp_calc_hwinfo_field_sz(pf, tl);
+   break;
default:
*size += nfp_dump_error_tlv_size(tl);
break;
@@ -334,6 +355,37 @@ nfp_dump_hwinfo(struct nfp_pf *pf, struct nfp_dump_tl 
*spec,
return 0;
 }
 
+static int nfp_dump_hwinfo_field(struct nfp_pf *pf, struct nfp_dump_tl *spec,
+struct nfp_dump_state *dump)
+{
+   struct nfp_dump_tl *dump_header = dump->p;
+   u32 tl_len, key_len, val_len;
+   const char *key, *value;
+   u32 total_size;
+   int err;
+
+   tl_len = be32_to_cpu(spec->length);
+   key_len = strnlen(spec->data, tl_len);
+   if (key_len == tl_len)
+   return nfp_dump_error_tlv(spec, -EINVAL, dump);
+
+   key = spec->data;
+   value = nfp_hwinfo_lookup(pf->hwinfo, key);
+   if (!value)
+   return nfp_dump_error_tlv(spec, -ENOENT, dump);
+
+   val_len = strlen(value);
+   total_size = sizeof(*dump_header) + ALIGN8(key_len + val_len + 2);
+   err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_HWINFO_FIELD, total_size, dump);
+   if (err)
+   return err;
+
+   memcpy(dump_header->data, key, key_len + 1);
+   memcpy(dump_header->data + key_len + 1, value, val_len + 1);
+
+   return 0;
+}
+
 static int
 nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
  struct nfp_dump_state *dump)
@@ -410,6 +462,11 @@ nfp_dump_for_tlv(struct nfp_pf *pf, struct nfp_dump_tl 
*tl, void *param)
if (err)
return err;
break;
+   case NFP_DUMPSPEC_TYPE_HWINFO_FIELD:
+   err = nfp_dump_hwinfo_field(pf, tl, dump);
+   if (err)
+   return err;
+   break;
default:
err = nfp_dump_error_tlv(tl, -EOPNOTSUPP, dump);
if (err)
-- 
2.11.0



[PATCH net-next 06/10] nfp: dump all hwinfo

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- Dump hwinfo as separate TLV chunk, in a packed format containing
  zero-separated key and value strings.
- This provides additional debug context, if requested by the dumpspec.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 33 ++
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h   |  2 ++
 .../ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c| 10 +++
 3 files changed, 45 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index 746e114a8da8..449cf0a3a158 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -44,6 +44,7 @@
 
 enum nfp_dumpspec_type {
NFP_DUMPSPEC_TYPE_RTSYM = 4,
+   NFP_DUMPSPEC_TYPE_HWINFO = 5,
NFP_DUMPSPEC_TYPE_PROLOG = 1,
NFP_DUMPSPEC_TYPE_ERROR = 10001,
 };
@@ -222,11 +223,16 @@ static int
 nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, void *param)
 {
u32 *size = param;
+   u32 hwinfo_size;
 
switch (be32_to_cpu(tl->type)) {
case NFP_DUMPSPEC_TYPE_RTSYM:
*size += nfp_calc_rtsym_dump_sz(pf, tl);
break;
+   case NFP_DUMPSPEC_TYPE_HWINFO:
+   hwinfo_size = nfp_hwinfo_get_packed_str_size(pf->hwinfo);
+   *size += sizeof(struct nfp_dump_tl) + ALIGN8(hwinfo_size);
+   break;
default:
*size += nfp_dump_error_tlv_size(tl);
break;
@@ -307,6 +313,28 @@ nfp_dump_error_tlv(struct nfp_dump_tl *spec, int error,
 }
 
 static int
+nfp_dump_hwinfo(struct nfp_pf *pf, struct nfp_dump_tl *spec,
+   struct nfp_dump_state *dump)
+{
+   struct nfp_dump_tl *dump_header = dump->p;
+   u32 hwinfo_size, total_size;
+   char *hwinfo;
+   int err;
+
+   hwinfo = nfp_hwinfo_get_packed_strings(pf->hwinfo);
+   hwinfo_size = nfp_hwinfo_get_packed_str_size(pf->hwinfo);
+   total_size = sizeof(*dump_header) + ALIGN8(hwinfo_size);
+
+   err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_HWINFO, total_size, dump);
+   if (err)
+   return err;
+
+   memcpy(dump_header->data, hwinfo, hwinfo_size);
+
+   return 0;
+}
+
+static int
 nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
  struct nfp_dump_state *dump)
 {
@@ -377,6 +405,11 @@ nfp_dump_for_tlv(struct nfp_pf *pf, struct nfp_dump_tl 
*tl, void *param)
if (err)
return err;
break;
+   case NFP_DUMPSPEC_TYPE_HWINFO:
+   err = nfp_dump_hwinfo(pf, tl, dump);
+   if (err)
+   return err;
+   break;
default:
err = nfp_dump_error_tlv(tl, -EOPNOTSUPP, dump);
if (err)
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
index 3ce51f03126f..ced62d112aa2 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
@@ -49,6 +49,8 @@
 struct nfp_hwinfo;
 struct nfp_hwinfo *nfp_hwinfo_read(struct nfp_cpp *cpp);
 const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup);
+char *nfp_hwinfo_get_packed_strings(struct nfp_hwinfo *hwinfo);
+u32 nfp_hwinfo_get_packed_str_size(struct nfp_hwinfo *hwinfo);
 
 /* Implemented in nfp_nsp.c, low level functions */
 
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c
index 4f24aff1e772..063a9a6243d6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c
@@ -302,3 +302,13 @@ const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, 
const char *lookup)
 
return NULL;
 }
+
+char *nfp_hwinfo_get_packed_strings(struct nfp_hwinfo *hwinfo)
+{
+   return hwinfo->data;
+}
+
+u32 nfp_hwinfo_get_packed_str_size(struct nfp_hwinfo *hwinfo)
+{
+   return le32_to_cpu(hwinfo->size) - sizeof(u32);
+}
-- 
2.11.0



[PATCH net-next 02/10] nfp: load debug dump spec

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

Load the TLV-based binary specification of what needs to be included in
a dump, from the "_abi_dump_spec" rtsymbol. If the symbol is not defined,
then dumps for levels >= 1 are not supported.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index a7061b6c609d..15b6623ef0b2 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -32,13 +32,45 @@
  */
 
 #include 
+#include 
 
 #include "nfp_main.h"
+#include "nfpcore/nfp.h"
+#include "nfpcore/nfp_nffw.h"
+
+#define NFP_DUMP_SPEC_RTSYM"_abi_dump_spec"
 
 struct nfp_dumpspec *
 nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
 {
-   return NULL;
+   const struct nfp_rtsym *specsym;
+   struct nfp_dumpspec *dumpspec;
+   int bytes_read;
+   u32 cpp_id;
+
+   specsym = nfp_rtsym_lookup(rtbl, NFP_DUMP_SPEC_RTSYM);
+   if (!specsym)
+   return NULL;
+
+   /* expected size of this buffer is in the order of tens of kilobytes */
+   dumpspec = vmalloc(sizeof(*dumpspec) + specsym->size);
+   if (!dumpspec)
+   return NULL;
+
+   dumpspec->size = specsym->size;
+
+   cpp_id = NFP_CPP_ISLAND_ID(specsym->target, NFP_CPP_ACTION_RW, 0,
+  specsym->domain);
+
+   bytes_read = nfp_cpp_read(cpp, cpp_id, specsym->addr, dumpspec->data,
+ specsym->size);
+   if (bytes_read != specsym->size) {
+   vfree(dumpspec);
+   nfp_warn(cpp, "Debug dump specification read failed.\n");
+   return NULL;
+   }
+
+   return dumpspec;
 }
 
 s64 nfp_net_dump_calculate_size(struct nfp_pf *pf, struct nfp_dumpspec *spec,
-- 
2.11.0



[PATCH net-next 01/10] nfp: debug dump ethtool ops

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- Skeleton code to perform a binary debug dump via ethtoolops
  "set_dump", "get_dump_flags" and "get_dump_data", i.e. the ethtool
  -W/w mechanism.
- Skeleton functions for debugdump operations provided.
- An integer "dump level" can be specified, this is stored between
  ethtool invocations. Dump level 0 is still the "arm.diag" resource for
  backward compatibility. Other dump levels each define a set of state
  information to include in the dump, driven by a spec from FW.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/Makefile|  1 +
 drivers/net/ethernet/netronome/nfp/nfp_main.c  |  6 +++
 drivers/net/ethernet/netronome/nfp/nfp_main.h  | 29 
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 54 +
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 55 ++
 5 files changed, 137 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c

diff --git a/drivers/net/ethernet/netronome/nfp/Makefile 
b/drivers/net/ethernet/netronome/nfp/Makefile
index 24c4408b5734..6e5ef984398b 100644
--- a/drivers/net/ethernet/netronome/nfp/Makefile
+++ b/drivers/net/ethernet/netronome/nfp/Makefile
@@ -22,6 +22,7 @@ nfp-objs := \
nfp_hwmon.o \
nfp_main.o \
nfp_net_common.o \
+   nfp_net_debugdump.o \
nfp_net_ethtool.o \
nfp_net_main.o \
nfp_net_repr.o \
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c 
b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 35eaccbece36..0953fa8f3109 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -45,6 +45,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "nfpcore/nfp.h"
@@ -509,6 +510,9 @@ static int nfp_pci_probe(struct pci_dev *pdev,
pf->mip = nfp_mip_open(pf->cpp);
pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip);
 
+   pf->dump_flag = NFP_DUMP_NSP_DIAG;
+   pf->dumpspec = nfp_net_dump_load_dumpspec(pf->cpp, pf->rtbl);
+
err = nfp_pcie_sriov_read_nfd_limit(pf);
if (err)
goto err_fw_unload;
@@ -544,6 +548,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
nfp_fw_unload(pf);
kfree(pf->eth_tbl);
kfree(pf->nspi);
+   vfree(pf->dumpspec);
 err_devlink_unreg:
devlink_unregister(devlink);
 err_hwinfo_free:
@@ -579,6 +584,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
 
devlink_unregister(devlink);
 
+   vfree(pf->dumpspec);
kfree(pf->rtbl);
nfp_mip_close(pf->mip);
if (pf->fw_loaded)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h 
b/drivers/net/ethernet/netronome/nfp/nfp_main.h
index be0ee59f2eb9..add46e28212b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h
@@ -39,6 +39,7 @@
 #ifndef NFP_MAIN_H
 #define NFP_MAIN_H
 
+#include 
 #include 
 #include 
 #include 
@@ -62,6 +63,17 @@ struct nfp_port;
 struct nfp_rtsym_table;
 
 /**
+ * struct nfp_dumpspec - NFP FW dump specification structure
+ * @size:  Size of the data
+ * @data:  Sequence of TLVs, each being an instruction to dump some data
+ * from FW
+ */
+struct nfp_dumpspec {
+   u32 size;
+   u8 data[0];
+};
+
+/**
  * struct nfp_pf - NFP PF-specific device structure
  * @pdev:  Backpointer to PCI device
  * @cpp:   Pointer to the CPP handle
@@ -83,6 +95,9 @@ struct nfp_rtsym_table;
  * @mip:   MIP handle
  * @rtbl:  RTsym table
  * @hwinfo:HWInfo table
+ * @dumpspec:  Debug dump specification
+ * @dump_flag: Store dump flag between set_dump and get_dump_flag
+ * @dump_len:  Store dump length between set_dump and get_dump_flag
  * @eth_tbl:   NSP ETH table
  * @nspi:  NSP identification info
  * @hwmon_dev: pointer to hwmon device
@@ -124,6 +139,9 @@ struct nfp_pf {
const struct nfp_mip *mip;
struct nfp_rtsym_table *rtbl;
struct nfp_hwinfo *hwinfo;
+   struct nfp_dumpspec *dumpspec;
+   u32 dump_flag;
+   u32 dump_len;
struct nfp_eth_table *eth_tbl;
struct nfp_nsp_identify *nspi;
 
@@ -157,4 +175,15 @@ void nfp_net_get_mac_addr(struct nfp_pf *pf, struct 
nfp_port *port);
 
 bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
 
+enum nfp_dump_diag {
+   NFP_DUMP_NSP_DIAG = 0,
+};
+
+struct nfp_dumpspec *
+nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *r

[PATCH net-next 00/10] nfp: enhanced debug dump via ethtool

2017-12-04 Thread Simon Horman
Add debug dump implementation to the NFP driver. This makes use of
existing ethtool infrastructure.  ethtool -W is used to select the dump
level and ethtool -w is used to dump NFP state.

The existing behaviour of dump level 0, dumping the arm.diag resource, is
preserved. Dump levels greater than 0 are implemented by this patchset and
optionally supported by firmware providing a _abi_dump_spec rtsym. This
rtsym provides a specification, in TLV format, of the information to be
dumped from the NFP at each supported dump level.

Dumps are also structured using a TLVs. They consist a prolog and the data
described int he corresponding dump.

Carl Heymann (10):
  nfp: debug dump ethtool ops
  nfp: load debug dump spec
  nfp: dump prolog
  nfp: dumpspec TLV traversal
  nfp: dump rtsyms
  nfp: dump all hwinfo
  nfp: dump single hwinfo field by key
  nfp: dump firmware name
  nfp: dump CPP, XPB and direct ME CSRs
  nfp: dump indirect ME CSRs

 drivers/net/ethernet/netronome/nfp/Makefile|   1 +
 drivers/net/ethernet/netronome/nfp/nfp_asm.h   |  10 +
 drivers/net/ethernet/netronome/nfp/nfp_main.c  |   6 +
 drivers/net/ethernet/netronome/nfp/nfp_main.h  |  29 +
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 787 +
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   |  55 +-
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h   |   2 +
 .../ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c|  10 +
 8 files changed, 892 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c

-- 
2.11.0



[PATCH net-next 05/10] nfp: dump rtsyms

2017-12-04 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

- Support rtsym TLVs.
- If specified rtsym is not found, dump the spec TLV as -ENOENT error.

Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 124 +
 1 file changed, 124 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index d52e01ca6621..746e114a8da8 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -43,6 +43,7 @@
 #define ALIGN8(x)  ALIGN(x, 8)
 
 enum nfp_dumpspec_type {
+   NFP_DUMPSPEC_TYPE_RTSYM = 4,
NFP_DUMPSPEC_TYPE_PROLOG = 1,
NFP_DUMPSPEC_TYPE_ERROR = 10001,
 };
@@ -59,6 +60,34 @@ struct nfp_dump_tl {
char data[0];
 };
 
+/* NFP CPP parameters */
+struct nfp_dumpspec_cpp_isl_id {
+   u8 target;
+   u8 action;
+   u8 token;
+   u8 island;
+};
+
+struct nfp_dump_common_cpp {
+   struct nfp_dumpspec_cpp_isl_id cpp_id;
+   __be32 offset;  /* address to start dump */
+   __be32 dump_length; /* total bytes to dump, aligned to reg size */
+};
+
+struct nfp_dumpspec_rtsym {
+   struct nfp_dump_tl tl;
+   char rtsym[0];
+};
+
+struct nfp_dump_rtsym {
+   struct nfp_dump_tl tl;
+   struct nfp_dump_common_cpp cpp;
+   __be32 error;   /* error code encountered while reading */
+   u8 padded_name_length;  /* pad so data starts at 8 byte boundary */
+   char rtsym[0];
+   /* after padded_name_length, there is dump_length data */
+};
+
 struct nfp_dump_prolog {
struct nfp_dump_tl tl;
__be32 dump_level;
@@ -122,6 +151,12 @@ nfp_traverse_tlvs(struct nfp_pf *pf, void *data, u32 
data_length, void *param,
return 0;
 }
 
+static u32 nfp_get_numeric_cpp_id(struct nfp_dumpspec_cpp_isl_id *cpp_id)
+{
+   return NFP_CPP_ISLAND_ID(cpp_id->target, cpp_id->action, cpp_id->token,
+cpp_id->island);
+}
+
 struct nfp_dumpspec *
 nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
 {
@@ -162,11 +197,36 @@ static int nfp_dump_error_tlv_size(struct nfp_dump_tl 
*spec)
 }
 
 static int
+nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
+{
+   struct nfp_rtsym_table *rtbl = pf->rtbl;
+   struct nfp_dumpspec_rtsym *spec_rtsym;
+   const struct nfp_rtsym *sym;
+   u32 tl_len, key_len;
+
+   spec_rtsym = (struct nfp_dumpspec_rtsym *)spec;
+   tl_len = be32_to_cpu(spec->length);
+   key_len = strnlen(spec_rtsym->rtsym, tl_len);
+   if (key_len == tl_len)
+   return nfp_dump_error_tlv_size(spec);
+
+   sym = nfp_rtsym_lookup(rtbl, spec_rtsym->rtsym);
+   if (!sym)
+   return nfp_dump_error_tlv_size(spec);
+
+   return ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1) +
+  ALIGN8(sym->size);
+}
+
+static int
 nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, void *param)
 {
u32 *size = param;
 
switch (be32_to_cpu(tl->type)) {
+   case NFP_DUMPSPEC_TYPE_RTSYM:
+   *size += nfp_calc_rtsym_dump_sz(pf, tl);
+   break;
default:
*size += nfp_dump_error_tlv_size(tl);
break;
@@ -247,12 +307,76 @@ nfp_dump_error_tlv(struct nfp_dump_tl *spec, int error,
 }
 
 static int
+nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
+ struct nfp_dump_state *dump)
+{
+   struct nfp_dump_rtsym *dump_header = dump->p;
+   struct nfp_dumpspec_cpp_isl_id cpp_params;
+   struct nfp_rtsym_table *rtbl = pf->rtbl;
+   const struct nfp_rtsym *sym;
+   u32 header_size, total_size;
+   u32 tl_len, key_len;
+   int bytes_read;
+   u32 cpp_id;
+   void *dest;
+   int err;
+
+   tl_len = be32_to_cpu(spec->tl.length);
+   key_len = strnlen(spec->rtsym, tl_len);
+   if (key_len == tl_len)
+   return nfp_dump_error_tlv(>tl, -EINVAL, dump);
+
+   sym = nfp_rtsym_lookup(rtbl, spec->rtsym);
+   if (!sym)
+   return nfp_dump_error_tlv(>tl, -ENOENT, dump);
+
+   header_size =
+   ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1);
+   total_size = header_size + ALIGN8(sym->size);
+   dest = dump->p + header_size;
+
+   err = nfp_add_tlv(be32_to_cpu(spec->tl.type), total_size, dump);
+   if (err)
+   return err;
+
+   dump_header->padded_name_length =
+   header_size - offsetof(struct nfp_dump_rtsym, rtsym);
+   memcpy(dump_header->rtsym, spec->rtsym, key_len +

[PATCH net-next 3/4] nfp: flower: compile Geneve match fields

2017-12-19 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Compile Geneve match fields for offloading to the NFP. The addition of
Geneve overflows the 8 bit key_layer field, so apply extended metadata to
the match cmsg allowing up to 32 more key_layer fields.

Rather than adding new Geneve blocks, move the vxlan code to generic ipv4
udp tunnel structs and use these for both vxlan and Geneve.

Matches are only supported when specifically mentioning well known port
6081. Geneve tunnel options are not yet included in the match.

Only offload Geneve if the fw supports it - include check for this.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   | 32 -
 drivers/net/ethernet/netronome/nfp/flower/main.h   |  9 +++-
 drivers/net/ethernet/netronome/nfp/flower/match.c  | 55 +-
 .../net/ethernet/netronome/nfp/flower/offload.c| 37 +++
 4 files changed, 91 insertions(+), 42 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h 
b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index d6b63c8f14da..2e71c32690e9 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -41,7 +41,7 @@
 #include "../nfp_app.h"
 #include "../nfpcore/nfp_cpp.h"
 
-#define NFP_FLOWER_LAYER_META  BIT(0)
+#define NFP_FLOWER_LAYER_EXT_META  BIT(0)
 #define NFP_FLOWER_LAYER_PORT  BIT(1)
 #define NFP_FLOWER_LAYER_MAC   BIT(2)
 #define NFP_FLOWER_LAYER_TPBIT(3)
@@ -50,6 +50,8 @@
 #define NFP_FLOWER_LAYER_CTBIT(6)
 #define NFP_FLOWER_LAYER_VXLAN BIT(7)
 
+#define NFP_FLOWER_LAYER2_GENEVE   BIT(5)
+
 #define NFP_FLOWER_MASK_VLAN_PRIO  GENMASK(15, 13)
 #define NFP_FLOWER_MASK_VLAN_CFI   BIT(12)
 #define NFP_FLOWER_MASK_VLAN_VID   GENMASK(11, 0)
@@ -105,6 +107,7 @@
 enum nfp_flower_tun_type {
NFP_FL_TUNNEL_NONE =0,
NFP_FL_TUNNEL_VXLAN =   2,
+   NFP_FL_TUNNEL_GENEVE =  4,
 };
 
 struct nfp_fl_act_head {
@@ -198,6 +201,18 @@ struct nfp_flower_meta_tci {
__be16 tci;
 };
 
+/* Extended metadata for additional key_layers (1W/4B)
+ * 
+ *3   2   1
+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  nfp_flow_key_layer2  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_flower_ext_meta {
+   __be32 nfp_flow_key_layer2;
+};
+
 /* Port details (1W/4B)
  * 
  *3   2   1
@@ -296,7 +311,7 @@ struct nfp_flower_ipv6 {
struct in6_addr ipv6_dst;
 };
 
-/* Flow Frame VXLAN --> Tunnel details (4W/16B)
+/* Flow Frame IPv4 UDP TUNNEL --> Tunnel details (4W/16B)
  * -
  *3   2   1
  *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
@@ -305,22 +320,17 @@ struct nfp_flower_ipv6 {
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * | ipv4_addr_dst |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |   tun_flags   |   tos |   ttl |
+ * |Reserved   |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |   gpe_flags   |Reserved   | Next Protocol |
+ * |Reserved   |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * | VNI   |   Reserved|
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  */
-struct nfp_flower_vxlan {
+struct nfp_flower_ipv4_udp_tun {
__be32 ip_src;
__be32 ip_dst;
-   __be16 tun_flags;
-   u8 tos;
-   u8 ttl;
-   u8 gpe_flags;
-   u8 reserved[2];
-   u8 nxt_proto;
+   __be32 reserved[2];
__be32 tun_id;
 };
 
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h 
b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 87be25ae8d19..6e3937a0b708 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -34,6 +34,8 @@
 #ifndef __NFP_FLOWER_H__
 #define __NFP_FLOWER_H__ 1
 
+#include "cmsg.h"
+
 #include 
 #include 
 #include 
@@ -58,6 +60,10 @@ struct nfp_app;
 #define NFP_FL_MASK_ID_LOCATION1
 
 #define NFP_FL_VXLAN_PORT   

[PATCH net-next 4/4] nfp: flower: compile Geneve encap actions

2017-12-19 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Generate rules for the NFP to encapsulate packets in Geneve tunnels. Move
the vxlan action code to generic udp tunnel actions and use core code for
both vxlan and Geneve.

Only support outputting to well known port 6081. Setting tunnel options
is not supported yet.

Only attempt to offload if the fw supports Geneve.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/action.c | 75 +-
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   | 11 ++--
 2 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c 
b/drivers/net/ethernet/netronome/nfp/flower/action.c
index ca74c517f626..b3567a596fc1 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -81,6 +81,9 @@ static bool nfp_fl_netdev_is_tunnel_type(struct net_device 
*out_dev,
if (!strcmp(out_dev->rtnl_link_ops->kind, "vxlan"))
return tun_type == NFP_FL_TUNNEL_VXLAN;
 
+   if (!strcmp(out_dev->rtnl_link_ops->kind, "geneve"))
+   return tun_type == NFP_FL_TUNNEL_GENEVE;
+
return false;
 }
 
@@ -136,11 +139,23 @@ nfp_fl_output(struct nfp_fl_output *output, const struct 
tc_action *action,
return 0;
 }
 
-static bool nfp_fl_supported_tun_port(const struct tc_action *action)
+static enum nfp_flower_tun_type
+nfp_fl_get_tun_from_act_l4_port(struct nfp_app *app,
+   const struct tc_action *action)
 {
struct ip_tunnel_info *tun = tcf_tunnel_info(action);
-
-   return tun->key.tp_dst == htons(NFP_FL_VXLAN_PORT);
+   struct nfp_flower_priv *priv = app->priv;
+
+   switch (tun->key.tp_dst) {
+   case htons(NFP_FL_VXLAN_PORT):
+   return NFP_FL_TUNNEL_VXLAN;
+   case htons(NFP_FL_GENEVE_PORT):
+   if (priv->flower_ext_feats & NFP_FL_FEATS_GENEVE)
+   return NFP_FL_TUNNEL_GENEVE;
+   /* FALLTHROUGH */
+   default:
+   return NFP_FL_TUNNEL_NONE;
+   }
 }
 
 static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char *act_data, int act_len)
@@ -165,38 +180,33 @@ static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char 
*act_data, int act_len)
 }
 
 static int
-nfp_fl_set_vxlan(struct nfp_fl_set_vxlan *set_vxlan,
-const struct tc_action *action,
-struct nfp_fl_pre_tunnel *pre_tun)
+nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
+   const struct tc_action *action,
+   struct nfp_fl_pre_tunnel *pre_tun,
+   enum nfp_flower_tun_type tun_type)
 {
-   struct ip_tunnel_info *vxlan = tcf_tunnel_info(action);
-   size_t act_size = sizeof(struct nfp_fl_set_vxlan);
-   u32 tmp_set_vxlan_type_index = 0;
+   size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun);
+   struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action);
+   u32 tmp_set_ip_tun_type_index = 0;
/* Currently support one pre-tunnel so index is always 0. */
int pretun_idx = 0;
 
-   if (vxlan->options_len) {
-   /* Do not support options e.g. vxlan gpe. */
+   if (ip_tun->options_len)
return -EOPNOTSUPP;
-   }
 
-   set_vxlan->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL;
-   set_vxlan->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+   set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL;
+   set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ;
 
/* Set tunnel type and pre-tunnel index. */
-   tmp_set_vxlan_type_index |=
-   FIELD_PREP(NFP_FL_IPV4_TUNNEL_TYPE, NFP_FL_TUNNEL_VXLAN) |
+   tmp_set_ip_tun_type_index |=
+   FIELD_PREP(NFP_FL_IPV4_TUNNEL_TYPE, tun_type) |
FIELD_PREP(NFP_FL_IPV4_PRE_TUN_INDEX, pretun_idx);
 
-   set_vxlan->tun_type_index = cpu_to_be32(tmp_set_vxlan_type_index);
-
-   set_vxlan->tun_id = vxlan->key.tun_id;
-   set_vxlan->tun_flags = vxlan->key.tun_flags;
-   set_vxlan->ipv4_ttl = vxlan->key.ttl;
-   set_vxlan->ipv4_tos = vxlan->key.tos;
+   set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index);
+   set_tun->tun_id = ip_tun->key.tun_id;
 
/* Complete pre_tunnel action. */
-   pre_tun->ipv4_dst = vxlan->key.u.ipv4.dst;
+   pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst;
 
return 0;
 }
@@ -433,8 +443,8 @@ nfp_flower_loop_action(const struct tc_action *a,
   struct net_device *netdev,
   enum nfp_flower_tun_type *tun_type, int *tun_out_cnt)

[PATCH net-next 0/4] nfp: flower: add Geneve tunnel support

2017-12-19 Thread Simon Horman
John Hurley says:

This patchset adds support for offloading the encap and decap of Geneve
tunnels to the NFP. In both cases, specifying well known port 6081 is a
requirement for rule offload.

Geneve firmware support has been recently added, so the patchset includes
the reading of a fw symbol that defines a bitmap of newly supported
features. Geneve will only be offloaded if the fw supports it. The new
symbol is added in fw r5646.

Geneve option fields are not supported as either a match or an action due
there current exclussion from TC flower. Because Geneve (as both a match
and action) behaves the same as other udp tunnels such as VXLAN, generic
functions are created that handle both Geneve and VXLAN. It is anticapated
that these functions will be modified to support options in future
patches.

The removal of an unused variable 'tun_dst_mask' is included as a separate
patch here. This does not affect functionality.

Also included are modifications to the test framework to check that the
new encap and decap features are functioning correctly.

John Hurley (4):
  nfp: flower: remove unused tun_mask variable
  nfp: flower: read extra feature support from fw
  nfp: flower: compile Geneve match fields
  nfp: flower: compile Geneve encap actions

 drivers/net/ethernet/netronome/nfp/flower/action.c | 75 +-
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   | 43 +++--
 drivers/net/ethernet/netronome/nfp/flower/main.c   | 10 ++-
 drivers/net/ethernet/netronome/nfp/flower/main.h   | 11 +++-
 drivers/net/ethernet/netronome/nfp/flower/match.c  | 58 ++---
 .../net/ethernet/netronome/nfp/flower/offload.c| 37 ---
 6 files changed, 152 insertions(+), 82 deletions(-)

-- 
2.11.0



[PATCH net-next 2/4] nfp: flower: read extra feature support from fw

2017-12-19 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

Extract the _abi_flower_extra_features symbol from the fw which gives a 64
bit bitmap of new features (on top of the flower base support) that the fw
can offload. Store this bitmap in the priv data associated with each app.
If the symbol does not exist, set the bitmap to 0.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/main.c | 10 +-
 drivers/net/ethernet/netronome/nfp/flower/main.h |  2 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c 
b/drivers/net/ethernet/netronome/nfp/flower/main.c
index 8fcc90c0d2d3..63160e9754d4 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -381,7 +381,7 @@ static int nfp_flower_init(struct nfp_app *app)
 {
const struct nfp_pf *pf = app->pf;
struct nfp_flower_priv *app_priv;
-   u64 version;
+   u64 version, features;
int err;
 
if (!pf->eth_tbl) {
@@ -424,6 +424,14 @@ static int nfp_flower_init(struct nfp_app *app)
if (err)
goto err_free_app_priv;
 
+   /* Extract the extra features supported by the firmware. */
+   features = nfp_rtsym_read_le(app->pf->rtbl,
+"_abi_flower_extra_features", );
+   if (err)
+   app_priv->flower_ext_feats = 0;
+   else
+   app_priv->flower_ext_feats = features;
+
return 0;
 
 err_free_app_priv:
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h 
b/drivers/net/ethernet/netronome/nfp/flower/main.h
index e6b26c5ae6e0..87be25ae8d19 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -77,6 +77,7 @@ struct nfp_fl_stats_id {
  * @nn:Pointer to vNIC
  * @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
  * @stats_ids: List of free stats ids
  * @mask_ids:  List of free mask ids
  * @mask_table:Hash table used to store masks
@@ -101,6 +102,7 @@ struct nfp_flower_priv {
struct nfp_net *nn;
u32 mask_id_seed;
u64 flower_version;
+   u64 flower_ext_feats;
struct nfp_fl_stats_id stats_ids;
struct nfp_fl_mask_id mask_ids;
DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
-- 
2.11.0



[PATCH net-next 1/4] nfp: flower: remove unused tun_mask variable

2017-12-19 Thread Simon Horman
From: John Hurley <john.hur...@netronome.com>

The tunnel dest IP is required for separate offload to the NFP. It is
already verified that a dest IP must be present and must be an exact
match in the flower rule. Therefore, we can just extract the IP from the
generated offload rule and remove the unused mask variable. The function
is then no longer required to return the IP separately.

Because tun_dst is localised to tunnel matches, move the declaration to
the tunnel if branch.

Signed-off-by: John Hurley <john.hur...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/match.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c 
b/drivers/net/ethernet/netronome/nfp/flower/match.c
index 1f2b879e12d4..e3b10b34035b 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -218,7 +218,7 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
 static void
 nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
 struct tc_cls_flower_offload *flow,
-bool mask_version, __be32 *tun_dst)
+bool mask_version)
 {
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
struct flow_dissector_key_ipv4_addrs *vxlan_ips;
@@ -246,7 +246,6 @@ nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
 target);
frame->ip_src = vxlan_ips->src;
frame->ip_dst = vxlan_ips->dst;
-   *tun_dst = vxlan_ips->dst;
}
 }
 
@@ -256,7 +255,6 @@ int nfp_flower_compile_flow_match(struct 
tc_cls_flower_offload *flow,
  struct nfp_fl_payload *nfp_flow)
 {
enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
-   __be32 tun_dst, tun_dst_mask = 0;
struct nfp_repr *netdev_repr;
int err;
u8 *ext;
@@ -342,12 +340,15 @@ int nfp_flower_compile_flow_match(struct 
tc_cls_flower_offload *flow,
}
 
if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) {
+   __be32 tun_dst;
+
/* Populate Exact VXLAN Data. */
nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)ext,
-flow, false, _dst);
+flow, false);
/* Populate Mask VXLAN Data. */
nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)msk,
-flow, true, _dst_mask);
+flow, true);
+   tun_dst = ((struct nfp_flower_vxlan *)ext)->ip_dst;
ext += sizeof(struct nfp_flower_vxlan);
msk += sizeof(struct nfp_flower_vxlan);
 
-- 
2.11.0



Re: [PATCH net-next 0/2] nfp: fix rtsym and XDP register handling in debug dump

2017-12-15 Thread Simon Horman
On Thu, Dec 14, 2017 at 10:50:24AM +0100, Simon Horman wrote:
> Hi,
> 
> this series resolves two problems in the recently added debug dump facility.
> 
> * Correctly handle reading absolute rtysms
> * Correctly handle special-case PB register reads
> 
> These fixes are for code only present in net-next.

Hi Dave,

It seems that I made a thinko in the title of the cover letter.  s/XDP/XPB/
These changes do not relate to XDP.

> Carl Heymann (2):
>   nfp: fix absolute rtsym handling in debug dump
>   nfp: fix XPB register reads in debug dump
> 
>  .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 57 
> +++---
>  1 file changed, 39 insertions(+), 18 deletions(-)
> 
> -- 
> 2.11.0
> 


[PATCH net-next 2/2] nfp: fix XPB register reads in debug dump

2017-12-14 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

For XPB registers reads, some island IDs require special handling (e.g.
ARM island), which is already taken care of in nfp_xpb_readl(), so use
that instead of a straight CPP read.

Without this fix all "xpbm:ArmIsldXpbmMap.*" registers are reported as
0x. It has also been observed to cause a system reboot.

With this fix correct values are reported, none of which are 0x.

The values may be read using ethtool debug level 2.
 # ethtool -W  2
 # ethtool -w  data dump.dat

Fixes: 0e6c4955e149 ("nfp: dump CPP, XPB and direct ME CSRs")
Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index 315bd22819ff..173646e17e94 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -38,6 +38,7 @@
 #include "nfp_main.h"
 #include "nfpcore/nfp.h"
 #include "nfpcore/nfp_nffw.h"
+#include "nfpcore/nfp6000/nfp6000.h"
 
 #define NFP_DUMP_SPEC_RTSYM"_abi_dump_spec"
 
@@ -478,6 +479,12 @@ static int nfp_dump_hwinfo_field(struct nfp_pf *pf, struct 
nfp_dump_tl *spec,
return 0;
 }
 
+static bool is_xpb_read(struct nfp_dumpspec_cpp_isl_id *cpp_id)
+{
+   return cpp_id->target == NFP_CPP_TARGET_ISLAND_XPB &&
+  cpp_id->action == 0 && cpp_id->token == 0;
+}
+
 static int
 nfp_dump_csr_range(struct nfp_pf *pf, struct nfp_dumpspec_csr *spec_csr,
   struct nfp_dump_state *dump)
@@ -511,8 +518,12 @@ nfp_dump_csr_range(struct nfp_pf *pf, struct 
nfp_dumpspec_csr *spec_csr,
max_rd_addr = cpp_rd_addr + be32_to_cpu(spec_csr->cpp.dump_length);
 
while (cpp_rd_addr < max_rd_addr) {
-   bytes_read = nfp_cpp_read(pf->cpp, cpp_id, cpp_rd_addr, dest,
- reg_sz);
+   if (is_xpb_read(_csr->cpp.cpp_id))
+   bytes_read = nfp_xpb_readl(pf->cpp, cpp_rd_addr,
+  (u32 *)dest);
+   else
+   bytes_read = nfp_cpp_read(pf->cpp, cpp_id, cpp_rd_addr,
+ dest, reg_sz);
if (bytes_read != reg_sz) {
if (bytes_read >= 0)
bytes_read = -EIO;
-- 
2.11.0



[PATCH net-next 1/2] nfp: fix absolute rtsym handling in debug dump

2017-12-14 Thread Simon Horman
From: Carl Heymann <carl.heym...@netronome.com>

In TLV-based ethtool debug dumps, don't do a CPP read for absolute
rtsyms, use the addr field in the symbol table directly as the value.

Without this fix rtsym gro_release_ring_0 is 4 bytes of zeros.
With this fix the correct value, 0x004a 0x is reported.

The values may be read using ethtool debug level 2.
 # ethtool -W  2
 # ethtool -w  data dump.dat

Fixes: e1e798e3fd93 ("nfp: dump rtsyms")
Signed-off-by: Carl Heymann <carl.heym...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 42 +-
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
index cbff0adad235..315bd22819ff 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
@@ -265,6 +265,7 @@ nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct 
nfp_dump_tl *spec)
struct nfp_dumpspec_rtsym *spec_rtsym;
const struct nfp_rtsym *sym;
u32 tl_len, key_len;
+   u32 size;
 
spec_rtsym = (struct nfp_dumpspec_rtsym *)spec;
tl_len = be32_to_cpu(spec->length);
@@ -276,8 +277,13 @@ nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct 
nfp_dump_tl *spec)
if (!sym)
return nfp_dump_error_tlv_size(spec);
 
+   if (sym->type == NFP_RTSYM_TYPE_ABS)
+   size = sizeof(sym->addr);
+   else
+   size = sym->size;
+
return ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1) +
-  ALIGN8(sym->size);
+  ALIGN8(size);
 }
 
 static int
@@ -654,21 +660,25 @@ nfp_dump_single_rtsym(struct nfp_pf *pf, struct 
nfp_dumpspec_rtsym *spec,
header_size - offsetof(struct nfp_dump_rtsym, rtsym);
memcpy(dump_header->rtsym, spec->rtsym, key_len + 1);
 
-   cpp_params.target = sym->target;
-   cpp_params.action = NFP_CPP_ACTION_RW;
-   cpp_params.token  = 0;
-   cpp_params.island = sym->domain;
-   cpp_id = nfp_get_numeric_cpp_id(_params);
-
-   dump_header->cpp.cpp_id = cpp_params;
-   dump_header->cpp.offset = cpu_to_be32(sym->addr);
-   dump_header->cpp.dump_length = cpu_to_be32(sym->size);
-
-   bytes_read = nfp_cpp_read(pf->cpp, cpp_id, sym->addr, dest, sym->size);
-   if (bytes_read != sym->size) {
-   if (bytes_read >= 0)
-   bytes_read = -EIO;
-   dump_header->error = cpu_to_be32(bytes_read);
+   if (sym->type == NFP_RTSYM_TYPE_ABS) {
+   dump_header->cpp.dump_length = cpu_to_be32(sizeof(sym->addr));
+   *(u64 *)dest = sym->addr;
+   } else {
+   cpp_params.target = sym->target;
+   cpp_params.action = NFP_CPP_ACTION_RW;
+   cpp_params.token  = 0;
+   cpp_params.island = sym->domain;
+   cpp_id = nfp_get_numeric_cpp_id(_params);
+   dump_header->cpp.cpp_id = cpp_params;
+   dump_header->cpp.offset = cpu_to_be32(sym->addr);
+   dump_header->cpp.dump_length = cpu_to_be32(sym->size);
+   bytes_read = nfp_cpp_read(pf->cpp, cpp_id, sym->addr, dest,
+ sym->size);
+   if (bytes_read != sym->size) {
+   if (bytes_read >= 0)
+   bytes_read = -EIO;
+   dump_header->error = cpu_to_be32(bytes_read);
+   }
}
 
return 0;
-- 
2.11.0



[PATCH net-next 0/2] nfp: fix rtsym and XDP register handling in debug dump

2017-12-14 Thread Simon Horman
Hi,

this series resolves two problems in the recently added debug dump facility.

* Correctly handle reading absolute rtysms
* Correctly handle special-case PB register reads

These fixes are for code only present in net-next.

Carl Heymann (2):
  nfp: fix absolute rtsym handling in debug dump
  nfp: fix XPB register reads in debug dump

 .../net/ethernet/netronome/nfp/nfp_net_debugdump.c | 57 +++---
 1 file changed, 39 insertions(+), 18 deletions(-)

-- 
2.11.0



Re: [PATCH 1/8] dt-bindings: can: rcar_can: document r8a774[35] can support

2017-11-20 Thread Simon Horman
On Tue, Nov 07, 2017 at 03:10:42PM +, Fabrizio Castro wrote:
> Document "renesas,can-r8a7743" and "renesas,can-r8a7745" compatible
> strings. Since the fallback compatible string ("renesas,rcar-gen2-can")
> activates the right code in the driver, no driver change is needed.
> 
> Signed-off-by: Fabrizio Castro <fabrizio.cas...@bp.renesas.com>
> Reviewed-by: Biju Das <biju@bp.renesas.com>

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>



Re: [PATCH 0/8] Add CAN support to iwg2[02]d

2017-11-20 Thread Simon Horman
On Tue, Nov 07, 2017 at 03:10:41PM +, Fabrizio Castro wrote:
> Hello,
> 
> this series delivers all of the changes necessary to add CAN bus
> support to the:
> * iW-RainboW-G22D SODIMM, and
> * iW-RainboW-G20M-Qseven-RZG1M
> development platforms, including documentation, pinctrl driver, SoC
> specific device trees, and board specific device trees.
> 
> This work has been based and tested on top of:
> renesas-devel-20171106-v4.14-rc8
> 
> Best regards,
> 
> Fabrizio Castro (8):
>   dt-bindings: can: rcar_can: document r8a774[35] can support
>   pinctrl: sh-pfc: r8a7745: Add CAN[01] support
>   ARM: dts: r8a7745: Add CAN[01] SoC support
>   ARM: dts: iwg22d-sodimm: Add can0 support to carrier board
>   ARM: dts: iwg22d-sodimm-dbhd-ca: Add can1 support to HDMI DB
>   ARM: dts: r8a7743: Add CAN[01] SoC support
>   ARM: dts: iwg20d-q7-common: Add can0 support to carrier board
>   ARM: dts: iwg20d-q7-dbcm-ca: Add can1 support to camera DB

Thanks, I have applied the "ARM: dts" patches for inclusion in v4.16.


[net-next 7/7] nfp: implement ethtool FEC mode settings

2017-11-04 Thread Simon Horman
From: Dirk van der Merwe <dirk.vanderme...@netronome.com>

Add support in the driver ethtool ops to modify the NFP FEC modes.

The FEC modes can be set for vNIC associated with physical ports or
for MAC representor netdevs.

Signed-off-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 117 -
 1 file changed, 116 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index d0028894667c..60c8d733a37d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -244,6 +244,30 @@ nfp_app_get_drvinfo(struct net_device *netdev, struct 
ethtool_drvinfo *drvinfo)
nfp_get_drvinfo(app, app->pdev, "*", drvinfo);
 }
 
+static void
+nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port,
+ struct ethtool_link_ksettings *c)
+{
+   unsigned int modes;
+
+   ethtool_link_ksettings_add_link_mode(c, supported, FEC_NONE);
+   if (!nfp_eth_can_support_fec(eth_port)) {
+   ethtool_link_ksettings_add_link_mode(c, advertising, FEC_NONE);
+   return;
+   }
+
+   modes = nfp_eth_supported_fec_modes(eth_port);
+   if (modes & NFP_FEC_BASER) {
+   ethtool_link_ksettings_add_link_mode(c, supported, FEC_BASER);
+   ethtool_link_ksettings_add_link_mode(c, advertising, FEC_BASER);
+   }
+
+   if (modes & NFP_FEC_REED_SOLOMON) {
+   ethtool_link_ksettings_add_link_mode(c, supported, FEC_RS);
+   ethtool_link_ksettings_add_link_mode(c, advertising, FEC_RS);
+   }
+}
+
 /**
  * nfp_net_get_link_ksettings - Get Link Speed settings
  * @netdev:network interface device structure
@@ -278,9 +302,11 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
 
port = nfp_port_from_netdev(netdev);
eth_port = nfp_port_get_eth_port(port);
-   if (eth_port)
+   if (eth_port) {
cmd->base.autoneg = eth_port->aneg != NFP_ANEG_DISABLED ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
+   nfp_net_set_fec_link_mode(eth_port, cmd);
+   }
 
if (!netif_carrier_ok(netdev))
return 0;
@@ -686,6 +712,91 @@ static int nfp_port_get_sset_count(struct net_device 
*netdev, int sset)
}
 }
 
+static int nfp_port_fec_ethtool_to_nsp(u32 fec)
+{
+   switch (fec) {
+   case ETHTOOL_FEC_AUTO:
+   return NFP_FEC_AUTO_BIT;
+   case ETHTOOL_FEC_OFF:
+   return NFP_FEC_DISABLED_BIT;
+   case ETHTOOL_FEC_RS:
+   return NFP_FEC_REED_SOLOMON_BIT;
+   case ETHTOOL_FEC_BASER:
+   return NFP_FEC_BASER_BIT;
+   default:
+   /* NSP only supports a single mode at a time */
+   return -EOPNOTSUPP;
+   }
+}
+
+static u32 nfp_port_fec_nsp_to_ethtool(u32 fec)
+{
+   u32 result = 0;
+
+   if (fec & NFP_FEC_AUTO)
+   result |= ETHTOOL_FEC_AUTO;
+   if (fec & NFP_FEC_BASER)
+   result |= ETHTOOL_FEC_BASER;
+   if (fec & NFP_FEC_REED_SOLOMON)
+   result |= ETHTOOL_FEC_RS;
+   if (fec & NFP_FEC_DISABLED)
+   result |= ETHTOOL_FEC_OFF;
+
+   return result ?: ETHTOOL_FEC_NONE;
+}
+
+static int
+nfp_port_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *param)
+{
+   struct nfp_eth_table_port *eth_port;
+   struct nfp_port *port;
+
+   param->active_fec = ETHTOOL_FEC_NONE_BIT;
+   param->fec = ETHTOOL_FEC_NONE_BIT;
+
+   port = nfp_port_from_netdev(netdev);
+   eth_port = nfp_port_get_eth_port(port);
+   if (!eth_port)
+   return -EOPNOTSUPP;
+
+   if (!nfp_eth_can_support_fec(eth_port))
+   return 0;
+
+   param->fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec_modes_supported);
+   param->active_fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec);
+
+   return 0;
+}
+
+static int
+nfp_port_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *param)
+{
+   struct nfp_eth_table_port *eth_port;
+   struct nfp_port *port;
+   int err, fec;
+
+   port = nfp_port_from_netdev(netdev);
+   eth_port = nfp_port_get_eth_port(port);
+   if (!eth_port)
+   return -EOPNOTSUPP;
+
+   if (!nfp_eth_can_support_fec(eth_port))
+   return -EOPNOTSUPP;
+
+   fec = nfp_port_fec_ethtool_to_nsp(param->fec);
+   if (fec < 0)
+   return fec;
+
+   err = nfp_eth_set_fec(port->app->cpp, eth_port->index, fec);
+   if (!err)
+   /* Only refresh if we did something */
+   nfp_net_refresh

[net-next 4/7] nfp: resync repr state when port table sync

2017-11-04 Thread Simon Horman
From: Dirk van der Merwe <dirk.vanderme...@netronome.com>

If the NSP port table has been refreshed, resync the representor state
with the new port information. At the moment, this only entails looking
for invalid ports and killing off representors associated with them.

The repr instance becomes NULL which is safe since the app accessor
function for reprs returns NULL when it cannot access a repr.

Signed-off-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_main.c |  6 +++
 drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 47 +++
 drivers/net/ethernet/netronome/nfp/nfp_net_repr.h |  1 +
 3 files changed, 54 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 0beb9b21557b..c505014121c4 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -611,6 +611,7 @@ int nfp_net_refresh_port_table_sync(struct nfp_pf *pf)
struct nfp_eth_table *eth_table;
struct nfp_net *nn, *next;
struct nfp_port *port;
+   int err;
 
lockdep_assert_held(>lock);
 
@@ -640,6 +641,11 @@ int nfp_net_refresh_port_table_sync(struct nfp_pf *pf)
 
kfree(eth_table);
 
+   /* Resync repr state. This may cause reprs to be removed. */
+   err = nfp_reprs_resync_phys_ports(pf->app);
+   if (err)
+   return err;
+
/* Shoot off the ports which became invalid */
list_for_each_entry_safe(nn, next, >vnics, vnic_list) {
if (!nn->port || nn->port->type != NFP_PORT_INVALID)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index d540a9dc77b3..1bce8c131bb9 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -390,3 +390,50 @@ struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
 
return reprs;
 }
+
+int nfp_reprs_resync_phys_ports(struct nfp_app *app)
+{
+   struct nfp_reprs *reprs, *old_reprs;
+   struct nfp_repr *repr;
+   int i;
+
+   old_reprs =
+   rcu_dereference_protected(app->reprs[NFP_REPR_TYPE_PHYS_PORT],
+ lockdep_is_held(>pf->lock));
+   if (!old_reprs)
+   return 0;
+
+   reprs = nfp_reprs_alloc(old_reprs->num_reprs);
+   if (!reprs)
+   return -ENOMEM;
+
+   for (i = 0; i < old_reprs->num_reprs; i++) {
+   if (!old_reprs->reprs[i])
+   continue;
+
+   repr = netdev_priv(old_reprs->reprs[i]);
+   if (repr->port->type == NFP_PORT_INVALID)
+   continue;
+
+   reprs->reprs[i] = old_reprs->reprs[i];
+   }
+
+   old_reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
+   synchronize_rcu();
+
+   /* Now we free up removed representors */
+   for (i = 0; i < old_reprs->num_reprs; i++) {
+   if (!old_reprs->reprs[i])
+   continue;
+
+   repr = netdev_priv(old_reprs->reprs[i]);
+   if (repr->port->type != NFP_PORT_INVALID)
+   continue;
+
+   nfp_app_repr_stop(app, repr);
+   nfp_repr_clean(repr);
+   }
+
+   kfree(old_reprs);
+   return 0;
+}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h 
b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h
index 32179cad062a..5d4d897bc9c6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h
@@ -124,5 +124,6 @@ void
 nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
 enum nfp_repr_type type);
 struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs);
+int nfp_reprs_resync_phys_ports(struct nfp_app *app);
 
 #endif /* NFP_NET_REPR_H */
-- 
2.11.0



[net-next 5/7] nfp: add get/set link settings ndos to representors

2017-11-04 Thread Simon Horman
From: Dirk van der Merwe <dirk.vanderme...@netronome.com>

Since it is now safe to modify link settings for representors, we can
attach the get/set link settings ndos to it. The get/set link settings
are nfp_port based operations.

If a port becomes invalid, the representor will be removed in the same
way a vnic would be.

Signed-off-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 0061097c271e..d0028894667c 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -1155,6 +1155,8 @@ const struct ethtool_ops nfp_port_ethtool_ops = {
.set_dump   = nfp_app_set_dump,
.get_dump_flag  = nfp_app_get_dump_flag,
.get_dump_data  = nfp_app_get_dump_data,
+   .get_link_ksettings = nfp_net_get_link_ksettings,
+   .set_link_ksettings = nfp_net_set_link_ksettings,
 };
 
 void nfp_net_set_ethtool_ops(struct net_device *netdev)
-- 
2.11.0



[net-next 0/7] nfp: ethtool and related improvements

2017-11-04 Thread Simon Horman
Dirk van der Merwe says:

This patch series throws a couple of loosely related items into a single
series.

Patch 1: Clang compilation fix reported by
  Matthias Kaehlcke 

Patch 2: Driver can now do MAC reinit on load when there has been a
  media override set in the NSP.

Patch 3: Refactor the nfp_app_reprs_set API.

Patch 4: Similar to vNICs, representors must be able to deal with media
  override changes in the NSP.

Patch 5: Since representors can now handle media overrides, we can
  allocate the get/set link ndo's to them.

Patch 6 & 7: Add support for FEC mode modification.

Dirk van der Merwe (5):
  nfp: refactor nfp_app_reprs_set
  nfp: resync repr state when port table sync
  nfp: add get/set link settings ndos to representors
  nfp: add helpers for FEC support
  nfp: implement ethtool FEC mode settings

Jakub Kicinski (2):
  nfp: don't depend on compiler constant propagation
  nfp: make use of MAC reinit

 drivers/net/ethernet/netronome/nfp/flower/main.c   |  16 +--
 drivers/net/ethernet/netronome/nfp/nfp_app.c   |   6 -
 drivers/net/ethernet/netronome/nfp/nfp_main.c  |  28 -
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 121 -
 drivers/net/ethernet/netronome/nfp/nfp_net_main.c  |   8 +-
 drivers/net/ethernet/netronome/nfp/nfp_net_repr.c  |  47 
 drivers/net/ethernet/netronome/nfp/nfp_net_repr.h  |   1 +
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c   |   5 +
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h   |  36 ++
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c   |  87 +--
 10 files changed, 325 insertions(+), 30 deletions(-)

-- 
2.11.0



[net-next 1/7] nfp: don't depend on compiler constant propagation

2017-11-04 Thread Simon Horman
From: Jakub Kicinski <jakub.kicin...@netronome.com>

Matthias reports:

  nfp_eth_set_bit_config() is marked as __always_inline to allow gcc to
  identify the 'mask' parameter as known to be constant at compile time,
  which is required to use the FIELD_GET() macro.

  The forced inlining does the trick for gcc, but for kernel builds with
  clang it results in undefined symbols:

  drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.o: In function
`__nfp_eth_set_aneg':

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c:(.text+0x787):
undefined reference to `__compiletime_assert_492'

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c:(.text+0x7b1):
undefined reference to `__compiletime_assert_496'

  These __compiletime_assert_xyx() calls would have been optimized away
if
  the compiler had seen 'mask' as a constant.

Add a macro to extract the mask and shift and pass those to
nfp_eth_set_bit_config() separately.

Reported-by: Matthias Kaehlcke <m...@chromium.org>
Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Tested-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c   | 23 ++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
index f6f7c085f8e0..47251396fcae 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
@@ -469,10 +469,10 @@ int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned 
int idx, bool configed)
return nfp_eth_config_commit_end(nsp);
 }
 
-/* Force inline, FIELD_* macroes require masks to be compilation-time known */
-static __always_inline int
+static int
 nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int raw_idx,
-  const u64 mask, unsigned int val, const u64 ctrl_bit)
+  const u64 mask, const unsigned int shift,
+  unsigned int val, const u64 ctrl_bit)
 {
union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
unsigned int idx = nfp_nsp_config_idx(nsp);
@@ -489,11 +489,11 @@ nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int 
raw_idx,
 
/* Check if we are already in requested state */
reg = le64_to_cpu(entries[idx].raw[raw_idx]);
-   if (val == FIELD_GET(mask, reg))
+   if (val == (reg & mask) >> shift)
return 0;
 
reg &= ~mask;
-   reg |= FIELD_PREP(mask, val);
+   reg |= (val << shift) & mask;
entries[idx].raw[raw_idx] = cpu_to_le64(reg);
 
entries[idx].control |= cpu_to_le64(ctrl_bit);
@@ -503,6 +503,13 @@ nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int 
raw_idx,
return 0;
 }
 
+#define NFP_ETH_SET_BIT_CONFIG(nsp, raw_idx, mask, val, ctrl_bit)  \
+   ({  \
+   __BF_FIELD_CHECK(mask, 0ULL, val, "NFP_ETH_SET_BIT_CONFIG: "); \
+   nfp_eth_set_bit_config(nsp, raw_idx, mask, __bf_shf(mask), \
+  val, ctrl_bit);  \
+   })
+
 /**
  * __nfp_eth_set_aneg() - set PHY autonegotiation control bit
  * @nsp:   NFP NSP handle returned from nfp_eth_config_start()
@@ -515,7 +522,7 @@ nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int 
raw_idx,
  */
 int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode)
 {
-   return nfp_eth_set_bit_config(nsp, NSP_ETH_RAW_STATE,
+   return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
  NSP_ETH_STATE_ANEG, mode,
  NSP_ETH_CTRL_SET_ANEG);
 }
@@ -544,7 +551,7 @@ int __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int 
speed)
return -EINVAL;
}
 
-   return nfp_eth_set_bit_config(nsp, NSP_ETH_RAW_STATE,
+   return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
  NSP_ETH_STATE_RATE, rate,
  NSP_ETH_CTRL_SET_RATE);
 }
@@ -561,6 +568,6 @@ int __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int 
speed)
  */
 int __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes)
 {
-   return nfp_eth_set_bit_config(nsp, NSP_ETH_RAW_PORT, NSP_ETH_PORT_LANES,
+   return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_PORT, NSP_ETH_PORT_LANES,
  lanes, NSP_ETH_CTRL_SET_LANES);
 }
-- 
2.11.0



[net-next 6/7] nfp: add helpers for FEC support

2017-11-04 Thread Simon Horman
From: Dirk van der Merwe <dirk.vanderme...@netronome.com>

Implement helpers to determine and modify FEC modes via the NSP.
The NSP advertises FEC capabilities on a per port basis and provides
support for:
* Auto mode selection
* Reed Solomon
* BaseR
* None/Off

Signed-off-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h   | 30 ++
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c   | 64 ++
 2 files changed, 94 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
index 47486d42f2d7..650ca1a5bd21 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
@@ -79,6 +79,18 @@ enum nfp_eth_aneg {
NFP_ANEG_DISABLED,
 };
 
+enum nfp_eth_fec {
+   NFP_FEC_AUTO_BIT = 0,
+   NFP_FEC_BASER_BIT,
+   NFP_FEC_REED_SOLOMON_BIT,
+   NFP_FEC_DISABLED_BIT,
+};
+
+#define NFP_FEC_AUTO   BIT(NFP_FEC_AUTO_BIT)
+#define NFP_FEC_BASER  BIT(NFP_FEC_BASER_BIT)
+#define NFP_FEC_REED_SOLOMON   BIT(NFP_FEC_REED_SOLOMON_BIT)
+#define NFP_FEC_DISABLED   BIT(NFP_FEC_DISABLED_BIT)
+
 /**
  * struct nfp_eth_table - ETH table information
  * @count: number of table entries
@@ -93,6 +105,7 @@ enum nfp_eth_aneg {
  * @speed: interface speed (in Mbps)
  * @interface: interface (module) plugged in
  * @media: media type of the @interface
+ * @fec:   forward error correction mode
  * @aneg:  auto negotiation mode
  * @mac_addr:  interface MAC address
  * @label_port:port id
@@ -105,6 +118,7 @@ enum nfp_eth_aneg {
  * @port_type: one of %PORT_* defines for ethtool
  * @port_lanes:total number of lanes on the port (sum of lanes of all 
subports)
  * @is_split:  is interface part of a split port
+ * @fec_modes_supported:   bitmap of FEC modes supported
  */
 struct nfp_eth_table {
unsigned int count;
@@ -120,6 +134,7 @@ struct nfp_eth_table {
unsigned int interface;
enum nfp_eth_media media;
 
+   enum nfp_eth_fec fec;
enum nfp_eth_aneg aneg;
 
u8 mac_addr[ETH_ALEN];
@@ -139,6 +154,8 @@ struct nfp_eth_table {
unsigned int port_lanes;
 
bool is_split;
+
+   unsigned int fec_modes_supported;
} ports[0];
 };
 
@@ -149,6 +166,19 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp 
*nsp);
 int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable);
 int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx,
   bool configed);
+int
+nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode);
+
+static inline bool nfp_eth_can_support_fec(struct nfp_eth_table_port *eth_port)
+{
+   return !!eth_port->fec_modes_supported;
+}
+
+static inline unsigned int
+nfp_eth_supported_fec_modes(struct nfp_eth_table_port *eth_port)
+{
+   return eth_port->fec_modes_supported;
+}
 
 struct nfp_nsp *nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx);
 int nfp_eth_config_commit_end(struct nfp_nsp *nsp);
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
index 47251396fcae..7ca589660e4d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
@@ -55,6 +55,8 @@
 #define NSP_ETH_PORT_INDEX GENMASK_ULL(15, 8)
 #define NSP_ETH_PORT_LABEL GENMASK_ULL(53, 48)
 #define NSP_ETH_PORT_PHYLABEL  GENMASK_ULL(59, 54)
+#define NSP_ETH_PORT_FEC_SUPP_BASERBIT_ULL(60)
+#define NSP_ETH_PORT_FEC_SUPP_RS   BIT_ULL(61)
 
 #define NSP_ETH_PORT_LANES_MASKcpu_to_le64(NSP_ETH_PORT_LANES)
 
@@ -67,6 +69,7 @@
 #define NSP_ETH_STATE_MEDIAGENMASK_ULL(21, 20)
 #define NSP_ETH_STATE_OVRD_CHNGBIT_ULL(22)
 #define NSP_ETH_STATE_ANEG GENMASK_ULL(25, 23)
+#define NSP_ETH_STATE_FEC  GENMASK_ULL(27, 26)
 
 #define NSP_ETH_CTRL_CONFIGUREDBIT_ULL(0)
 #define NSP_ETH_CTRL_ENABLED   BIT_ULL(1)
@@ -75,6 +78,7 @@
 #define NSP_ETH_CTRL_SET_RATE  BIT_ULL(4)
 #define NSP_ETH_CTRL_SET_LANES BIT_ULL(5)
 #define NSP_ETH_CTRL_SET_ANEG  BIT_ULL(6)
+#define NSP_ETH_CTRL_SET_FEC   BIT_ULL(7)
 
 enum nfp_eth_raw {
NSP_ETH_RAW_PORT = 0,
@@ -152,6 +156,7 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union 
eth_table_entry *src,
   unsigned int index, struct nfp_eth_table_port *dst)
 {
unsigned int rate;
+   unsigned int fec;
u64 port, state;
 
port = le64_to_cpu(src->port);
@@ -183,6 +188,18 @@ nfp_eth_port_translate(struc

[net-next 3/7] nfp: refactor nfp_app_reprs_set

2017-11-04 Thread Simon Horman
From: Dirk van der Merwe <dirk.vanderme...@netronome.com>

The criteria that reprs cannot be replaced with another new set of reprs
has been removed. This check is not needed since the only use case that
could exercise this at the moment, would be to modify the number of
SRIOV VFs without first disabling them. This case is explicitly
disallowed in any case and subsequent patches in this series
need to be able to replace the running set of reprs.

All cases where the return code used to be checked for the
nfp_app_reprs_set function have been removed.
As stated above, it is not possible for the current code to encounter a
case where reprs exist and need to be replaced.

Signed-off-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/main.c | 16 
 drivers/net/ethernet/netronome/nfp/nfp_app.c |  6 --
 2 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c 
b/drivers/net/ethernet/netronome/nfp/flower/main.c
index e46e7c60d491..e0283bb24f06 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -142,8 +142,8 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
 {
u8 nfp_pcie = nfp_cppcore_pcie_unit(app->pf->cpp);
struct nfp_flower_priv *priv = app->priv;
-   struct nfp_reprs *reprs, *old_reprs;
enum nfp_port_type port_type;
+   struct nfp_reprs *reprs;
const u8 queue = 0;
int i, err;
 
@@ -194,11 +194,7 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
 reprs->reprs[i]->name);
}
 
-   old_reprs = nfp_app_reprs_set(app, repr_type, reprs);
-   if (IS_ERR(old_reprs)) {
-   err = PTR_ERR(old_reprs);
-   goto err_reprs_clean;
-   }
+   nfp_app_reprs_set(app, repr_type, reprs);
 
return 0;
 err_reprs_clean:
@@ -222,8 +218,8 @@ static int
 nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
 {
struct nfp_eth_table *eth_tbl = app->pf->eth_tbl;
-   struct nfp_reprs *reprs, *old_reprs;
struct sk_buff *ctrl_skb;
+   struct nfp_reprs *reprs;
unsigned int i;
int err;
 
@@ -280,11 +276,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct 
nfp_flower_priv *priv)
 phys_port, reprs->reprs[phys_port]->name);
}
 
-   old_reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
-   if (IS_ERR(old_reprs)) {
-   err = PTR_ERR(old_reprs);
-   goto err_reprs_clean;
-   }
+   nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
 
/* The MAC_REPR control message should be sent after the MAC
 * representors are registered using nfp_app_reprs_set().  This is
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c 
b/drivers/net/ethernet/netronome/nfp/nfp_app.c
index 3644d74fe304..955a9f44d244 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c
@@ -106,14 +106,8 @@ nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type 
type,
 
old = rcu_dereference_protected(app->reprs[type],
lockdep_is_held(>pf->lock));
-   if (reprs && old) {
-   old = ERR_PTR(-EBUSY);
-   goto exit_unlock;
-   }
-
rcu_assign_pointer(app->reprs[type], reprs);
 
-exit_unlock:
return old;
 }
 
-- 
2.11.0



[net-next 2/7] nfp: make use of MAC reinit

2017-11-04 Thread Simon Horman
From: Jakub Kicinski <jakub.kicin...@netronome.com>

Recent management FW images can perform full reinit of MAC cores
without requiring a reboot.  When loading the driver check if there
are changes pending and if so call NSP MAC reinit.  Full application
FW reload is still required, and all MACs need to be reinited at the
same time (not only the ones which have been reconfigured, and thus
potentially causing disruption to unrelated netdevs) therefore for
now changing MAC config without reloading the driver still remains
future work.

Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Tested-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
Signed-off-by: Simon Horman <simon.hor...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_main.c  | 28 +-
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   |  2 +-
 drivers/net/ethernet/netronome/nfp/nfp_net_main.c  |  2 +-
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c   |  5 
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h   |  6 +
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c 
b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index f8fa63b66739..35eaccbece36 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -346,6 +346,32 @@ nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, 
struct nfp_nsp *nsp)
return err < 0 ? err : 1;
 }
 
+static void
+nfp_nsp_init_ports(struct pci_dev *pdev, struct nfp_pf *pf,
+  struct nfp_nsp *nsp)
+{
+   bool needs_reinit = false;
+   int i;
+
+   pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
+   if (!pf->eth_tbl)
+   return;
+
+   if (!nfp_nsp_has_mac_reinit(nsp))
+   return;
+
+   for (i = 0; i < pf->eth_tbl->count; i++)
+   needs_reinit |= pf->eth_tbl->ports[i].override_changed;
+   if (!needs_reinit)
+   return;
+
+   kfree(pf->eth_tbl);
+   if (nfp_nsp_mac_reinit(nsp))
+   dev_warn(>dev, "MAC reinit failed\n");
+
+   pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
+}
+
 static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
 {
struct nfp_nsp *nsp;
@@ -366,7 +392,7 @@ static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf 
*pf)
if (err < 0)
goto exit_close_nsp;
 
-   pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
+   nfp_nsp_init_ports(pdev, pf, nsp);
 
pf->nspi = __nfp_nsp_identify(nsp);
if (pf->nspi)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index c67b90c8d8b7..0061097c271e 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -328,7 +328,7 @@ nfp_net_set_link_ksettings(struct net_device *netdev,
return -EOPNOTSUPP;
 
if (netif_running(netdev)) {
-   netdev_warn(netdev, "Changing settings not allowed on an active 
interface. It may cause the port to be disabled until reboot.\n");
+   netdev_warn(netdev, "Changing settings not allowed on an active 
interface. It may cause the port to be disabled until driver reload.\n");
return -EBUSY;
}
 
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index ff373acd28f3..0beb9b21557b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -597,7 +597,7 @@ nfp_net_eth_port_update(struct nfp_cpp *cpp, struct 
nfp_port *port,
return -EIO;
}
if (eth_port->override_changed) {
-   nfp_warn(cpp, "Port #%d config changed, unregistering. Reboot 
required before port will be operational again.\n", port->eth_id);
+   nfp_warn(cpp, "Port #%d config changed, unregistering. Driver 
reload required before port will be operational again.\n", port->eth_id);
port->type = NFP_PORT_INVALID;
}
 
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
index 37364555c42b..14a6d1ba51a9 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
@@ -477,6 +477,11 @@ int nfp_nsp_device_soft_reset(struct nfp_nsp *state)
return nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0);
 }
 
+int nfp_nsp_mac_reinit(struct nfp_nsp *state)
+{
+   return nfp_nsp_command(state, SPCODE_MAC_INIT, 0, 0, 0);
+}
+
 int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw)
 {
return nfp_nsp_command_buf(state, SPCODE_FW_LOAD, f

Re: [patch net-next v2 0/4] net: sched: block callbacks follow-up

2017-11-01 Thread Simon Horman
On Wed, Nov 01, 2017 at 11:47:37AM +0100, Jiri Pirko wrote:
> From: Jiri Pirko <j...@mellanox.com>
> 
> This patchset does a bit of cleanup of leftovers after block callbacks
> patchset. The main part is patch 2, which restores the original handling
> of tc offload feature flag.

Reviewed-by: Simon Horman <simon.hor...@netronome.com>



Re: [PATCH net-next v4 3/3] net sched act_vlan: VLAN action rewrite to use RCU lock/unlock and update

2017-11-01 Thread Simon Horman
On Tue, Oct 31, 2017 at 02:17:00PM -0400, Manish Kurup wrote:
> Using a spinlock in the VLAN action causes performance issues when the VLAN
> action is used on multiple cores. Rewrote the VLAN action to use RCU read
> locking for reads and updates instead.
> 
> Acked-by: Jamal Hadi Salim 
> Acked-by: Jiri Pirko 
> Signed-off-by: Manish Kurup 
> ---
>  include/net/tc_act/tc_vlan.h | 46 +--
>  net/sched/act_vlan.c | 65 
> 
>  2 files changed, 78 insertions(+), 33 deletions(-)
> 
> diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h
> index c2090df..22ae260 100644
> --- a/include/net/tc_act/tc_vlan.h
> +++ b/include/net/tc_act/tc_vlan.h
> @@ -13,12 +13,17 @@
>  #include 
>  #include 
>  
> +struct tcf_vlan_params {
> + int   tcfv_action;
> + u16   tcfv_push_vid;
> + __be16tcfv_push_proto;
> + u8tcfv_push_prio;
> + struct rcu_head   rcu;
> +};
> +
>  struct tcf_vlan {
>   struct tc_actioncommon;
> - int tcfv_action;
> - u16 tcfv_push_vid;
> - __be16  tcfv_push_proto;
> - u8  tcfv_push_prio;
> + struct tcf_vlan_params __rcu *vlan_p;
>  };
>  #define to_vlan(a) ((struct tcf_vlan *)a)
>  
> @@ -33,22 +38,45 @@ static inline bool is_tcf_vlan(const struct tc_action *a)
>  
>  static inline u32 tcf_vlan_action(const struct tc_action *a)
>  {
> - return to_vlan(a)->tcfv_action;
> + u32 tcfv_action;
> +
> + rcu_read_lock();
> + tcfv_action = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_action;
> + rcu_read_unlock();
> +
> + return tcfv_action;
>  }
>  
>  static inline u16 tcf_vlan_push_vid(const struct tc_action *a)
>  {
> - return to_vlan(a)->tcfv_push_vid;
> + u16 tcfv_push_vid;
> +
> + rcu_read_lock();
> + tcfv_push_vid = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_vid;
> + rcu_read_unlock();
> +
> + return tcfv_push_vid;
>  }
>  
>  static inline __be16 tcf_vlan_push_proto(const struct tc_action *a)
>  {
> - return to_vlan(a)->tcfv_push_proto;
> + __be16 tcfv_push_proto;
> +
> + rcu_read_lock();
> + tcfv_push_proto = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_proto;
> + rcu_read_unlock();
> +
> + return tcfv_push_proto;
>  }
>  
>  static inline u8 tcf_vlan_push_prio(const struct tc_action *a)
>  {
> - return to_vlan(a)->tcfv_push_prio;
> -}
> + u8 tcfv_push_prio;
>  
> + rcu_read_lock();
> + tcfv_push_prio = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_prio;
> + rcu_read_unlock();
> +
> + return tcfv_push_prio;
> +}
>  #endif /* __NET_TC_VLAN_H */
> diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
> index b093bad..7f461f9 100644
> --- a/net/sched/act_vlan.c
> +++ b/net/sched/act_vlan.c
> @@ -26,6 +26,7 @@ static int tcf_vlan(struct sk_buff *skb, const struct 
> tc_action *a,
>   struct tcf_result *res)
>  {
>   struct tcf_vlan *v = to_vlan(a);
> + struct tcf_vlan_params *p;
>   int action;
>   int err;
>   u16 tci;
> @@ -33,24 +34,27 @@ static int tcf_vlan(struct sk_buff *skb, const struct 
> tc_action *a,
>   tcf_lastuse_update(>tcf_tm);
>   bstats_cpu_update(this_cpu_ptr(v->common.cpu_bstats), skb);
>  
> - spin_lock(>tcf_lock);
> - action = v->tcf_action;
> -
>   /* Ensure 'data' points at mac_header prior calling vlan manipulating
>* functions.
>*/
>   if (skb_at_tc_ingress(skb))
>   skb_push_rcsum(skb, skb->mac_len);
>  
> - switch (v->tcfv_action) {
> + rcu_read_lock();
> +
> + action = READ_ONCE(v->tcf_action);
> +
> + p = rcu_dereference(v->vlan_p);
> +
> + switch (p->tcfv_action) {

Its not clear to me why v->tcfv_action is changed to p->tcfv_action here.

>   case TCA_VLAN_ACT_POP:
>   err = skb_vlan_pop(skb);
>   if (err)
>   goto drop;
>   break;
>   case TCA_VLAN_ACT_PUSH:
> - err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid |
> - (v->tcfv_push_prio << VLAN_PRIO_SHIFT));
> + err = skb_vlan_push(skb, p->tcfv_push_proto, p->tcfv_push_vid |
> + (p->tcfv_push_prio << VLAN_PRIO_SHIFT));
>   if (err)
>   goto drop;
>   break;
> @@ -69,14 +73,14 @@ static int tcf_vlan(struct sk_buff *skb, const struct 
> tc_action *a,
>   goto drop;
>   }
>   /* replace the vid */
> - tci = (tci & ~VLAN_VID_MASK) | v->tcfv_push_vid;
> + tci = (tci & ~VLAN_VID_MASK) | p->tcfv_push_vid;
>   /* replace prio bits, if tcfv_push_prio specified */
> - if (v->tcfv_push_prio) 

Re: [patch net-next RFC 2/9] net_sch: mqprio: Change TC_SETUP_MQPRIO to TC_SETUP_QDISC_MQPRIO

2017-11-01 Thread Simon Horman
On Mon, Oct 30, 2017 at 09:56:06AM +0100, Jiri Pirko wrote:
> From: Nogah Frankel 
> 
> Change TC_SETUP_MQPRIO to TC_SETUP_QDISC_MQPRIO to match the new
> convention.

Why is there a new convention? This churn in this and the following patch
warrant some justification IMHO.


Re: [PATCH] netfilter: ipvs: Convert timers to use timer_setup()

2017-11-02 Thread Simon Horman
On Tue, Oct 24, 2017 at 10:07:03PM +0300, Julian Anastasov wrote:
> 
>   Hello,
> 
> On Tue, 24 Oct 2017, Kees Cook wrote:
> 
> > In preparation for unconditionally passing the struct timer_list pointer to
> > all timer callbacks, switch to using the new timer_setup() and from_timer()
> > to pass the timer pointer explicitly.
> > 
> > Cc: Wensong Zhang <wens...@linux-vs.org>
> > Cc: Simon Horman <ho...@verge.net.au>
> > Cc: Julian Anastasov <j...@ssi.bg>
> > Cc: Pablo Neira Ayuso <pa...@netfilter.org>
> > Cc: Jozsef Kadlecsik <kad...@blackhole.kfki.hu>
> > Cc: Florian Westphal <f...@strlen.de>
> > Cc: "David S. Miller" <da...@davemloft.net>
> > Cc: netdev@vger.kernel.org
> > Cc: lvs-de...@vger.kernel.org
> > Cc: netfilter-de...@vger.kernel.org
> > Cc: coret...@netfilter.org
> > Signed-off-by: Kees Cook <keesc...@chromium.org>
> 
>   Looks good to me,
> 
> Acked-by: Julian Anastasov <j...@ssi.bg>

Signed-off-by: Simon Horman <ho...@verge.net.au>

Pablo, could you take this?


Re: [PATCH] netfilter/ipvs: clear ipvs_property flag when SKB net namespace changed

2017-11-02 Thread Simon Horman
On Sat, Oct 28, 2017 at 01:33:09PM +0300, Julian Anastasov wrote:
> 
>   Hello,
> 
> On Thu, 26 Oct 2017, Ye Yin wrote:
> 
> > When run ipvs in two different network namespace at the same host, and one
> > ipvs transport network traffic to the other network namespace ipvs.
> > 'ipvs_property' flag will make the second ipvs take no effect. So we should
> > clear 'ipvs_property' when SKB network namespace changed.
> > 
> > Signed-off-by: Ye Yin <hust...@gmail.com>
> > Signed-off-by: Wei Zhou <chouryz...@gmail.com>
> 
>   Patch looks good to me. ipvs_property was added long ago
> but skb_scrub_packet() is more recent (3.11), so:
> 
> Fixes: 621e84d6f373 ("dev: introduce skb_scrub_packet()")
> Signed-off-by: Julian Anastasov <j...@ssi.bg>
> 
>   I guess, DaveM can apply it directly as a bugfix
> to the net tree.

Sounds like a good plan to me, Dave?

Signed-off-by: Simon Horman <ho...@verge.net.au>



Re: [patch net-next 1/9] net_sch: red: Add offload ability to RED qdisc

2017-11-06 Thread Simon Horman
On Mon, Nov 06, 2017 at 07:23:41AM +0100, Jiri Pirko wrote:
> From: Nogah Frankel <nog...@mellanox.com>
> 
> Add the ability to offload RED qdisc by using ndo_setup_tc.
> There are four commands for RED offloading:
> * TC_RED_SET: handles set and change.
> * TC_RED_DESTROY: handle qdisc destroy.
> * TC_RED_STATS: update the qdiscs counters (given as reference)
> * TC_RED_XSTAT: returns red xstats.
> 
> Whether RED is being offloaded is being determined every time dump action
> is being called because parent change of this qdisc could change its
> offload state but doesn't require any RED function to be called.
> 
> Signed-off-by: Nogah Frankel <nog...@mellanox.com>
> Signed-off-by: Jiri Pirko <j...@mellanox.com>

Reviewed-by: Simon Horman <simon.hor...@netronome.com>


Re: [patch net-next 2/9] net_sch: mqprio: Change TC_SETUP_MQPRIO to TC_SETUP_QDISC_MQPRIO

2017-11-06 Thread Simon Horman
On Mon, Nov 06, 2017 at 07:23:42AM +0100, Jiri Pirko wrote:
> From: Nogah Frankel <nog...@mellanox.com>
> 
> Change TC_SETUP_MQPRIO to TC_SETUP_QDISC_MQPRIO to match the new
> convention.
> 
> Signed-off-by: Nogah Frankel <nog...@mellanox.com>
> Signed-off-by: Jiri Pirko <j...@mellanox.com>

Reviewed-by: Simon Horman <simon.hor...@netronome.com>



Re: [patch net-next 3/9] net_sch: cbs: Change TC_SETUP_CBS to TC_SETUP_QDISC_CBS

2017-11-06 Thread Simon Horman
On Mon, Nov 06, 2017 at 07:23:43AM +0100, Jiri Pirko wrote:
> From: Nogah Frankel <nog...@mellanox.com>
> 
> Change TC_SETUP_CBS to TC_SETUP_QDISC_CBS to match the new convention..
> 
> Signed-off-by: Nogah Frankel <nog...@mellanox.com>
> Signed-off-by: Jiri Pirko <j...@mellanox.com>

Reviewed-by: Simon Horman <simon.hor...@netronome.com>



[PATCH net-next] flow_dissector: dissect tunnel info outside __skb_flow_dissect()

2017-12-04 Thread Simon Horman
Move dissection of tunnel info to outside of the main flow dissection
function, __skb_flow_dissect(). The sole user of this feature, the flower
classifier, is updated to call tunnel info dissection directly, using
skb_flow_dissect_tunnel_info().

This results in a slightly less complex implementation of
__skb_flow_dissect(), in particular removing logic from that call path
which is not used by the majority of users. The expense of this is borne by
the flower classifier which now has to make an extra call for tunnel info
dissection.

This patch should not result in any behavioural change.

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 include/linux/skbuff.h|  5 +
 net/core/flow_dissector.c | 12 +---
 net/sched/cls_flower.c|  1 +
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index bc486ef23f20..7d053bbaa5d1 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1211,6 +1211,11 @@ static inline bool skb_flow_dissect_flow_keys_buf(struct 
flow_keys *flow,
  data, proto, nhoff, hlen, flags);
 }
 
+void
+skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
+struct flow_dissector *flow_dissector,
+void *target_container);
+
 static inline __u32 skb_get_hash(struct sk_buff *skb)
 {
if (!skb->l4_hash && !skb->sw_hash)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 15ce30063765..cc75488d3653 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -133,10 +133,10 @@ skb_flow_dissect_set_enc_addr_type(enum 
flow_dissector_key_id type,
ctrl->addr_type = type;
 }
 
-static void
-__skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
-  struct flow_dissector *flow_dissector,
-  void *target_container)
+void
+skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
+struct flow_dissector *flow_dissector,
+void *target_container)
 {
struct ip_tunnel_info *info;
struct ip_tunnel_key *key;
@@ -212,6 +212,7 @@ __skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
tp->dst = key->tp_dst;
}
 }
+EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
 
 static enum flow_dissect_ret
 __skb_flow_dissect_mpls(const struct sk_buff *skb,
@@ -576,9 +577,6 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
  FLOW_DISSECTOR_KEY_BASIC,
  target_container);
 
-   __skb_flow_dissect_tunnel_info(skb, flow_dissector,
-  target_container);
-
if (dissector_uses_key(flow_dissector,
   FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
struct ethhdr *eth = eth_hdr(skb);
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 543a3e875d05..6132a7317efa 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -166,6 +166,7 @@ static int fl_classify(struct sk_buff *skb, const struct 
tcf_proto *tp,
 * so do it rather here.
 */
skb_key.basic.n_proto = skb->protocol;
+   skb_flow_dissect_tunnel_info(skb, >dissector, _key);
skb_flow_dissect(skb, >dissector, _key, 0);
 
fl_set_masked_key(_mkey, _key, >mask);
-- 
2.11.0



Re: [PATCH v4 0/4] Teach phylib hard-resetting devices

2017-12-10 Thread Simon Horman
On Mon, Dec 04, 2017 at 11:34:48AM +0100, Geert Uytterhoeven wrote:
>   Hi David, Andrew, Florian, Simon, Magnus,
> 
> This patch series adds optional PHY reset support to phylib.
> 
> The first two patches are destined for David's net-next tree. They add
> core PHY reset code, and update a driver that currently uses its own
> reset code.
> 
> The last two patches are destined for Simon's renesas tree.  They add
> properties to describe the EthernetAVB PHY reset topology to the common
> Salvator-X/XS and ULCB DTS files, which solves two issues:
>   1. On Salvator-XS, the enable pin of the regulator providing PHY power
>  is connected to PRESETn, and PSCI powers down the SoC during system
>  suspend.  Hence a PHY reset is needed to restore network
>  functionality after system resume.
>   2. Linux should not rely on the boot loader having reset the PHY, but
>  should reset the PHY during driver probe.

Thanks, I have applied patches 3/4 and 4/4 for v4.16.


Re: [PATCH] dt-bindings: net: ravb: Add support for r8a77990 SoC

2018-05-13 Thread Simon Horman
On Fri, May 11, 2018 at 03:59:42PM -0400, David Miller wrote:
> From: Yoshihiro Shimoda <yoshihiro.shimoda...@renesas.com>
> Date: Fri, 11 May 2018 12:18:56 +0900
> 
> > Add documentation for r8a77990 compatible string to renesas ravb device
> > tree bindings documentation.
> > 
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda...@renesas.com>
> 
> I'm assuming this isn't targetted at one of my trees.  Just FYI.

Hi Dave,

I think this is appropriate for net-next but if not I can take it.

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>


Shimoda-san,

please use "[PATCH net-next]" for non-bugfix networking updates which
are targeted at Dave's net-next tree. Bug fixes should be for "net".
Patches should of course apply cleanly to whichever tree it is targeted at.


Re: [PATCH] dt-bindings: can: rcar_can: Fix R8A7796 SoC name

2018-05-04 Thread Simon Horman
On Thu, May 03, 2018 at 03:02:33PM +0200, Geert Uytterhoeven wrote:
> R8A7796 is R-Car M3-W.
> 
> Signed-off-by: Geert Uytterhoeven <geert+rene...@glider.be>

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>



Re: [PATCH 3/3] sh_eth: add R8A77980 support

2018-05-17 Thread Simon Horman
On Wed, May 16, 2018 at 11:00:29PM +0300, Sergei Shtylyov wrote:
> Finally, add support for the DT probing of the R-Car V3H (AKA R8A77980) --
> it's the only R-Car gen3 SoC having the GEther controller -- others have
> only EtherAVB...
> 
> Based on the original (and large) patch by Vladimir Barinov.
> 
> Signed-off-by: Vladimir Barinov <vladimir.bari...@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>


Re: [PATCH 2/3] sh_eth: add EDMR.NBST support

2018-05-17 Thread Simon Horman
On Wed, May 16, 2018 at 10:58:26PM +0300, Sergei Shtylyov wrote:
> The R-Car V3H (AKA R8A77980) GEther controller adds the DMA burst mode bit
> (NBST) in EDMR and the manual tells to always set it before doing any DMA.
> 
> Based on the original (and large) patch by Vladimir Barinov.
> 
> Signed-off-by: Vladimir Barinov <vladimir.bari...@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>

> 
> ---
>  drivers/net/ethernet/renesas/sh_eth.c |4 
>  drivers/net/ethernet/renesas/sh_eth.h |2 ++
>  2 files changed, 6 insertions(+)
> 
> Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
> ===
> --- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
> +++ net-next/drivers/net/ethernet/renesas/sh_eth.c
> @@ -1434,6 +1434,10 @@ static int sh_eth_dev_init(struct net_de
>  
>   sh_eth_write(ndev, mdp->cd->trscer_err_mask, TRSCER);
>  
> + /* DMA transfer burst mode */
> + if (mdp->cd->nbst)
> + sh_eth_modify(ndev, EDMR, EDMR_NBST, EDMR_NBST);
> +
>   if (mdp->cd->bculr)
>   sh_eth_write(ndev, 0x800, BCULR);   /* Burst sycle set */

Not related to this patch, but: s/sycle/cycle/

>  
> Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
> ===
> --- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
> +++ net-next/drivers/net/ethernet/renesas/sh_eth.h
> @@ -184,6 +184,7 @@ enum GECMR_BIT {
>  
>  /* EDMR */
>  enum DMAC_M_BIT {
> + EDMR_NBST = 0x80,

It would be nice to start using BIT() in this file.

>   EDMR_EL = 0x40, /* Litte endian */
>   EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
>   EDMR_SRST_GETHER = 0x03,
> @@ -505,6 +506,7 @@ struct sh_eth_cpu_data {
>   unsigned bculr:1;   /* EtherC have BCULR */
>   unsigned tsu:1; /* EtherC have TSU */
>   unsigned hw_swap:1; /* E-DMAC have DE bit in EDMR */
> + unsigned nbst:1;/* E-DMAC has NBST bit in EDMR */
>   unsigned rpadir:1;  /* E-DMAC have RPADIR */
>   unsigned no_trimd:1;/* E-DMAC DO NOT have TRIMD */
>   unsigned no_ade:1;  /* E-DMAC DO NOT have ADE bit in EESR */
> 


Re: [PATCH net v2] net/sched: act_simple: fix parsing of TCA_DEF_DATA

2018-06-08 Thread Simon Horman
On Fri, Jun 08, 2018 at 05:02:31AM +0200, Davide Caratti wrote:
> use nla_strlcpy() to avoid copying data beyond the length of TCA_DEF_DATA
> netlink attribute, in case it is less than SIMP_MAX_DATA and it does not
> end with '\0' character.
> 
> v2: fix errors in the commit message, thanks Hangbin Liu
> 
> Fixes: fa1b1cff3d06 ("net_cls_act: Make act_simple use of netlink policy.")
> Signed-off-by: Davide Caratti 

Reviewed-by: Simon Horman 


Re: [PATCH net] KEYS: DNS: fix parsing multiple options

2018-06-11 Thread Simon Horman
On Mon, Jun 11, 2018 at 10:57:42AM -0700, Eric Biggers wrote:
> Hi Simon,
> 
> On Mon, Jun 11, 2018 at 11:40:23AM +0200, Simon Horman wrote:
> > On Fri, Jun 08, 2018 at 09:20:37AM -0700, Eric Biggers wrote:
> > > From: Eric Biggers 
> > > 
> > > My recent fix for dns_resolver_preparse() printing very long strings was
> > > incomplete, as shown by syzbot which still managed to hit the
> > > WARN_ONCE() in set_precision() by adding a crafted "dns_resolver" key:
> > > 
> > > precision 50001 too large
> > > WARNING: CPU: 7 PID: 864 at lib/vsprintf.c:2164 vsnprintf+0x48a/0x5a0
> > > 
> > > The bug this time isn't just a printing bug, but also a logical error
> > > when multiple options ("#"-separated strings) are given in the key
> > > payload.  Specifically, when separating an option string into name and
> > > value, if there is no value then the name is incorrectly considered to
> > > end at the end of the key payload, rather than the end of the current
> > > option.  This bypasses validation of the option length, and also means
> > > that specifying multiple options is broken -- which presumably has gone
> > > unnoticed as there is currently only one valid option anyway.
> > > 
> > > Fix it by correctly calculating the length of the option name.
> > > 
> > > Reproducer:
> > > 
> > > perl -e 'print "#A#", "\x00" x 5' | keyctl padd dns_resolver desc 
> > > @s
> > > 
> > > Fixes: 4a2d789267e0 ("DNS: If the DNS server returns an error, allow that 
> > > to be cached [ver #2]")
> > > Signed-off-by: Eric Biggers 
> > > ---
> > >  net/dns_resolver/dns_key.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
> > > index 40c851693f77e..d448823d4d2ed 100644
> > > --- a/net/dns_resolver/dns_key.c
> > > +++ b/net/dns_resolver/dns_key.c
> > > @@ -97,7 +97,7 @@ dns_resolver_preparse(struct key_preparsed_payload 
> > > *prep)
> > >   return -EINVAL;
> > >   }
> > >  
> > > - eq = memchr(opt, '=', opt_len) ?: end;
> > > + eq = memchr(opt, '=', opt_len) ?: next_opt;
> > >   opt_nlen = eq - opt;
> > >   eq++;
> > 
> > It seems risky to advance eq++ in the case there the value is empty.
> > Its not not pointing to the value but it may be accessed twice further on
> > in this loop.
> > 
> 
> Sure, that's a separate existing issue though, and it must be checked that the
> value is present before using it anyway, which the code already does, so it's
> not a "real" bug.  I think I'll keep this patch simple and leave that part 
> as-is
> for now.

Thanks Eric, I was reflecting on that too. I agree that your patch resolves
a problem without introducing a new one.

Reviewed-by: Simon Horman 


Re: [PATCH net] KEYS: DNS: fix parsing multiple options

2018-06-11 Thread Simon Horman
On Fri, Jun 08, 2018 at 09:20:37AM -0700, Eric Biggers wrote:
> From: Eric Biggers 
> 
> My recent fix for dns_resolver_preparse() printing very long strings was
> incomplete, as shown by syzbot which still managed to hit the
> WARN_ONCE() in set_precision() by adding a crafted "dns_resolver" key:
> 
> precision 50001 too large
> WARNING: CPU: 7 PID: 864 at lib/vsprintf.c:2164 vsnprintf+0x48a/0x5a0
> 
> The bug this time isn't just a printing bug, but also a logical error
> when multiple options ("#"-separated strings) are given in the key
> payload.  Specifically, when separating an option string into name and
> value, if there is no value then the name is incorrectly considered to
> end at the end of the key payload, rather than the end of the current
> option.  This bypasses validation of the option length, and also means
> that specifying multiple options is broken -- which presumably has gone
> unnoticed as there is currently only one valid option anyway.
> 
> Fix it by correctly calculating the length of the option name.
> 
> Reproducer:
> 
> perl -e 'print "#A#", "\x00" x 5' | keyctl padd dns_resolver desc @s
> 
> Fixes: 4a2d789267e0 ("DNS: If the DNS server returns an error, allow that to 
> be cached [ver #2]")
> Signed-off-by: Eric Biggers 
> ---
>  net/dns_resolver/dns_key.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
> index 40c851693f77e..d448823d4d2ed 100644
> --- a/net/dns_resolver/dns_key.c
> +++ b/net/dns_resolver/dns_key.c
> @@ -97,7 +97,7 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
>   return -EINVAL;
>   }
>  
> - eq = memchr(opt, '=', opt_len) ?: end;
> + eq = memchr(opt, '=', opt_len) ?: next_opt;
>   opt_nlen = eq - opt;
>   eq++;

It seems risky to advance eq++ in the case there the value is empty.
Its not not pointing to the value but it may be accessed twice further on
in this loop.

>   opt_vlen = next_opt - eq; /* will be -1 if no value */
> -- 
> 2.18.0.rc1.242.g61856ae69a-goog
> 


Re: [PATCH iproute2] configure: require libmnl

2018-06-05 Thread Simon Horman
On Thu, May 31, 2018 at 03:32:09PM -0400, Stephen Hemminger wrote:
> Several users of BPF and other features are trying to build without
> libmnl, then complaining that features don't work.  The time has
> come to require libmnl to build iproute2.
> 
> Signed-off-by: Stephen Hemminger 

Reviewed-by: Simon Horman 



Re: [PATCH net-next V2 1/2] cls_flower: Fix missing free of rhashtable

2018-06-04 Thread Simon Horman
On Sun, Jun 03, 2018 at 10:06:13AM +0300, Paul Blakey wrote:
> When destroying the instance, destroy the head rhashtable.
> 
> Fixes: 05cd271fd61a ("cls_flower: Support multiple masks per priority")
> Reported-by: Vlad Buslov 
> Reviewed-by: Roi Dayan 
> Reviewed-by: Jiri Pirko 
> Signed-off-by: Paul Blakey 

Reviewed-by: Simon Horman 


Re: [PATCH net-next V2 2/2] cls_flower: Fix comparing of old filter mask with new filter

2018-06-04 Thread Simon Horman
On Sun, Jun 03, 2018 at 10:06:14AM +0300, Paul Blakey wrote:
> We incorrectly compare the mask and the result is that we can't modify
> an already existing rule.
> 
> Fix that by comparing correctly.
> 
> Fixes: 05cd271fd61a ("cls_flower: Support multiple masks per priority")
> Reported-by: Vlad Buslov 
> Reviewed-by: Roi Dayan 
> Reviewed-by: Jiri Pirko 
> Signed-off-by: Paul Blakey 

Reviewed-by: Simon Horman 



Re: [PATCH net 0/5] net sched actions: code style cleanup and fixes

2018-06-20 Thread Simon Horman
On Tue, Jun 19, 2018 at 12:56:03PM -0400, Roman Mashak wrote:
> The patchset fixes a few code stylistic issues and typos, as well as one
> detected by sparse semantic checker tool.
> 
> No functional changes introduced.
> 
> Patch 1 & 2 fix coding style bits caught by the checkpatch.pl script
> Patch 3 fixes an issue with a shadowed variable
> Patch 4 adds sizeof() operator instead of magic number for buffer length
> Patch 5 fixes typos in diagnostics messages
> 
> Roman Mashak (5):
>   net sched actions: fix coding style in pedit action
>   net sched actions: fix coding style in pedit headers
>   net sched actions: fix sparse warning
>   net sched actions: use sizeof operator for buffer length
>   net sched actions: fix misleading text strings in pedit action

All patches:

Reviewed-by: Simon Horman 



Re: [PATCH] DT: net: can: rcar_canfd: document R8A77970 bindings

2018-04-30 Thread Simon Horman
On Thu, Apr 26, 2018 at 10:41:14PM +0300, Sergei Shtylyov wrote:
> Document the R-Car V3M (R8A77970) SoC support in the R-Car CAN-FD bindings.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>

> 
> ---
> The patch is against the 'linux-can-next.git' repo but I wouldn't object if
> it's merged to the 'linux-can.git' repo instead. :-)
> 
>  Documentation/devicetree/bindings/net/can/rcar_canfd.txt |1 +
>  1 file changed, 1 insertion(+)
> 
> Index: linux-can-next/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
> ===
> --- 
> linux-can-next.orig/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
> +++ linux-can-next/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
> @@ -6,6 +6,7 @@ Required properties:
>- "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller.
>- "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
>- "renesas,r8a7796-canfd" for R8A7796 (R-Car M3) compatible controller.
> +  - "renesas,r8a77970-canfd" for R8A77970 (R-Car V3M) compatible controller.
>  
>When compatible with the generic version, nodes must list the
>SoC-specific version corresponding to the platform first, followed by the
> 


Re: [PATCH] DT: net: can: rcar_canfd: document R8A77980 bindings

2018-04-30 Thread Simon Horman
On Fri, Apr 27, 2018 at 09:53:33PM +0300, Sergei Shtylyov wrote:
> Document the R-Car V3H (R8A77980) SoC support in the R-Car CAN-FD bindings.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>
> 
> ---
> The patch is against the 'linux-can-next.git' repo plus the R8A77970 bindings
> patch posted yesterday. Although I wouldn't object if they're both merged to
> the 'linux-can.git' repo instead. :-)
> 
>  Documentation/devicetree/bindings/net/can/rcar_canfd.txt |1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Simon Horman <horms+rene...@verge.net.au>

> 
> Index: linux-can-next/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
> ===
> --- 
> linux-can-next.orig/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
> +++ linux-can-next/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
> @@ -7,6 +7,7 @@ Required properties:
>- "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
>- "renesas,r8a7796-canfd" for R8A7796 (R-Car M3) compatible controller.
>- "renesas,r8a77970-canfd" for R8A77970 (R-Car V3M) compatible controller.
> +  - "renesas,r8a77980-canfd" for R8A77980 (R-Car V3H) compatible controller.
>  
>When compatible with the generic version, nodes must list the
>SoC-specific version corresponding to the platform first, followed by the
> 


Re: [PATCH v3 0/4] Teach phylib hard-resetting devices

2017-10-20 Thread Simon Horman
On Fri, Oct 20, 2017 at 10:14:17AM +0200, Geert Uytterhoeven wrote:
>   Hi David, Andrew, Florian, Simon, Magnus,
> 
> This patch series adds optional PHY reset support to phylib.
> 
> The first two patches are destined for David's net-next tree. They add
> core PHY reset code, and update a driver that currently uses its own
> reset code.  Note that these patches depend on "[PATCH v2] of_mdio: Fix
> broken PHY IRQ in case of probe deferral"
> (https://www.spinics.net/lists/linux-renesas-soc/msg19442.html), as v3
> needs to propagate errors from of_mdiobus_register_phy() and
> of_mdiobus_register_device() [1].
> 
> The last two patches are new (sort of, see [2]), and destined for
> Simon's renesas tree.  They add properties to describe the EthernetAVB
> PHY reset topology to the common Salvator-X/XS and ULCB DTS files, which
> solves two issues:
>   1. On Salvator-XS, the enable pin of the regulator providing PHY power
>  is connected to PRESETn, and PSCI powers down the SoC during system
>  suspend.  Hence a PHY reset is needed to restore network functionality
>  after resume.
>   2. Linux should not rely on the boot loader having reset the PHY, but
>  should reset the PHY during driver probe.
> 
> Changes compared to v2, as sent by Sergei Shtylyov:
>   - Fix fwnode_get_named_gpiod() call due to added parameters (which
> allowed to eliminate the gpiod_direction_output() call),
>   - Rebased, refreshed, reworded,
>   - Take over from Sergei,
>   - Add Acked-by,
>   - Remove unneeded gpiod check, as gpiod_set_value() handles NULL fine,
>   - Handle fwnode_get_named_gpiod() errors correctly:
>   - -ENOENT is ignored (the GPIO is optional), and turned into NULL,
>   which allowed to remove all later !IS_ERR() checks,
>   - Other errors (incl. -EPROBE_DEFER) are propagated [1],
>   - Extract DTS patches from series "[PATCH 0/4] ravb: Add PHY reset
> support" (https://www.spinics.net/lists/netdev/msg457308.html), and
> incorporate in this series, after moving reset-gpios from the
> ethernet to the ethernet-phy node [2].
> 
> Thanks for your comments!
> 
> Geert Uytterhoeven (2):
>   arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset
>   arm64: dts: renesas: ulcb: Add EthernetAVB PHY reset

I have marked the above patches as deferred pending acceptance of
the other patches in this series. Please repost or otherwise ping
me once that has happened.

> 
> Sergei Shtylyov (2):
>   phylib: Add device reset GPIO support
>   macb: Kill PHY reset code
> 
>  Documentation/devicetree/bindings/net/phy.txt|  2 ++
>  arch/arm64/boot/dts/renesas/salvator-common.dtsi |  1 +
>  arch/arm64/boot/dts/renesas/ulcb.dtsi|  1 +
>  drivers/net/ethernet/cadence/macb.h  |  1 -
>  drivers/net/ethernet/cadence/macb_main.c | 21 ---
>  drivers/net/phy/at803x.c | 18 +++--
>  drivers/net/phy/mdio_bus.c   |  4 +++
>  drivers/net/phy/mdio_device.c| 26 +--
>  drivers/net/phy/phy_device.c | 33 
> ++--
>  drivers/of/of_mdio.c | 23 +
>  include/linux/mdio.h |  3 +++
>  include/linux/phy.h  |  5 
>  12 files changed, 97 insertions(+), 41 deletions(-)
> 
> -- 
> 2.7.4
> 
> Gr{oetje,eeting}s,
> 
>   Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- 
> ge...@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like 
> that.
>   -- Linus Torvalds
> 


[PATCH net-next] nfp: use struct fields for 8 bit-wide access

2017-10-20 Thread Simon Horman
From: Pieter Jansen van Vuuren <pieter.jansenvanvuu...@netronome.com>

Use direct access struct fields rather than PREP_FIELD()
macros to manipulate the jump ID and length, both of which
are exactly 8-bits wide. This simplifies the code somewhat.

Signed-off-by: Simon Horman <simon.hor...@netronome.com>
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuu...@netronome.com>
Acked-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/action.c | 87 +++---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   | 26 ---
 2 files changed, 39 insertions(+), 74 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c 
b/drivers/net/ethernet/netronome/nfp/flower/action.c
index 1194c47ef827..0a5fc9f8545f 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -47,13 +47,9 @@
 static void nfp_fl_pop_vlan(struct nfp_fl_pop_vlan *pop_vlan)
 {
size_t act_size = sizeof(struct nfp_fl_pop_vlan);
-   u16 tmp_pop_vlan_op;
 
-   tmp_pop_vlan_op =
-   FIELD_PREP(NFP_FL_ACT_LEN_LW, act_size >> NFP_FL_LW_SIZ) |
-   FIELD_PREP(NFP_FL_ACT_JMP_ID, NFP_FL_ACTION_OPCODE_POP_VLAN);
-
-   pop_vlan->a_op = cpu_to_be16(tmp_pop_vlan_op);
+   pop_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_POP_VLAN;
+   pop_vlan->head.len_lw = act_size >> NFP_FL_LW_SIZ;
pop_vlan->reserved = 0;
 }
 
@@ -64,14 +60,9 @@ nfp_fl_push_vlan(struct nfp_fl_push_vlan *push_vlan,
size_t act_size = sizeof(struct nfp_fl_push_vlan);
struct tcf_vlan *vlan = to_vlan(action);
u16 tmp_push_vlan_tci;
-   u16 tmp_push_vlan_op;
-
-   tmp_push_vlan_op =
-   FIELD_PREP(NFP_FL_ACT_LEN_LW, act_size >> NFP_FL_LW_SIZ) |
-   FIELD_PREP(NFP_FL_ACT_JMP_ID, NFP_FL_ACTION_OPCODE_PUSH_VLAN);
 
-   push_vlan->a_op = cpu_to_be16(tmp_push_vlan_op);
-   /* Set action push vlan parameters. */
+   push_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_VLAN;
+   push_vlan->head.len_lw = act_size >> NFP_FL_LW_SIZ;
push_vlan->reserved = 0;
push_vlan->vlan_tpid = tcf_vlan_push_proto(action);
 
@@ -101,16 +92,12 @@ nfp_fl_output(struct nfp_fl_output *output, const struct 
tc_action *action,
  int *tun_out_cnt)
 {
size_t act_size = sizeof(struct nfp_fl_output);
-   u16 tmp_output_op, tmp_flags;
struct net_device *out_dev;
+   u16 tmp_flags;
int ifindex;
 
-   /* Set action opcode to output action. */
-   tmp_output_op =
-   FIELD_PREP(NFP_FL_ACT_LEN_LW, act_size >> NFP_FL_LW_SIZ) |
-   FIELD_PREP(NFP_FL_ACT_JMP_ID, NFP_FL_ACTION_OPCODE_OUTPUT);
-
-   output->a_op = cpu_to_be16(tmp_output_op);
+   output->head.jump_id = NFP_FL_ACTION_OPCODE_OUTPUT;
+   output->head.len_lw = act_size >> NFP_FL_LW_SIZ;
 
ifindex = tcf_mirred_ifindex(action);
out_dev = __dev_get_by_index(dev_net(in_dev), ifindex);
@@ -161,7 +148,6 @@ static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char 
*act_data, int act_len)
 {
size_t act_size = sizeof(struct nfp_fl_pre_tunnel);
struct nfp_fl_pre_tunnel *pre_tun_act;
-   u16 tmp_pre_tun_op;
 
/* Pre_tunnel action must be first on action list.
 * If other actions already exist they need pushed forward.
@@ -173,11 +159,8 @@ static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char 
*act_data, int act_len)
 
memset(pre_tun_act, 0, act_size);
 
-   tmp_pre_tun_op =
-   FIELD_PREP(NFP_FL_ACT_LEN_LW, act_size >> NFP_FL_LW_SIZ) |
-   FIELD_PREP(NFP_FL_ACT_JMP_ID, NFP_FL_ACTION_OPCODE_PRE_TUNNEL);
-
-   pre_tun_act->a_op = cpu_to_be16(tmp_pre_tun_op);
+   pre_tun_act->head.jump_id = NFP_FL_ACTION_OPCODE_PRE_TUNNEL;
+   pre_tun_act->head.len_lw = act_size >> NFP_FL_LW_SIZ;
 
return pre_tun_act;
 }
@@ -190,7 +173,6 @@ nfp_fl_set_vxlan(struct nfp_fl_set_vxlan *set_vxlan,
struct ip_tunnel_info *vxlan = tcf_tunnel_info(action);
size_t act_size = sizeof(struct nfp_fl_set_vxlan);
u32 tmp_set_vxlan_type_index = 0;
-   u16 tmp_set_vxlan_op;
/* Currently support one pre-tunnel so index is always 0. */
int pretun_idx = 0;
 
@@ -199,12 +181,8 @@ nfp_fl_set_vxlan(struct nfp_fl_set_vxlan *set_vxlan,
return -EOPNOTSUPP;
}
 
-   tmp_set_vxlan_op =
-   FIELD_PREP(NFP_FL_ACT_LEN_LW, act_size >> NFP_FL_LW_SIZ) |
-   FIELD_PREP(NFP_FL_ACT_JMP_ID,
-  NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL);
-
-   set_vxlan->a_op = cpu_to_be16(tmp_set_vxlan_op);
+   set_vxlan->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL;
+   set_vxlan->head.len_lw = act_size >&g

<    5   6   7   8   9   10   11   >