summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Goudar <ganeshgr@chelsio.com>2018-01-22 16:18:26 +0300
committerDavid S. Miller <davem@davemloft.net>2018-01-22 18:18:09 +0300
commitc746fc0e8b2d144e2ee9122e4efd72326ff3cd1b (patch)
tree95655d1195c9973a6fb1b5198acc991664640e63
parent291040cd7e8368a38ae6624f457c39827c55c7f8 (diff)
downloadlinux-c746fc0e8b2d144e2ee9122e4efd72326ff3cd1b.tar.xz
cxgb4: add geneve offload support for T6
Add geneve segmentation offload support of T6 cards. Original work by: Santosh Rastapur <santosh@chelsio.com> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c71
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h11
4 files changed, 63 insertions, 24 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index f05b58f74c7a..3e0218735b2b 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 11fe5961040a..4716387830ef 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 eab781fab2a8..a7af71bf14fb 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 d9c06d6dc7b2..a6df73398d17 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