|
@@ -1495,7 +1495,6 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
|
|
struct sk_buff *skb)
|
|
struct sk_buff *skb)
|
|
{
|
|
{
|
|
__le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
|
|
__le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
|
|
- __le16 hdr_info = rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
|
|
|
|
bool encap_pkt = false;
|
|
bool encap_pkt = false;
|
|
|
|
|
|
skb_checksum_none_assert(skb);
|
|
skb_checksum_none_assert(skb);
|
|
@@ -1504,8 +1503,8 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
|
|
if (!(ring->netdev->features & NETIF_F_RXCSUM))
|
|
if (!(ring->netdev->features & NETIF_F_RXCSUM))
|
|
return;
|
|
return;
|
|
|
|
|
|
- if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) &&
|
|
|
|
- (hdr_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_TUNNEL >> 16))) {
|
|
|
|
|
|
+ /* check for VXLAN and Geneve packets */
|
|
|
|
+ if (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) {
|
|
encap_pkt = true;
|
|
encap_pkt = true;
|
|
skb->encapsulation = 1;
|
|
skb->encapsulation = 1;
|
|
}
|
|
}
|
|
@@ -3922,6 +3921,9 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
|
|
rfctl &= ~IXGBE_RFCTL_RSC_DIS;
|
|
rfctl &= ~IXGBE_RFCTL_RSC_DIS;
|
|
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
|
|
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
|
|
rfctl |= IXGBE_RFCTL_RSC_DIS;
|
|
rfctl |= IXGBE_RFCTL_RSC_DIS;
|
|
|
|
+
|
|
|
|
+ /* disable NFS filtering */
|
|
|
|
+ rfctl |= (IXGBE_RFCTL_NFSW_DIS | IXGBE_RFCTL_NFSR_DIS);
|
|
IXGBE_WRITE_REG(hw, IXGBE_RFCTL, rfctl);
|
|
IXGBE_WRITE_REG(hw, IXGBE_RFCTL, rfctl);
|
|
|
|
|
|
/* Program registers for the distribution of queues */
|
|
/* Program registers for the distribution of queues */
|
|
@@ -4586,18 +4588,23 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void ixgbe_clear_vxlan_port(struct ixgbe_adapter *adapter)
|
|
|
|
|
|
+static void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask)
|
|
{
|
|
{
|
|
- switch (adapter->hw.mac.type) {
|
|
|
|
- case ixgbe_mac_X550:
|
|
|
|
- case ixgbe_mac_X550EM_x:
|
|
|
|
- case ixgbe_mac_x550em_a:
|
|
|
|
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_VXLANCTRL, 0);
|
|
|
|
|
|
+ struct ixgbe_hw *hw = &adapter->hw;
|
|
|
|
+ u32 vxlanctrl;
|
|
|
|
+
|
|
|
|
+ if (!(adapter->flags & (IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE |
|
|
|
|
+ IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) && ~mask;
|
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl);
|
|
|
|
+
|
|
|
|
+ if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK)
|
|
adapter->vxlan_port = 0;
|
|
adapter->vxlan_port = 0;
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ if (mask & IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK)
|
|
|
|
+ adapter->geneve_port = 0;
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_IXGBE_DCB
|
|
#ifdef CONFIG_IXGBE_DCB
|
|
@@ -5711,8 +5718,10 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
|
|
if (fwsm & IXGBE_FWSM_TS_ENABLED)
|
|
if (fwsm & IXGBE_FWSM_TS_ENABLED)
|
|
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
|
|
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
|
|
break;
|
|
break;
|
|
- case ixgbe_mac_X550EM_x:
|
|
|
|
case ixgbe_mac_x550em_a:
|
|
case ixgbe_mac_x550em_a:
|
|
|
|
+ adapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE;
|
|
|
|
+ /* fall through */
|
|
|
|
+ case ixgbe_mac_X550EM_x:
|
|
#ifdef CONFIG_IXGBE_DCB
|
|
#ifdef CONFIG_IXGBE_DCB
|
|
adapter->flags &= ~IXGBE_FLAG_DCB_CAPABLE;
|
|
adapter->flags &= ~IXGBE_FLAG_DCB_CAPABLE;
|
|
#endif
|
|
#endif
|
|
@@ -6144,7 +6153,7 @@ int ixgbe_open(struct net_device *netdev)
|
|
|
|
|
|
ixgbe_up_complete(adapter);
|
|
ixgbe_up_complete(adapter);
|
|
|
|
|
|
- ixgbe_clear_vxlan_port(adapter);
|
|
|
|
|
|
+ ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK);
|
|
udp_tunnel_get_rx_info(netdev);
|
|
udp_tunnel_get_rx_info(netdev);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -7223,9 +7232,9 @@ static void ixgbe_service_task(struct work_struct *work)
|
|
ixgbe_service_event_complete(adapter);
|
|
ixgbe_service_event_complete(adapter);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (adapter->flags2 & IXGBE_FLAG2_VXLAN_REREG_NEEDED) {
|
|
|
|
|
|
+ if (adapter->flags2 & IXGBE_FLAG2_UDP_TUN_REREG_NEEDED) {
|
|
rtnl_lock();
|
|
rtnl_lock();
|
|
- adapter->flags2 &= ~IXGBE_FLAG2_VXLAN_REREG_NEEDED;
|
|
|
|
|
|
+ adapter->flags2 &= ~IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
|
|
udp_tunnel_get_rx_info(adapter->netdev);
|
|
udp_tunnel_get_rx_info(adapter->netdev);
|
|
rtnl_unlock();
|
|
rtnl_unlock();
|
|
}
|
|
}
|
|
@@ -7665,6 +7674,10 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
|
|
if (adapter->vxlan_port &&
|
|
if (adapter->vxlan_port &&
|
|
udp_hdr(skb)->dest == adapter->vxlan_port)
|
|
udp_hdr(skb)->dest == adapter->vxlan_port)
|
|
hdr.network = skb_inner_network_header(skb);
|
|
hdr.network = skb_inner_network_header(skb);
|
|
|
|
+
|
|
|
|
+ if (adapter->geneve_port &&
|
|
|
|
+ udp_hdr(skb)->dest == adapter->geneve_port)
|
|
|
|
+ hdr.network = skb_inner_network_header(skb);
|
|
}
|
|
}
|
|
|
|
|
|
/* Currently only IPv4/IPv6 with TCP is supported */
|
|
/* Currently only IPv4/IPv6 with TCP is supported */
|
|
@@ -8800,10 +8813,23 @@ static int ixgbe_set_features(struct net_device *netdev,
|
|
netdev->features = features;
|
|
netdev->features = features;
|
|
|
|
|
|
if ((adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) {
|
|
if ((adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) {
|
|
- if (features & NETIF_F_RXCSUM)
|
|
|
|
- adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
|
|
|
|
- else
|
|
|
|
- ixgbe_clear_vxlan_port(adapter);
|
|
|
|
|
|
+ if (features & NETIF_F_RXCSUM) {
|
|
|
|
+ adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
|
|
|
|
+ } else {
|
|
|
|
+ u32 port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
|
|
|
|
+
|
|
|
|
+ ixgbe_clear_udp_tunnel_port(adapter, port_mask);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)) {
|
|
|
|
+ if (features & NETIF_F_RXCSUM) {
|
|
|
|
+ adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
|
|
|
|
+ } else {
|
|
|
|
+ u32 port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
|
|
|
|
+
|
|
|
|
+ ixgbe_clear_udp_tunnel_port(adapter, port_mask);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (need_reset)
|
|
if (need_reset)
|
|
@@ -8816,67 +8842,115 @@ static int ixgbe_set_features(struct net_device *netdev,
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up
|
|
|
|
|
|
+ * ixgbe_add_udp_tunnel_port - Get notifications about adding UDP tunnel ports
|
|
* @dev: The port's netdev
|
|
* @dev: The port's netdev
|
|
* @ti: Tunnel endpoint information
|
|
* @ti: Tunnel endpoint information
|
|
**/
|
|
**/
|
|
-static void ixgbe_add_vxlan_port(struct net_device *dev,
|
|
|
|
- struct udp_tunnel_info *ti)
|
|
|
|
|
|
+static void ixgbe_add_udp_tunnel_port(struct net_device *dev,
|
|
|
|
+ struct udp_tunnel_info *ti)
|
|
{
|
|
{
|
|
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
|
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
__be16 port = ti->port;
|
|
__be16 port = ti->port;
|
|
-
|
|
|
|
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
|
|
|
|
- return;
|
|
|
|
|
|
+ u32 port_shift = 0;
|
|
|
|
+ u32 reg;
|
|
|
|
|
|
if (ti->sa_family != AF_INET)
|
|
if (ti->sa_family != AF_INET)
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
|
|
|
|
- return;
|
|
|
|
|
|
+ switch (ti->type) {
|
|
|
|
+ case UDP_TUNNEL_TYPE_VXLAN:
|
|
|
|
+ if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
|
|
|
|
+ return;
|
|
|
|
|
|
- if (adapter->vxlan_port == port)
|
|
|
|
- return;
|
|
|
|
|
|
+ if (adapter->vxlan_port == port)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (adapter->vxlan_port) {
|
|
|
|
+ netdev_info(dev,
|
|
|
|
+ "VXLAN port %d set, not adding port %d\n",
|
|
|
|
+ ntohs(adapter->vxlan_port),
|
|
|
|
+ ntohs(port));
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ adapter->vxlan_port = port;
|
|
|
|
+ break;
|
|
|
|
+ case UDP_TUNNEL_TYPE_GENEVE:
|
|
|
|
+ if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (adapter->geneve_port == port)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (adapter->geneve_port) {
|
|
|
|
+ netdev_info(dev,
|
|
|
|
+ "GENEVE port %d set, not adding port %d\n",
|
|
|
|
+ ntohs(adapter->geneve_port),
|
|
|
|
+ ntohs(port));
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
- if (adapter->vxlan_port) {
|
|
|
|
- netdev_info(dev,
|
|
|
|
- "Hit Max num of VXLAN ports, not adding port %d\n",
|
|
|
|
- ntohs(port));
|
|
|
|
|
|
+ port_shift = IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT;
|
|
|
|
+ adapter->geneve_port = port;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- adapter->vxlan_port = port;
|
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, ntohs(port));
|
|
|
|
|
|
+ reg = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) | ntohs(port) << port_shift;
|
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, reg);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * ixgbe_del_vxlan_port - Get notifications about VXLAN ports that go away
|
|
|
|
|
|
+ * ixgbe_del_udp_tunnel_port - Get notifications about removing UDP tunnel ports
|
|
* @dev: The port's netdev
|
|
* @dev: The port's netdev
|
|
* @ti: Tunnel endpoint information
|
|
* @ti: Tunnel endpoint information
|
|
**/
|
|
**/
|
|
-static void ixgbe_del_vxlan_port(struct net_device *dev,
|
|
|
|
- struct udp_tunnel_info *ti)
|
|
|
|
|
|
+static void ixgbe_del_udp_tunnel_port(struct net_device *dev,
|
|
|
|
+ struct udp_tunnel_info *ti)
|
|
{
|
|
{
|
|
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
|
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
|
|
|
+ u32 port_mask;
|
|
|
|
|
|
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
|
|
|
|
|
|
+ if (ti->type != UDP_TUNNEL_TYPE_VXLAN &&
|
|
|
|
+ ti->type != UDP_TUNNEL_TYPE_GENEVE)
|
|
return;
|
|
return;
|
|
|
|
|
|
if (ti->sa_family != AF_INET)
|
|
if (ti->sa_family != AF_INET)
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
|
|
|
|
- return;
|
|
|
|
|
|
+ switch (ti->type) {
|
|
|
|
+ case UDP_TUNNEL_TYPE_VXLAN:
|
|
|
|
+ if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
|
|
|
|
+ return;
|
|
|
|
|
|
- if (adapter->vxlan_port != ti->port) {
|
|
|
|
- netdev_info(dev, "Port %d was not found, not deleting\n",
|
|
|
|
- ntohs(ti->port));
|
|
|
|
|
|
+ if (adapter->vxlan_port != ti->port) {
|
|
|
|
+ netdev_info(dev, "VXLAN port %d not found\n",
|
|
|
|
+ ntohs(ti->port));
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
|
|
|
|
+ break;
|
|
|
|
+ case UDP_TUNNEL_TYPE_GENEVE:
|
|
|
|
+ if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (adapter->geneve_port != ti->port) {
|
|
|
|
+ netdev_info(dev, "GENEVE port %d not found\n",
|
|
|
|
+ ntohs(ti->port));
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- ixgbe_clear_vxlan_port(adapter);
|
|
|
|
- adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
|
|
|
|
|
|
+ ixgbe_clear_udp_tunnel_port(adapter, port_mask);
|
|
|
|
+ adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
|
|
}
|
|
}
|
|
|
|
|
|
static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
|
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 = {
|
|
.ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
|
|
.ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
|
|
.ndo_dfwd_add_station = ixgbe_fwd_add,
|
|
.ndo_dfwd_add_station = ixgbe_fwd_add,
|
|
.ndo_dfwd_del_station = ixgbe_fwd_del,
|
|
.ndo_dfwd_del_station = ixgbe_fwd_del,
|
|
- .ndo_udp_tunnel_add = ixgbe_add_vxlan_port,
|
|
|
|
- .ndo_udp_tunnel_del = ixgbe_del_vxlan_port,
|
|
|
|
|
|
+ .ndo_udp_tunnel_add = ixgbe_add_udp_tunnel_port,
|
|
|
|
+ .ndo_udp_tunnel_del = ixgbe_del_udp_tunnel_port,
|
|
.ndo_features_check = ixgbe_features_check,
|
|
.ndo_features_check = ixgbe_features_check,
|
|
};
|
|
};
|
|
|
|
|