Commit c746fc0e authored by Ganesh Goudar's avatar Ganesh Goudar Committed by David S. Miller

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: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 291040cd
...@@ -846,6 +846,8 @@ struct adapter { ...@@ -846,6 +846,8 @@ struct adapter {
int msg_enable; int msg_enable;
__be16 vxlan_port; __be16 vxlan_port;
u8 vxlan_port_cnt; u8 vxlan_port_cnt;
__be16 geneve_port;
u8 geneve_port_cnt;
struct adapter_params params; struct adapter_params params;
struct cxgb4_virt_res vres; struct cxgb4_virt_res vres;
......
...@@ -3020,6 +3020,17 @@ static void cxgb_del_udp_tunnel(struct net_device *netdev, ...@@ -3020,6 +3020,17 @@ static void cxgb_del_udp_tunnel(struct net_device *netdev,
adapter->vxlan_port = 0; adapter->vxlan_port = 0;
t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A, 0); t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A, 0);
break; 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: default:
return; return;
} }
...@@ -3055,17 +3066,11 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev, ...@@ -3055,17 +3066,11 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
u8 match_all_mac[] = { 0, 0, 0, 0, 0, 0 }; u8 match_all_mac[] = { 0, 0, 0, 0, 0, 0 };
int i, ret; int i, ret;
if (chip_ver < CHELSIO_T6) if (chip_ver < CHELSIO_T6 || !adapter->rawf_cnt)
return; return;
switch (ti->type) { switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN: 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 /* Callback for adding vxlan port can be called with the same
* port for both IPv4 and IPv6. We should not disable the * port for both IPv4 and IPv6. We should not disable the
* offloading when the same port for both protocols is added * offloading when the same port for both protocols is added
...@@ -3091,6 +3096,26 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev, ...@@ -3091,6 +3096,26 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A, t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A,
VXLAN_V(be16_to_cpu(ti->port)) | VXLAN_EN_F); VXLAN_V(be16_to_cpu(ti->port)) | VXLAN_EN_F);
break; 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: default:
return; return;
} }
...@@ -3101,7 +3126,6 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev, ...@@ -3101,7 +3126,6 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
* we will remove this 'match all' entry and fallback to adding * we will remove this 'match all' entry and fallback to adding
* exact match filters. * exact match filters.
*/ */
if (adapter->rawf_cnt) {
for_each_port(adapter, i) { for_each_port(adapter, i) {
pi = adap2pinfo(adapter, i); pi = adap2pinfo(adapter, i);
...@@ -3119,7 +3143,6 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev, ...@@ -3119,7 +3143,6 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
} }
atomic_inc(&adapter->mps_encap[ret].refcnt); atomic_inc(&adapter->mps_encap[ret].refcnt);
} }
}
} }
static netdev_features_t cxgb_features_check(struct sk_buff *skb, static netdev_features_t cxgb_features_check(struct sk_buff *skb,
......
...@@ -1199,6 +1199,8 @@ enum cpl_tx_tnl_lso_type cxgb_encap_offload_supported(struct sk_buff *skb) ...@@ -1199,6 +1199,8 @@ enum cpl_tx_tnl_lso_type cxgb_encap_offload_supported(struct sk_buff *skb)
case IPPROTO_UDP: case IPPROTO_UDP:
if (adapter->vxlan_port == udp_hdr(skb)->dest) if (adapter->vxlan_port == udp_hdr(skb)->dest)
tnl_type = TX_TNL_TYPE_VXLAN; tnl_type = TX_TNL_TYPE_VXLAN;
else if (adapter->geneve_port == udp_hdr(skb)->dest)
tnl_type = TX_TNL_TYPE_GENEVE;
break; break;
default: default:
return tnl_type; return tnl_type;
...@@ -1238,6 +1240,7 @@ static inline void t6_fill_tnl_lso(struct sk_buff *skb, ...@@ -1238,6 +1240,7 @@ static inline void t6_fill_tnl_lso(struct sk_buff *skb,
switch (tnl_type) { switch (tnl_type) {
case TX_TNL_TYPE_VXLAN: case TX_TNL_TYPE_VXLAN:
case TX_TNL_TYPE_GENEVE:
tnl_lso->UdpLenSetOut_to_TnlHdrLen = tnl_lso->UdpLenSetOut_to_TnlHdrLen =
htons(CPL_TX_TNL_LSO_UDPCHKCLROUT_F | htons(CPL_TX_TNL_LSO_UDPCHKCLROUT_F |
CPL_TX_TNL_LSO_UDPLENSETOUT_F); CPL_TX_TNL_LSO_UDPLENSETOUT_F);
......
...@@ -2522,6 +2522,17 @@ ...@@ -2522,6 +2522,17 @@
#define VXLAN_V(x) ((x) << VXLAN_S) #define VXLAN_V(x) ((x) << VXLAN_S)
#define VXLAN_G(x) (((x) >> VXLAN_S) & VXLAN_M) #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_Y_L_A 0xf000
#define MPS_CLS_TCAM_DATA0_A 0xf000 #define MPS_CLS_TCAM_DATA0_A 0xf000
#define MPS_CLS_TCAM_DATA1_A 0xf004 #define MPS_CLS_TCAM_DATA1_A 0xf004
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment