Skip to content

Commit a21d082

Browse files
etantilovJeff Kirsher
authored andcommitted
ixgbe: add support for geneve Rx offload
Add geneve Rx offload support for x550em_a. The implementation follows the vxlan code with the lower 16 bits of the VXLANCTRL register holding the UDP port for VXLAN and the upper for Geneve. Disabled NFS filters in the RFCTL register which allows us to simplify the check for VXLAN and Geneve packets in ixgbe_rx_checksum(). Removed vxlan from the name of the callback functions and replaced it with udp_tunnel which is more in line with the new API. Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
1 parent c642697 commit a21d082

File tree

3 files changed

+134
-51
lines changed

3 files changed

+134
-51
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ struct ixgbe_adapter {
645645
#define IXGBE_FLAG_RX_HWTSTAMP_ENABLED BIT(25)
646646
#define IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER BIT(26)
647647
#define IXGBE_FLAG_DCB_CAPABLE BIT(27)
648+
#define IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE BIT(28)
648649

649650
u32 flags2;
650651
#define IXGBE_FLAG2_RSC_CAPABLE BIT(0)
@@ -658,7 +659,7 @@ struct ixgbe_adapter {
658659
#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP BIT(9)
659660
#define IXGBE_FLAG2_PTP_PPS_ENABLED BIT(10)
660661
#define IXGBE_FLAG2_PHY_INTERRUPT BIT(11)
661-
#define IXGBE_FLAG2_VXLAN_REREG_NEEDED BIT(12)
662+
#define IXGBE_FLAG2_UDP_TUN_REREG_NEEDED BIT(12)
662663
#define IXGBE_FLAG2_VLAN_PROMISC BIT(13)
663664

664665
/* Tx fast path data */
@@ -672,6 +673,7 @@ struct ixgbe_adapter {
672673

673674
/* Port number used to identify VXLAN traffic */
674675
__be16 vxlan_port;
676+
__be16 geneve_port;
675677

676678
/* TX */
677679
struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp;

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 124 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,6 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
14951495
struct sk_buff *skb)
14961496
{
14971497
__le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
1498-
__le16 hdr_info = rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
14991498
bool encap_pkt = false;
15001499

15011500
skb_checksum_none_assert(skb);
@@ -1504,8 +1503,8 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
15041503
if (!(ring->netdev->features & NETIF_F_RXCSUM))
15051504
return;
15061505

1507-
if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) &&
1508-
(hdr_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_TUNNEL >> 16))) {
1506+
/* check for VXLAN and Geneve packets */
1507+
if (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) {
15091508
encap_pkt = true;
15101509
skb->encapsulation = 1;
15111510
}
@@ -3922,6 +3921,9 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
39223921
rfctl &= ~IXGBE_RFCTL_RSC_DIS;
39233922
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
39243923
rfctl |= IXGBE_RFCTL_RSC_DIS;
3924+
3925+
/* disable NFS filtering */
3926+
rfctl |= (IXGBE_RFCTL_NFSW_DIS | IXGBE_RFCTL_NFSR_DIS);
39253927
IXGBE_WRITE_REG(hw, IXGBE_RFCTL, rfctl);
39263928

39273929
/* Program registers for the distribution of queues */
@@ -4586,18 +4588,23 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
45864588
}
45874589
}
45884590

4589-
static void ixgbe_clear_vxlan_port(struct ixgbe_adapter *adapter)
4591+
static void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask)
45904592
{
4591-
switch (adapter->hw.mac.type) {
4592-
case ixgbe_mac_X550:
4593-
case ixgbe_mac_X550EM_x:
4594-
case ixgbe_mac_x550em_a:
4595-
IXGBE_WRITE_REG(&adapter->hw, IXGBE_VXLANCTRL, 0);
4593+
struct ixgbe_hw *hw = &adapter->hw;
4594+
u32 vxlanctrl;
4595+
4596+
if (!(adapter->flags & (IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE |
4597+
IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)))
4598+
return;
4599+
4600+
vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) && ~mask;
4601+
IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl);
4602+
4603+
if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK)
45964604
adapter->vxlan_port = 0;
4597-
break;
4598-
default:
4599-
break;
4600-
}
4605+
4606+
if (mask & IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK)
4607+
adapter->geneve_port = 0;
46014608
}
46024609

46034610
#ifdef CONFIG_IXGBE_DCB
@@ -5711,8 +5718,10 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
57115718
if (fwsm & IXGBE_FWSM_TS_ENABLED)
57125719
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
57135720
break;
5714-
case ixgbe_mac_X550EM_x:
57155721
case ixgbe_mac_x550em_a:
5722+
adapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE;
5723+
/* fall through */
5724+
case ixgbe_mac_X550EM_x:
57165725
#ifdef CONFIG_IXGBE_DCB
57175726
adapter->flags &= ~IXGBE_FLAG_DCB_CAPABLE;
57185727
#endif
@@ -6144,7 +6153,7 @@ int ixgbe_open(struct net_device *netdev)
61446153

61456154
ixgbe_up_complete(adapter);
61466155

6147-
ixgbe_clear_vxlan_port(adapter);
6156+
ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK);
61486157
udp_tunnel_get_rx_info(netdev);
61496158

61506159
return 0;
@@ -7223,9 +7232,9 @@ static void ixgbe_service_task(struct work_struct *work)
72237232
ixgbe_service_event_complete(adapter);
72247233
return;
72257234
}
7226-
if (adapter->flags2 & IXGBE_FLAG2_VXLAN_REREG_NEEDED) {
7235+
if (adapter->flags2 & IXGBE_FLAG2_UDP_TUN_REREG_NEEDED) {
72277236
rtnl_lock();
7228-
adapter->flags2 &= ~IXGBE_FLAG2_VXLAN_REREG_NEEDED;
7237+
adapter->flags2 &= ~IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
72297238
udp_tunnel_get_rx_info(adapter->netdev);
72307239
rtnl_unlock();
72317240
}
@@ -7665,6 +7674,10 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
76657674
if (adapter->vxlan_port &&
76667675
udp_hdr(skb)->dest == adapter->vxlan_port)
76677676
hdr.network = skb_inner_network_header(skb);
7677+
7678+
if (adapter->geneve_port &&
7679+
udp_hdr(skb)->dest == adapter->geneve_port)
7680+
hdr.network = skb_inner_network_header(skb);
76687681
}
76697682

76707683
/* Currently only IPv4/IPv6 with TCP is supported */
@@ -8800,10 +8813,23 @@ static int ixgbe_set_features(struct net_device *netdev,
88008813
netdev->features = features;
88018814

88028815
if ((adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) {
8803-
if (features & NETIF_F_RXCSUM)
8804-
adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
8805-
else
8806-
ixgbe_clear_vxlan_port(adapter);
8816+
if (features & NETIF_F_RXCSUM) {
8817+
adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
8818+
} else {
8819+
u32 port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
8820+
8821+
ixgbe_clear_udp_tunnel_port(adapter, port_mask);
8822+
}
8823+
}
8824+
8825+
if ((adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)) {
8826+
if (features & NETIF_F_RXCSUM) {
8827+
adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
8828+
} else {
8829+
u32 port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
8830+
8831+
ixgbe_clear_udp_tunnel_port(adapter, port_mask);
8832+
}
88078833
}
88088834

88098835
if (need_reset)
@@ -8816,67 +8842,115 @@ static int ixgbe_set_features(struct net_device *netdev,
88168842
}
88178843

88188844
/**
8819-
* ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up
8845+
* ixgbe_add_udp_tunnel_port - Get notifications about adding UDP tunnel ports
88208846
* @dev: The port's netdev
88218847
* @ti: Tunnel endpoint information
88228848
**/
8823-
static void ixgbe_add_vxlan_port(struct net_device *dev,
8824-
struct udp_tunnel_info *ti)
8849+
static void ixgbe_add_udp_tunnel_port(struct net_device *dev,
8850+
struct udp_tunnel_info *ti)
88258851
{
88268852
struct ixgbe_adapter *adapter = netdev_priv(dev);
88278853
struct ixgbe_hw *hw = &adapter->hw;
88288854
__be16 port = ti->port;
8829-
8830-
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
8831-
return;
8855+
u32 port_shift = 0;
8856+
u32 reg;
88328857

88338858
if (ti->sa_family != AF_INET)
88348859
return;
88358860

8836-
if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
8837-
return;
8861+
switch (ti->type) {
8862+
case UDP_TUNNEL_TYPE_VXLAN:
8863+
if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
8864+
return;
88388865

8839-
if (adapter->vxlan_port == port)
8840-
return;
8866+
if (adapter->vxlan_port == port)
8867+
return;
8868+
8869+
if (adapter->vxlan_port) {
8870+
netdev_info(dev,
8871+
"VXLAN port %d set, not adding port %d\n",
8872+
ntohs(adapter->vxlan_port),
8873+
ntohs(port));
8874+
return;
8875+
}
8876+
8877+
adapter->vxlan_port = port;
8878+
break;
8879+
case UDP_TUNNEL_TYPE_GENEVE:
8880+
if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
8881+
return;
8882+
8883+
if (adapter->geneve_port == port)
8884+
return;
8885+
8886+
if (adapter->geneve_port) {
8887+
netdev_info(dev,
8888+
"GENEVE port %d set, not adding port %d\n",
8889+
ntohs(adapter->geneve_port),
8890+
ntohs(port));
8891+
return;
8892+
}
88418893

8842-
if (adapter->vxlan_port) {
8843-
netdev_info(dev,
8844-
"Hit Max num of VXLAN ports, not adding port %d\n",
8845-
ntohs(port));
8894+
port_shift = IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT;
8895+
adapter->geneve_port = port;
8896+
break;
8897+
default:
88468898
return;
88478899
}
88488900

8849-
adapter->vxlan_port = port;
8850-
IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, ntohs(port));
8901+
reg = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) | ntohs(port) << port_shift;
8902+
IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, reg);
88518903
}
88528904

88538905
/**
8854-
* ixgbe_del_vxlan_port - Get notifications about VXLAN ports that go away
8906+
* ixgbe_del_udp_tunnel_port - Get notifications about removing UDP tunnel ports
88558907
* @dev: The port's netdev
88568908
* @ti: Tunnel endpoint information
88578909
**/
8858-
static void ixgbe_del_vxlan_port(struct net_device *dev,
8859-
struct udp_tunnel_info *ti)
8910+
static void ixgbe_del_udp_tunnel_port(struct net_device *dev,
8911+
struct udp_tunnel_info *ti)
88608912
{
88618913
struct ixgbe_adapter *adapter = netdev_priv(dev);
8914+
u32 port_mask;
88628915

8863-
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
8916+
if (ti->type != UDP_TUNNEL_TYPE_VXLAN &&
8917+
ti->type != UDP_TUNNEL_TYPE_GENEVE)
88648918
return;
88658919

88668920
if (ti->sa_family != AF_INET)
88678921
return;
88688922

8869-
if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
8870-
return;
8923+
switch (ti->type) {
8924+
case UDP_TUNNEL_TYPE_VXLAN:
8925+
if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
8926+
return;
88718927

8872-
if (adapter->vxlan_port != ti->port) {
8873-
netdev_info(dev, "Port %d was not found, not deleting\n",
8874-
ntohs(ti->port));
8928+
if (adapter->vxlan_port != ti->port) {
8929+
netdev_info(dev, "VXLAN port %d not found\n",
8930+
ntohs(ti->port));
8931+
return;
8932+
}
8933+
8934+
port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
8935+
break;
8936+
case UDP_TUNNEL_TYPE_GENEVE:
8937+
if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
8938+
return;
8939+
8940+
if (adapter->geneve_port != ti->port) {
8941+
netdev_info(dev, "GENEVE port %d not found\n",
8942+
ntohs(ti->port));
8943+
return;
8944+
}
8945+
8946+
port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
8947+
break;
8948+
default:
88758949
return;
88768950
}
88778951

8878-
ixgbe_clear_vxlan_port(adapter);
8879-
adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
8952+
ixgbe_clear_udp_tunnel_port(adapter, port_mask);
8953+
adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
88808954
}
88818955

88828956
static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
@@ -9190,8 +9264,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
91909264
.ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
91919265
.ndo_dfwd_add_station = ixgbe_fwd_add,
91929266
.ndo_dfwd_del_station = ixgbe_fwd_del,
9193-
.ndo_udp_tunnel_add = ixgbe_add_vxlan_port,
9194-
.ndo_udp_tunnel_del = ixgbe_del_vxlan_port,
9267+
.ndo_udp_tunnel_add = ixgbe_add_udp_tunnel_port,
9268+
.ndo_udp_tunnel_del = ixgbe_del_udp_tunnel_port,
91959269
.ndo_features_check = ixgbe_features_check,
91969270
};
91979271

drivers/net/ethernet/intel/ixgbe/ixgbe_type.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,13 @@ struct ixgbe_thermal_sensor_data {
487487
#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) /* Ext Flexible Host
488488
* Filter Table */
489489

490+
/* masks for accessing VXLAN and GENEVE UDP ports */
491+
#define IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK 0x0000ffff /* VXLAN port */
492+
#define IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK 0xffff0000 /* GENEVE port */
493+
#define IXGBE_VXLANCTRL_ALL_UDPPORT_MASK 0xffffffff /* GENEVE/VXLAN */
494+
495+
#define IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT 16
496+
490497
#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
491498
#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
492499

0 commit comments

Comments
 (0)