mirror of
https://github.com/torvalds/linux.git
synced 2024-12-31 23:31:29 +00:00
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>
This commit is contained in:
parent
291040cd7e
commit
c746fc0e8b
@ -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,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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user