Commit a1980cc9 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
parents 84ee6e50 3b05aa99
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -3000,6 +3000,33 @@ netdev_features_t wx_fix_features(struct net_device *netdev,
}
EXPORT_SYMBOL(wx_fix_features);

#define WX_MAX_TUNNEL_HDR_LEN	80
netdev_features_t wx_features_check(struct sk_buff *skb,
				    struct net_device *netdev,
				    netdev_features_t features)
{
	struct wx *wx = netdev_priv(netdev);

	if (!skb->encapsulation)
		return features;

	if (wx->mac.type == wx_mac_em)
		return features & ~NETIF_F_CSUM_MASK;

	if (unlikely(skb_inner_mac_header(skb) - skb_transport_header(skb) >
		     WX_MAX_TUNNEL_HDR_LEN))
		return features & ~NETIF_F_CSUM_MASK;

	if (skb->inner_protocol_type == ENCAP_TYPE_ETHER &&
	    skb->inner_protocol != htons(ETH_P_IP) &&
	    skb->inner_protocol != htons(ETH_P_IPV6) &&
	    skb->inner_protocol != htons(ETH_P_TEB))
		return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);

	return features;
}
EXPORT_SYMBOL(wx_features_check);

void wx_set_ring(struct wx *wx, u32 new_tx_count,
		 u32 new_rx_count, struct wx_ring *temp_ring)
{
+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@ void wx_get_stats64(struct net_device *netdev,
int wx_set_features(struct net_device *netdev, netdev_features_t features);
netdev_features_t wx_fix_features(struct net_device *netdev,
				  netdev_features_t features);
netdev_features_t wx_features_check(struct sk_buff *skb,
				    struct net_device *netdev,
				    netdev_features_t features);
void wx_set_ring(struct wx *wx, u32 new_tx_count,
		 u32 new_rx_count, struct wx_ring *temp_ring);

+1 −0
Original line number Diff line number Diff line
@@ -587,6 +587,7 @@ static const struct net_device_ops ngbe_netdev_ops = {
	.ndo_set_rx_mode        = wx_set_rx_mode,
	.ndo_set_features       = wx_set_features,
	.ndo_fix_features       = wx_fix_features,
	.ndo_features_check     = wx_features_check,
	.ndo_validate_addr      = eth_validate_addr,
	.ndo_set_mac_address    = wx_set_mac,
	.ndo_get_stats64        = wx_get_stats64,
+37 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/string.h>
#include <linux/etherdevice.h>
#include <linux/phylink.h>
#include <net/udp_tunnel.h>
#include <net/ip.h>
#include <linux/if_vlan.h>

@@ -537,6 +538,39 @@ void txgbe_do_reset(struct net_device *netdev)
		txgbe_reset(wx);
}

static int txgbe_udp_tunnel_sync(struct net_device *dev, unsigned int table)
{
	struct wx *wx = netdev_priv(dev);
	struct udp_tunnel_info ti;

	udp_tunnel_nic_get_port(dev, table, 0, &ti);
	switch (ti.type) {
	case UDP_TUNNEL_TYPE_VXLAN:
		wr32(wx, TXGBE_CFG_VXLAN, ntohs(ti.port));
		break;
	case UDP_TUNNEL_TYPE_VXLAN_GPE:
		wr32(wx, TXGBE_CFG_VXLAN_GPE, ntohs(ti.port));
		break;
	case UDP_TUNNEL_TYPE_GENEVE:
		wr32(wx, TXGBE_CFG_GENEVE, ntohs(ti.port));
		break;
	default:
		break;
	}

	return 0;
}

static const struct udp_tunnel_nic_info txgbe_udp_tunnels = {
	.sync_table	= txgbe_udp_tunnel_sync,
	.flags		= UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
	.tables		= {
		{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
		{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN_GPE, },
		{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
	},
};

static const struct net_device_ops txgbe_netdev_ops = {
	.ndo_open               = txgbe_open,
	.ndo_stop               = txgbe_close,
@@ -545,6 +579,7 @@ static const struct net_device_ops txgbe_netdev_ops = {
	.ndo_set_rx_mode        = wx_set_rx_mode,
	.ndo_set_features       = wx_set_features,
	.ndo_fix_features       = wx_fix_features,
	.ndo_features_check     = wx_features_check,
	.ndo_validate_addr      = eth_validate_addr,
	.ndo_set_mac_address    = wx_set_mac,
	.ndo_get_stats64        = wx_get_stats64,
@@ -632,6 +667,7 @@ static int txgbe_probe(struct pci_dev *pdev,
	wx->driver_name = txgbe_driver_name;
	txgbe_set_ethtool_ops(netdev);
	netdev->netdev_ops = &txgbe_netdev_ops;
	netdev->udp_tunnel_nic_info = &txgbe_udp_tunnels;

	/* setup the private structure */
	err = txgbe_sw_init(wx);
@@ -677,6 +713,7 @@ static int txgbe_probe(struct pci_dev *pdev,
	netdev->features |= NETIF_F_HIGHDMA;
	netdev->hw_features |= NETIF_F_GRO;
	netdev->features |= NETIF_F_GRO;
	netdev->features |= NETIF_F_RX_UDP_TUNNEL_PORT;

	netdev->priv_flags |= IFF_UNICAST_FLT;
	netdev->priv_flags |= IFF_SUPP_NOFCS;
+3 −0
Original line number Diff line number Diff line
@@ -88,6 +88,9 @@
/* Port cfg registers */
#define TXGBE_CFG_PORT_ST                       0x14404
#define TXGBE_CFG_PORT_ST_LINK_UP               BIT(0)
#define TXGBE_CFG_VXLAN                         0x14410
#define TXGBE_CFG_VXLAN_GPE                     0x14414
#define TXGBE_CFG_GENEVE                        0x14418

/* I2C registers */
#define TXGBE_I2C_BASE                          0x14900