Skip to content

Commit 7ffdf72

Browse files
ogerlitzdavem330
authored andcommitted
net/mlx4_core: Add basic support for TCP/IP offloads under tunneling
Add the low-level device commands and definitions used for TCP/IP HW offloads of tunneled/vxlan traffic which are supported by the ConnectX3-pro NIC. This is done through the following elements: - read tunneling device caps in QUERY_DEV_CAP - add helper function to do SET_PORT for tunneling - add DMFS VXLAN steering rule definitions - add CQE and WQE checksum offload field definitions Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 604d13c commit 7ffdf72

File tree

8 files changed

+133
-4
lines changed

8 files changed

+133
-4
lines changed

drivers/net/ethernet/mellanox/mlx4/fw.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
134134
[5] = "Time stamping support",
135135
[6] = "VST (control vlan insertion/stripping) support",
136136
[7] = "FSM (MAC anti-spoofing) support",
137-
[8] = "Dynamic QP updates support"
137+
[8] = "Dynamic QP updates support",
138+
[9] = "TCP/IP offloads/flow-steering for VXLAN support"
138139
};
139140
int i;
140141

@@ -536,6 +537,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
536537
#define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98
537538
#define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0
538539
#define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d
540+
#define QUERY_DEV_CAP_VXLAN 0x9e
539541

540542
dev_cap->flags2 = 0;
541543
mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -701,6 +703,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
701703
MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC);
702704
if (field & 1<<6)
703705
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN;
706+
MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
707+
if (field & 1<<3)
708+
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS;
704709
MLX4_GET(dev_cap->max_icm_sz, outbox,
705710
QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
706711
if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS)
@@ -849,6 +854,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
849854
field &= 0x7f;
850855
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
851856

857+
/* For guests, disable vxlan tunneling */
858+
MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
859+
field &= 0xf7;
860+
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN);
861+
852862
/* For guests, report Blueflame disabled */
853863
MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET);
854864
field &= 0x7f;
@@ -1274,6 +1284,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
12741284
#define INIT_HCA_IN_SIZE 0x200
12751285
#define INIT_HCA_VERSION_OFFSET 0x000
12761286
#define INIT_HCA_VERSION 2
1287+
#define INIT_HCA_VXLAN_OFFSET 0x0c
12771288
#define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e
12781289
#define INIT_HCA_FLAGS_OFFSET 0x014
12791290
#define INIT_HCA_QPC_OFFSET 0x020
@@ -1432,6 +1443,12 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
14321443
MLX4_PUT(inbox, param->uar_page_sz, INIT_HCA_UAR_PAGE_SZ_OFFSET);
14331444
MLX4_PUT(inbox, param->log_uar_sz, INIT_HCA_LOG_UAR_SZ_OFFSET);
14341445

1446+
/* set parser VXLAN attributes */
1447+
if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) {
1448+
u8 parser_params = 0;
1449+
MLX4_PUT(inbox, parser_params, INIT_HCA_VXLAN_OFFSET);
1450+
}
1451+
14351452
err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000,
14361453
MLX4_CMD_NATIVE);
14371454

drivers/net/ethernet/mellanox/mlx4/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,19 @@ static void choose_steering_mode(struct mlx4_dev *dev,
14441444
mlx4_log_num_mgm_entry_size);
14451445
}
14461446

1447+
static void choose_tunnel_offload_mode(struct mlx4_dev *dev,
1448+
struct mlx4_dev_cap *dev_cap)
1449+
{
1450+
if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED &&
1451+
dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS)
1452+
dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN;
1453+
else
1454+
dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE;
1455+
1456+
mlx4_dbg(dev, "Tunneling offload mode is: %s\n", (dev->caps.tunnel_offload_mode
1457+
== MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) ? "vxlan" : "none");
1458+
}
1459+
14471460
static int mlx4_init_hca(struct mlx4_dev *dev)
14481461
{
14491462
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1484,6 +1497,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
14841497
}
14851498

14861499
choose_steering_mode(dev, &dev_cap);
1500+
choose_tunnel_offload_mode(dev, &dev_cap);
14871501

14881502
err = mlx4_get_phys_port_id(dev);
14891503
if (err)

drivers/net/ethernet/mellanox/mlx4/mcg.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,8 @@ const u16 __sw_id_hw[] = {
697697
[MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003,
698698
[MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002,
699699
[MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004,
700-
[MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006
700+
[MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006,
701+
[MLX4_NET_TRANS_RULE_ID_VXLAN] = 0xE008
701702
};
702703

703704
int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
@@ -722,7 +723,9 @@ static const int __rule_hw_sz[] = {
722723
[MLX4_NET_TRANS_RULE_ID_TCP] =
723724
sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
724725
[MLX4_NET_TRANS_RULE_ID_UDP] =
725-
sizeof(struct mlx4_net_trans_rule_hw_tcp_udp)
726+
sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
727+
[MLX4_NET_TRANS_RULE_ID_VXLAN] =
728+
sizeof(struct mlx4_net_trans_rule_hw_vxlan)
726729
};
727730

728731
int mlx4_hw_rule_sz(struct mlx4_dev *dev,
@@ -787,6 +790,13 @@ static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
787790
rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk;
788791
break;
789792

793+
case MLX4_NET_TRANS_RULE_ID_VXLAN:
794+
rule_hw->vxlan.vni =
795+
cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8);
796+
rule_hw->vxlan.vni_mask =
797+
cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8);
798+
break;
799+
790800
default:
791801
return -EINVAL;
792802
}

drivers/net/ethernet/mellanox/mlx4/port.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,47 @@ int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
800800
}
801801
EXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER);
802802

803+
enum {
804+
VXLAN_ENABLE_MODIFY = 1 << 7,
805+
VXLAN_STEERING_MODIFY = 1 << 6,
806+
807+
VXLAN_ENABLE = 1 << 7,
808+
};
809+
810+
struct mlx4_set_port_vxlan_context {
811+
u32 reserved1;
812+
u8 modify_flags;
813+
u8 reserved2;
814+
u8 enable_flags;
815+
u8 steering;
816+
};
817+
818+
int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering)
819+
{
820+
int err;
821+
u32 in_mod;
822+
struct mlx4_cmd_mailbox *mailbox;
823+
struct mlx4_set_port_vxlan_context *context;
824+
825+
mailbox = mlx4_alloc_cmd_mailbox(dev);
826+
if (IS_ERR(mailbox))
827+
return PTR_ERR(mailbox);
828+
context = mailbox->buf;
829+
memset(context, 0, sizeof(*context));
830+
831+
context->modify_flags = VXLAN_ENABLE_MODIFY | VXLAN_STEERING_MODIFY;
832+
context->enable_flags = VXLAN_ENABLE;
833+
context->steering = steering;
834+
835+
in_mod = MLX4_SET_PORT_VXLAN << 8 | port;
836+
err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
837+
MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
838+
839+
mlx4_free_cmd_mailbox(dev, mailbox);
840+
return err;
841+
}
842+
EXPORT_SYMBOL(mlx4_SET_PORT_VXLAN);
843+
803844
int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
804845
struct mlx4_vhcr *vhcr,
805846
struct mlx4_cmd_mailbox *inbox,

include/linux/mlx4/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ enum {
180180
MLX4_SET_PORT_GID_TABLE = 0x5,
181181
MLX4_SET_PORT_PRIO2TC = 0x8,
182182
MLX4_SET_PORT_SCHEDULER = 0x9,
183+
MLX4_SET_PORT_VXLAN = 0xB
183184
};
184185

185186
enum {

include/linux/mlx4/cq.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ struct mlx4_ts_cqe {
8181
} __packed;
8282

8383
enum {
84+
MLX4_CQE_L2_TUNNEL_IPOK = 1 << 31,
8485
MLX4_CQE_VLAN_PRESENT_MASK = 1 << 29,
86+
MLX4_CQE_L2_TUNNEL = 1 << 27,
87+
MLX4_CQE_L2_TUNNEL_CSUM = 1 << 26,
88+
MLX4_CQE_L2_TUNNEL_IPV4 = 1 << 25,
89+
8590
MLX4_CQE_QPN_MASK = 0xffffff,
8691
};
8792

include/linux/mlx4/device.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ static inline const char *mlx4_steering_mode_str(int steering_mode)
118118
}
119119
}
120120

121+
enum {
122+
MLX4_TUNNEL_OFFLOAD_MODE_NONE,
123+
MLX4_TUNNEL_OFFLOAD_MODE_VXLAN
124+
};
125+
121126
enum {
122127
MLX4_DEV_CAP_FLAG_RC = 1LL << 0,
123128
MLX4_DEV_CAP_FLAG_UC = 1LL << 1,
@@ -160,7 +165,8 @@ enum {
160165
MLX4_DEV_CAP_FLAG2_TS = 1LL << 5,
161166
MLX4_DEV_CAP_FLAG2_VLAN_CONTROL = 1LL << 6,
162167
MLX4_DEV_CAP_FLAG2_FSM = 1LL << 7,
163-
MLX4_DEV_CAP_FLAG2_UPDATE_QP = 1LL << 8
168+
MLX4_DEV_CAP_FLAG2_UPDATE_QP = 1LL << 8,
169+
MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS = 1LL << 9
164170
};
165171

166172
enum {
@@ -455,6 +461,7 @@ struct mlx4_caps {
455461
u32 function_caps; /* VFs must be aware of these */
456462
u16 hca_core_clock;
457463
u64 phys_port_id[MLX4_MAX_PORTS + 1];
464+
int tunnel_offload_mode;
458465
};
459466

460467
struct mlx4_buf_list {
@@ -909,6 +916,7 @@ enum mlx4_net_trans_rule_id {
909916
MLX4_NET_TRANS_RULE_ID_IPV4,
910917
MLX4_NET_TRANS_RULE_ID_TCP,
911918
MLX4_NET_TRANS_RULE_ID_UDP,
919+
MLX4_NET_TRANS_RULE_ID_VXLAN,
912920
MLX4_NET_TRANS_RULE_NUM, /* should be last */
913921
};
914922

@@ -966,6 +974,12 @@ struct mlx4_spec_ib {
966974
u8 dst_gid_msk[16];
967975
};
968976

977+
struct mlx4_spec_vxlan {
978+
__be32 vni;
979+
__be32 vni_mask;
980+
981+
};
982+
969983
struct mlx4_spec_list {
970984
struct list_head list;
971985
enum mlx4_net_trans_rule_id id;
@@ -974,6 +988,7 @@ struct mlx4_spec_list {
974988
struct mlx4_spec_ib ib;
975989
struct mlx4_spec_ipv4 ipv4;
976990
struct mlx4_spec_tcp_udp tcp_udp;
991+
struct mlx4_spec_vxlan vxlan;
977992
};
978993
};
979994

@@ -1060,6 +1075,15 @@ struct mlx4_net_trans_rule_hw_ipv4 {
10601075
__be32 src_ip_msk;
10611076
} __packed;
10621077

1078+
struct mlx4_net_trans_rule_hw_vxlan {
1079+
u8 size;
1080+
u8 rsvd;
1081+
__be16 id;
1082+
__be32 rsvd1;
1083+
__be32 vni;
1084+
__be32 vni_mask;
1085+
} __packed;
1086+
10631087
struct _rule_hw {
10641088
union {
10651089
struct {
@@ -1071,9 +1095,19 @@ struct _rule_hw {
10711095
struct mlx4_net_trans_rule_hw_ib ib;
10721096
struct mlx4_net_trans_rule_hw_ipv4 ipv4;
10731097
struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp;
1098+
struct mlx4_net_trans_rule_hw_vxlan vxlan;
10741099
};
10751100
};
10761101

1102+
enum {
1103+
VXLAN_STEER_BY_OUTER_MAC = 1 << 0,
1104+
VXLAN_STEER_BY_OUTER_VLAN = 1 << 1,
1105+
VXLAN_STEER_BY_VSID_VNI = 1 << 2,
1106+
VXLAN_STEER_BY_INNER_MAC = 1 << 3,
1107+
VXLAN_STEER_BY_INNER_VLAN = 1 << 4,
1108+
};
1109+
1110+
10771111
int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn,
10781112
enum mlx4_net_trans_promisc_mode mode);
10791113
int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
@@ -1096,6 +1130,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
10961130
int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc);
10971131
int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
10981132
u8 *pg, u16 *ratelimit);
1133+
int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering);
10991134
int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
11001135
int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
11011136
void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan);

include/linux/mlx4/qp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ enum {
109109
MLX4_RSS_TCP_IPV4 = 1 << 4,
110110
MLX4_RSS_IPV4 = 1 << 5,
111111

112+
MLX4_RSS_BY_OUTER_HEADERS = 0 << 6,
113+
MLX4_RSS_BY_INNER_HEADERS = 2 << 6,
114+
MLX4_RSS_BY_INNER_HEADERS_IPONLY = 3 << 6,
115+
112116
/* offset of mlx4_rss_context within mlx4_qp_context.pri_path */
113117
MLX4_RSS_OFFSET_IN_QPC_PRI_PATH = 0x24,
114118
/* offset of being RSS indirection QP within mlx4_qp_context.flags */
@@ -252,6 +256,8 @@ enum { /* param3 */
252256

253257
enum {
254258
MLX4_WQE_CTRL_NEC = 1 << 29,
259+
MLX4_WQE_CTRL_IIP = 1 << 28,
260+
MLX4_WQE_CTRL_ILP = 1 << 27,
255261
MLX4_WQE_CTRL_FENCE = 1 << 6,
256262
MLX4_WQE_CTRL_CQ_UPDATE = 3 << 2,
257263
MLX4_WQE_CTRL_SOLICITED = 1 << 1,

0 commit comments

Comments
 (0)