Commit 1698d600 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Implement .ndo_features_check().

For UDP encapsultions, we only support the offloaded Vxlan port and
Geneve port.  All other ports included FOU and GUE are not supported so
we need to turn off TSO and checksum features.

v2: Reverse the check for supported UDP ports to be more straight forward.
Reviewed-by: default avatarSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: default avatarEdwin Peer <edwin.peer@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dade5e15
...@@ -10781,6 +10781,40 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features) ...@@ -10781,6 +10781,40 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
return rc; return rc;
} }
static netdev_features_t bnxt_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
struct bnxt *bp;
__be16 udp_port;
u8 l4_proto = 0;
features = vlan_features_check(skb, features);
if (!skb->encapsulation)
return features;
switch (vlan_get_protocol(skb)) {
case htons(ETH_P_IP):
l4_proto = ip_hdr(skb)->protocol;
break;
case htons(ETH_P_IPV6):
l4_proto = ipv6_hdr(skb)->nexthdr;
break;
default:
return features;
}
if (l4_proto != IPPROTO_UDP)
return features;
bp = netdev_priv(dev);
/* For UDP, we can only handle 1 Vxlan port and 1 Geneve port. */
udp_port = udp_hdr(skb)->dest;
if (udp_port == bp->vxlan_port || udp_port == bp->nge_port)
return features;
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}
int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words, int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
u32 *reg_buf) u32 *reg_buf)
{ {
...@@ -12288,10 +12322,13 @@ static int bnxt_udp_tunnel_sync(struct net_device *netdev, unsigned int table) ...@@ -12288,10 +12322,13 @@ static int bnxt_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
unsigned int cmd; unsigned int cmd;
udp_tunnel_nic_get_port(netdev, table, 0, &ti); udp_tunnel_nic_get_port(netdev, table, 0, &ti);
if (ti.type == UDP_TUNNEL_TYPE_VXLAN) if (ti.type == UDP_TUNNEL_TYPE_VXLAN) {
bp->vxlan_port = ti.port;
cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN; cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN;
else } else {
bp->nge_port = ti.port;
cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE; cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE;
}
if (ti.port) if (ti.port)
return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti.port, cmd); return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti.port, cmd);
...@@ -12391,6 +12428,7 @@ static const struct net_device_ops bnxt_netdev_ops = { ...@@ -12391,6 +12428,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_change_mtu = bnxt_change_mtu, .ndo_change_mtu = bnxt_change_mtu,
.ndo_fix_features = bnxt_fix_features, .ndo_fix_features = bnxt_fix_features,
.ndo_set_features = bnxt_set_features, .ndo_set_features = bnxt_set_features,
.ndo_features_check = bnxt_features_check,
.ndo_tx_timeout = bnxt_tx_timeout, .ndo_tx_timeout = bnxt_tx_timeout,
#ifdef CONFIG_BNXT_SRIOV #ifdef CONFIG_BNXT_SRIOV
.ndo_get_vf_config = bnxt_get_vf_config, .ndo_get_vf_config = bnxt_get_vf_config,
......
...@@ -1914,6 +1914,8 @@ struct bnxt { ...@@ -1914,6 +1914,8 @@ struct bnxt {
u16 vxlan_fw_dst_port_id; u16 vxlan_fw_dst_port_id;
u16 nge_fw_dst_port_id; u16 nge_fw_dst_port_id;
__be16 vxlan_port;
__be16 nge_port;
u8 port_partition_type; u8 port_partition_type;
u8 port_count; u8 port_count;
u16 br_mode; u16 br_mode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment