diff mbox series

[net-next] cxgb4: add geneve offload support for T6

Message ID 1516627106-20122-1-git-send-email-ganeshgr@chelsio.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net-next] cxgb4: add geneve offload support for T6 | expand

Commit Message

Ganesh Goudar Jan. 22, 2018, 1:18 p.m. UTC
Add geneve segmentation offload support of T6 cards.

Original work by: Santosh Rastapur <santosh@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h      |  2 +
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 71 ++++++++++++++++---------
 drivers/net/ethernet/chelsio/cxgb4/sge.c        |  3 ++
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h    | 11 ++++
 4 files changed, 63 insertions(+), 24 deletions(-)

Comments

David Miller Jan. 22, 2018, 3:22 p.m. UTC | #1
From: Ganesh Goudar <ganeshgr@chelsio.com>
Date: Mon, 22 Jan 2018 18:48:26 +0530

> Add geneve segmentation offload support of T6 cards.
> 
> Original work by: Santosh Rastapur <santosh@chelsio.com>
> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>

Applied, thank you.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index f05b58f..3e02187 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -846,6 +846,8 @@  struct adapter {
 	int msg_enable;
 	__be16 vxlan_port;
 	u8 vxlan_port_cnt;
+	__be16 geneve_port;
+	u8 geneve_port_cnt;
 
 	struct adapter_params params;
 	struct cxgb4_virt_res vres;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 11fe596..4716387 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3020,6 +3020,17 @@  static void cxgb_del_udp_tunnel(struct net_device *netdev,
 		adapter->vxlan_port = 0;
 		t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A, 0);
 		break;
+	case UDP_TUNNEL_TYPE_GENEVE:
+		if (!adapter->geneve_port_cnt ||
+		    adapter->geneve_port != ti->port)
+			return; /* Invalid GENEVE destination port */
+
+		adapter->geneve_port_cnt--;
+		if (adapter->geneve_port_cnt)
+			return;
+
+		adapter->geneve_port = 0;
+		t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A, 0);
 	default:
 		return;
 	}
@@ -3055,17 +3066,11 @@  static void cxgb_add_udp_tunnel(struct net_device *netdev,
 	u8 match_all_mac[] = { 0, 0, 0, 0, 0, 0 };
 	int i, ret;
 
-	if (chip_ver < CHELSIO_T6)
+	if (chip_ver < CHELSIO_T6 || !adapter->rawf_cnt)
 		return;
 
 	switch (ti->type) {
 	case UDP_TUNNEL_TYPE_VXLAN:
-		/* For T6 fw reserves last 2 entries for
-		 * storing match all mac filter (config file entry).
-		 */
-		if (!adapter->rawf_cnt)
-			return;
-
 		/* Callback for adding vxlan port can be called with the same
 		 * port for both IPv4 and IPv6. We should not disable the
 		 * offloading when the same port for both protocols is added
@@ -3091,6 +3096,26 @@  static void cxgb_add_udp_tunnel(struct net_device *netdev,
 		t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A,
 			     VXLAN_V(be16_to_cpu(ti->port)) | VXLAN_EN_F);
 		break;
+	case UDP_TUNNEL_TYPE_GENEVE:
+		if (adapter->geneve_port_cnt &&
+		    adapter->geneve_port == ti->port) {
+			adapter->geneve_port_cnt++;
+			return;
+		}
+
+		/* We will support only one GENEVE port */
+		if (adapter->geneve_port_cnt) {
+			netdev_info(netdev, "UDP port %d already offloaded, not adding port %d\n",
+				    be16_to_cpu(adapter->geneve_port),
+				    be16_to_cpu(ti->port));
+			return;
+		}
+
+		adapter->geneve_port = ti->port;
+		adapter->geneve_port_cnt = 1;
+
+		t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A,
+			     GENEVE_V(be16_to_cpu(ti->port)) | GENEVE_EN_F);
 	default:
 		return;
 	}
@@ -3101,24 +3126,22 @@  static void cxgb_add_udp_tunnel(struct net_device *netdev,
 	 * we will remove this 'match all' entry and fallback to adding
 	 * exact match filters.
 	 */
-	if (adapter->rawf_cnt) {
-		for_each_port(adapter, i) {
-			pi = adap2pinfo(adapter, i);
-
-			ret = t4_alloc_raw_mac_filt(adapter, pi->viid,
-						    match_all_mac,
-						    match_all_mac,
-						    adapter->rawf_start +
-						    pi->port_id,
-						    1, pi->port_id, true);
-			if (ret < 0) {
-				netdev_info(netdev, "Failed to allocate a mac filter entry, not adding port %d\n",
-					    be16_to_cpu(ti->port));
-				cxgb_del_udp_tunnel(netdev, ti);
-				return;
-			}
-			atomic_inc(&adapter->mps_encap[ret].refcnt);
+	for_each_port(adapter, i) {
+		pi = adap2pinfo(adapter, i);
+
+		ret = t4_alloc_raw_mac_filt(adapter, pi->viid,
+					    match_all_mac,
+					    match_all_mac,
+					    adapter->rawf_start +
+					    pi->port_id,
+					    1, pi->port_id, true);
+		if (ret < 0) {
+			netdev_info(netdev, "Failed to allocate a mac filter entry, not adding port %d\n",
+				    be16_to_cpu(ti->port));
+			cxgb_del_udp_tunnel(netdev, ti);
+			return;
 		}
+		atomic_inc(&adapter->mps_encap[ret].refcnt);
 	}
 }
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index eab781f..a7af71b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -1199,6 +1199,8 @@  enum cpl_tx_tnl_lso_type cxgb_encap_offload_supported(struct sk_buff *skb)
 	case IPPROTO_UDP:
 		if (adapter->vxlan_port == udp_hdr(skb)->dest)
 			tnl_type = TX_TNL_TYPE_VXLAN;
+		else if (adapter->geneve_port == udp_hdr(skb)->dest)
+			tnl_type = TX_TNL_TYPE_GENEVE;
 		break;
 	default:
 		return tnl_type;
@@ -1238,6 +1240,7 @@  static inline void t6_fill_tnl_lso(struct sk_buff *skb,
 
 	switch (tnl_type) {
 	case TX_TNL_TYPE_VXLAN:
+	case TX_TNL_TYPE_GENEVE:
 		tnl_lso->UdpLenSetOut_to_TnlHdrLen =
 			htons(CPL_TX_TNL_LSO_UDPCHKCLROUT_F |
 			CPL_TX_TNL_LSO_UDPLENSETOUT_F);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index d9c06d6..a6df733 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -2522,6 +2522,17 @@ 
 #define VXLAN_V(x) ((x) << VXLAN_S)
 #define VXLAN_G(x) (((x) >> VXLAN_S) & VXLAN_M)
 
+#define MPS_RX_GENEVE_TYPE_A 0x11238
+
+#define GENEVE_EN_S    16
+#define GENEVE_EN_V(x) ((x) << GENEVE_EN_S)
+#define GENEVE_EN_F    GENEVE_EN_V(1U)
+
+#define GENEVE_S    0
+#define GENEVE_M    0xffffU
+#define GENEVE_V(x) ((x) << GENEVE_S)
+#define GENEVE_G(x) (((x) >> GENEVE_S) & GENEVE_M)
+
 #define MPS_CLS_TCAM_Y_L_A 0xf000
 #define MPS_CLS_TCAM_DATA0_A 0xf000
 #define MPS_CLS_TCAM_DATA1_A 0xf004