Skip to content

Commit a847726

Browse files
committed
Merge branch 'nfp-flower-updates-and-netconsole'
Jakub Kicinski says: ==================== nfp: flower updates and netconsole This set contains assorted updates to driver base and flower. First patch is a follow up to a fix to calculating counters which went into net. For ethtool counters we should also make sure they are visible even after ring reconfiguration. Next patch is a safety measure in case we are running on a machine with a broken BIOS we should fail the probe when risk of incorrect operation is too high. The next two patches add netpoll support and make use of napi_consume_skb(). Last we populate bus info on all representors. Pieter adds support for offload of the checksum action in flower. John follows up to another fix he's done in net, we set TTL values on tunnels to stack's default, now Johns does a full route lookup to get a more precise information, he populates ToS field as well. Last but not least he follows up on Jiri's request to enable LAG offload in case the team driver is used and then hash function is unknown. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 4e485d0 + 635cf43 commit a847726

File tree

8 files changed

+178
-68
lines changed

8 files changed

+178
-68
lines changed

drivers/net/ethernet/netronome/nfp/flower/action.c

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/bitfield.h>
3535
#include <net/pkt_cls.h>
3636
#include <net/switchdev.h>
37+
#include <net/tc_act/tc_csum.h>
3738
#include <net/tc_act/tc_gact.h>
3839
#include <net/tc_act/tc_mirred.h>
3940
#include <net/tc_act/tc_pedit.h>
@@ -44,6 +45,8 @@
4445
#include "main.h"
4546
#include "../nfp_net_repr.h"
4647

48+
#define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS (TUNNEL_CSUM | TUNNEL_KEY)
49+
4750
static void nfp_fl_pop_vlan(struct nfp_fl_pop_vlan *pop_vlan)
4851
{
4952
size_t act_size = sizeof(struct nfp_fl_pop_vlan);
@@ -235,9 +238,12 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
235238
size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun);
236239
struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action);
237240
u32 tmp_set_ip_tun_type_index = 0;
241+
struct flowi4 flow = {};
238242
/* Currently support one pre-tunnel so index is always 0. */
239243
int pretun_idx = 0;
244+
struct rtable *rt;
240245
struct net *net;
246+
int err;
241247

242248
if (ip_tun->options_len)
243249
return -EOPNOTSUPP;
@@ -254,7 +260,28 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
254260

255261
set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index);
256262
set_tun->tun_id = ip_tun->key.tun_id;
257-
set_tun->ttl = net->ipv4.sysctl_ip_default_ttl;
263+
264+
/* Do a route lookup to determine ttl - if fails then use default.
265+
* Note that CONFIG_INET is a requirement of CONFIG_NET_SWITCHDEV so
266+
* must be defined here.
267+
*/
268+
flow.daddr = ip_tun->key.u.ipv4.dst;
269+
flow.flowi4_proto = IPPROTO_UDP;
270+
rt = ip_route_output_key(net, &flow);
271+
err = PTR_ERR_OR_ZERO(rt);
272+
if (!err) {
273+
set_tun->ttl = ip4_dst_hoplimit(&rt->dst);
274+
ip_rt_put(rt);
275+
} else {
276+
set_tun->ttl = net->ipv4.sysctl_ip_default_ttl;
277+
}
278+
279+
set_tun->tos = ip_tun->key.tos;
280+
281+
if (!(ip_tun->key.tun_flags & TUNNEL_KEY) ||
282+
ip_tun->key.tun_flags & ~NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS)
283+
return -EOPNOTSUPP;
284+
set_tun->tun_flags = ip_tun->key.tun_flags;
258285

259286
/* Complete pre_tunnel action. */
260287
pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst;
@@ -398,8 +425,27 @@ nfp_fl_set_tport(const struct tc_action *action, int idx, u32 off,
398425
return 0;
399426
}
400427

428+
static u32 nfp_fl_csum_l4_to_flag(u8 ip_proto)
429+
{
430+
switch (ip_proto) {
431+
case 0:
432+
/* Filter doesn't force proto match,
433+
* both TCP and UDP will be updated if encountered
434+
*/
435+
return TCA_CSUM_UPDATE_FLAG_TCP | TCA_CSUM_UPDATE_FLAG_UDP;
436+
case IPPROTO_TCP:
437+
return TCA_CSUM_UPDATE_FLAG_TCP;
438+
case IPPROTO_UDP:
439+
return TCA_CSUM_UPDATE_FLAG_UDP;
440+
default:
441+
/* All other protocols will be ignored by FW */
442+
return 0;
443+
}
444+
}
445+
401446
static int
402-
nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
447+
nfp_fl_pedit(const struct tc_action *action, struct tc_cls_flower_offload *flow,
448+
char *nfp_action, int *a_len, u32 *csum_updated)
403449
{
404450
struct nfp_fl_set_ipv6_addr set_ip6_dst, set_ip6_src;
405451
struct nfp_fl_set_ip4_addrs set_ip_addr;
@@ -409,6 +455,7 @@ nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
409455
int idx, nkeys, err;
410456
size_t act_size;
411457
u32 offset, cmd;
458+
u8 ip_proto = 0;
412459

413460
memset(&set_ip6_dst, 0, sizeof(set_ip6_dst));
414461
memset(&set_ip6_src, 0, sizeof(set_ip6_src));
@@ -451,6 +498,15 @@ nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
451498
return err;
452499
}
453500

501+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
502+
struct flow_dissector_key_basic *basic;
503+
504+
basic = skb_flow_dissector_target(flow->dissector,
505+
FLOW_DISSECTOR_KEY_BASIC,
506+
flow->key);
507+
ip_proto = basic->ip_proto;
508+
}
509+
454510
if (set_eth.head.len_lw) {
455511
act_size = sizeof(set_eth);
456512
memcpy(nfp_action, &set_eth, act_size);
@@ -459,6 +515,10 @@ nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
459515
act_size = sizeof(set_ip_addr);
460516
memcpy(nfp_action, &set_ip_addr, act_size);
461517
*a_len += act_size;
518+
519+
/* Hardware will automatically fix IPv4 and TCP/UDP checksum. */
520+
*csum_updated |= TCA_CSUM_UPDATE_FLAG_IPV4HDR |
521+
nfp_fl_csum_l4_to_flag(ip_proto);
462522
} else if (set_ip6_dst.head.len_lw && set_ip6_src.head.len_lw) {
463523
/* TC compiles set src and dst IPv6 address as a single action,
464524
* the hardware requires this to be 2 separate actions.
@@ -471,18 +531,30 @@ nfp_fl_pedit(const struct tc_action *action, char *nfp_action, int *a_len)
471531
memcpy(&nfp_action[sizeof(set_ip6_src)], &set_ip6_dst,
472532
act_size);
473533
*a_len += act_size;
534+
535+
/* Hardware will automatically fix TCP/UDP checksum. */
536+
*csum_updated |= nfp_fl_csum_l4_to_flag(ip_proto);
474537
} else if (set_ip6_dst.head.len_lw) {
475538
act_size = sizeof(set_ip6_dst);
476539
memcpy(nfp_action, &set_ip6_dst, act_size);
477540
*a_len += act_size;
541+
542+
/* Hardware will automatically fix TCP/UDP checksum. */
543+
*csum_updated |= nfp_fl_csum_l4_to_flag(ip_proto);
478544
} else if (set_ip6_src.head.len_lw) {
479545
act_size = sizeof(set_ip6_src);
480546
memcpy(nfp_action, &set_ip6_src, act_size);
481547
*a_len += act_size;
548+
549+
/* Hardware will automatically fix TCP/UDP checksum. */
550+
*csum_updated |= nfp_fl_csum_l4_to_flag(ip_proto);
482551
} else if (set_tport.head.len_lw) {
483552
act_size = sizeof(set_tport);
484553
memcpy(nfp_action, &set_tport, act_size);
485554
*a_len += act_size;
555+
556+
/* Hardware will automatically fix TCP/UDP checksum. */
557+
*csum_updated |= nfp_fl_csum_l4_to_flag(ip_proto);
486558
}
487559

488560
return 0;
@@ -493,12 +565,18 @@ nfp_flower_output_action(struct nfp_app *app, const struct tc_action *a,
493565
struct nfp_fl_payload *nfp_fl, int *a_len,
494566
struct net_device *netdev, bool last,
495567
enum nfp_flower_tun_type *tun_type, int *tun_out_cnt,
496-
int *out_cnt)
568+
int *out_cnt, u32 *csum_updated)
497569
{
498570
struct nfp_flower_priv *priv = app->priv;
499571
struct nfp_fl_output *output;
500572
int err, prelag_size;
501573

574+
/* If csum_updated has not been reset by now, it means HW will
575+
* incorrectly update csums when they are not requested.
576+
*/
577+
if (*csum_updated)
578+
return -EOPNOTSUPP;
579+
502580
if (*a_len + sizeof(struct nfp_fl_output) > NFP_FL_MAX_A_SIZ)
503581
return -EOPNOTSUPP;
504582

@@ -529,10 +607,11 @@ nfp_flower_output_action(struct nfp_app *app, const struct tc_action *a,
529607

530608
static int
531609
nfp_flower_loop_action(struct nfp_app *app, const struct tc_action *a,
610+
struct tc_cls_flower_offload *flow,
532611
struct nfp_fl_payload *nfp_fl, int *a_len,
533612
struct net_device *netdev,
534613
enum nfp_flower_tun_type *tun_type, int *tun_out_cnt,
535-
int *out_cnt)
614+
int *out_cnt, u32 *csum_updated)
536615
{
537616
struct nfp_fl_set_ipv4_udp_tun *set_tun;
538617
struct nfp_fl_pre_tunnel *pre_tun;
@@ -545,14 +624,14 @@ nfp_flower_loop_action(struct nfp_app *app, const struct tc_action *a,
545624
} else if (is_tcf_mirred_egress_redirect(a)) {
546625
err = nfp_flower_output_action(app, a, nfp_fl, a_len, netdev,
547626
true, tun_type, tun_out_cnt,
548-
out_cnt);
627+
out_cnt, csum_updated);
549628
if (err)
550629
return err;
551630

552631
} else if (is_tcf_mirred_egress_mirror(a)) {
553632
err = nfp_flower_output_action(app, a, nfp_fl, a_len, netdev,
554633
false, tun_type, tun_out_cnt,
555-
out_cnt);
634+
out_cnt, csum_updated);
556635
if (err)
557636
return err;
558637

@@ -602,8 +681,17 @@ nfp_flower_loop_action(struct nfp_app *app, const struct tc_action *a,
602681
/* Tunnel decap is handled by default so accept action. */
603682
return 0;
604683
} else if (is_tcf_pedit(a)) {
605-
if (nfp_fl_pedit(a, &nfp_fl->action_data[*a_len], a_len))
684+
if (nfp_fl_pedit(a, flow, &nfp_fl->action_data[*a_len],
685+
a_len, csum_updated))
686+
return -EOPNOTSUPP;
687+
} else if (is_tcf_csum(a)) {
688+
/* csum action requests recalc of something we have not fixed */
689+
if (tcf_csum_update_flags(a) & ~*csum_updated)
606690
return -EOPNOTSUPP;
691+
/* If we will correctly fix the csum we can remove it from the
692+
* csum update list. Which will later be used to check support.
693+
*/
694+
*csum_updated &= ~tcf_csum_update_flags(a);
607695
} else {
608696
/* Currently we do not handle any other actions. */
609697
return -EOPNOTSUPP;
@@ -620,6 +708,7 @@ int nfp_flower_compile_action(struct nfp_app *app,
620708
int act_len, act_cnt, err, tun_out_cnt, out_cnt;
621709
enum nfp_flower_tun_type tun_type;
622710
const struct tc_action *a;
711+
u32 csum_updated = 0;
623712
LIST_HEAD(actions);
624713

625714
memset(nfp_flow->action_data, 0, NFP_FL_MAX_A_SIZ);
@@ -632,8 +721,9 @@ int nfp_flower_compile_action(struct nfp_app *app,
632721

633722
tcf_exts_to_list(flow->exts, &actions);
634723
list_for_each_entry(a, &actions, list) {
635-
err = nfp_flower_loop_action(app, a, nfp_flow, &act_len, netdev,
636-
&tun_type, &tun_out_cnt, &out_cnt);
724+
err = nfp_flower_loop_action(app, a, flow, nfp_flow, &act_len,
725+
netdev, &tun_type, &tun_out_cnt,
726+
&out_cnt, &csum_updated);
637727
if (err)
638728
return err;
639729
act_cnt++;

drivers/net/ethernet/netronome/nfp/flower/cmsg.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ struct nfp_fl_set_ipv4_udp_tun {
203203
__be16 reserved;
204204
__be64 tun_id __packed;
205205
__be32 tun_type_index;
206-
__be16 reserved2;
206+
__be16 tun_flags;
207207
u8 ttl;
208-
u8 reserved3;
208+
u8 tos;
209209
__be32 extra[2];
210210
};
211211

drivers/net/ethernet/netronome/nfp/flower/lag_conf.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,9 @@ nfp_fl_lag_changeupper_event(struct nfp_fl_lag *lag,
564564
if (lag_upper_info &&
565565
lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_ACTIVEBACKUP &&
566566
(lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH ||
567-
(lag_upper_info->hash_type != NETDEV_LAG_HASH_L34 &&
568-
lag_upper_info->hash_type != NETDEV_LAG_HASH_E34))) {
567+
(lag_upper_info->hash_type != NETDEV_LAG_HASH_L34 &&
568+
lag_upper_info->hash_type != NETDEV_LAG_HASH_E34 &&
569+
lag_upper_info->hash_type != NETDEV_LAG_HASH_UNKNOWN))) {
569570
can_offload = false;
570571
nfp_flower_cmsg_warn(priv->app,
571572
"Unable to offload tx_type %u hash %u\n",

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -945,11 +945,12 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
945945

946946
/**
947947
* nfp_net_tx_complete() - Handled completed TX packets
948-
* @tx_ring: TX ring structure
948+
* @tx_ring: TX ring structure
949+
* @budget: NAPI budget (only used as bool to determine if in NAPI context)
949950
*
950951
* Return: Number of completed TX descriptors
951952
*/
952-
static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring)
953+
static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring, int budget)
953954
{
954955
struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
955956
struct nfp_net_dp *dp = &r_vec->nfp_net->dp;
@@ -999,7 +1000,7 @@ static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring)
9991000

10001001
/* check for last gather fragment */
10011002
if (fidx == nr_frags - 1)
1002-
dev_consume_skb_any(skb);
1003+
napi_consume_skb(skb, budget);
10031004

10041005
tx_ring->txbufs[idx].dma_addr = 0;
10051006
tx_ring->txbufs[idx].skb = NULL;
@@ -1828,7 +1829,7 @@ static int nfp_net_poll(struct napi_struct *napi, int budget)
18281829
unsigned int pkts_polled = 0;
18291830

18301831
if (r_vec->tx_ring)
1831-
nfp_net_tx_complete(r_vec->tx_ring);
1832+
nfp_net_tx_complete(r_vec->tx_ring, budget);
18321833
if (r_vec->rx_ring)
18331834
pkts_polled = nfp_net_rx(r_vec->rx_ring, budget);
18341835

@@ -2062,7 +2063,7 @@ static void nfp_ctrl_poll(unsigned long arg)
20622063
struct nfp_net_r_vector *r_vec = (void *)arg;
20632064

20642065
spin_lock_bh(&r_vec->lock);
2065-
nfp_net_tx_complete(r_vec->tx_ring);
2066+
nfp_net_tx_complete(r_vec->tx_ring, 0);
20662067
__nfp_ctrl_tx_queued(r_vec);
20672068
spin_unlock_bh(&r_vec->lock);
20682069

@@ -3115,6 +3116,21 @@ nfp_net_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
31153116
return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL);
31163117
}
31173118

3119+
#ifdef CONFIG_NET_POLL_CONTROLLER
3120+
static void nfp_net_netpoll(struct net_device *netdev)
3121+
{
3122+
struct nfp_net *nn = netdev_priv(netdev);
3123+
int i;
3124+
3125+
/* nfp_net's NAPIs are statically allocated so even if there is a race
3126+
* with reconfig path this will simply try to schedule some disabled
3127+
* NAPI instances.
3128+
*/
3129+
for (i = 0; i < nn->dp.num_stack_tx_rings; i++)
3130+
napi_schedule_irqoff(&nn->r_vecs[i].napi);
3131+
}
3132+
#endif
3133+
31183134
static void nfp_net_stat64(struct net_device *netdev,
31193135
struct rtnl_link_stats64 *stats)
31203136
{
@@ -3482,6 +3498,9 @@ const struct net_device_ops nfp_net_netdev_ops = {
34823498
.ndo_get_stats64 = nfp_net_stat64,
34833499
.ndo_vlan_rx_add_vid = nfp_net_vlan_rx_add_vid,
34843500
.ndo_vlan_rx_kill_vid = nfp_net_vlan_rx_kill_vid,
3501+
#ifdef CONFIG_NET_POLL_CONTROLLER
3502+
.ndo_poll_controller = nfp_net_netpoll,
3503+
#endif
34853504
.ndo_set_vf_mac = nfp_app_set_vf_mac,
34863505
.ndo_set_vf_vlan = nfp_app_set_vf_vlan,
34873506
.ndo_set_vf_spoofchk = nfp_app_set_vf_spoofchk,

0 commit comments

Comments
 (0)