From c746fc0e8b2d144e2ee9122e4efd72326ff3cd1b Mon Sep 17 00:00:00 2001 From: Ganesh Goudar Date: Mon, 22 Jan 2018 18:48:26 +0530 Subject: [PATCH] cxgb4: add geneve offload support for T6 Add geneve segmentation offload support of T6 cards. Original work by: Santosh Rastapur Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller --- 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(-) 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 -- 2.7.4