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 {
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;
......
......@@ -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,7 +3126,6 @@ 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);
......@@ -3119,7 +3143,6 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
}
atomic_inc(&adapter->mps_encap[ret].refcnt);
}
}
}
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)
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);
......
......@@ -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
......
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