Skip to content

Commit 779d143

Browse files
committed
Merge branch 'mlx5-minimum-inline-header-mode'
Saeed Mahameed says: ==================== Mellanox 100G mlx5 minimum inline header mode This small series from Hadar adds the support for minimum inline header mode query in mlx5e NIC driver. Today on TX the driver copies to the HW descriptor only up to L2 header which is the default required mode and sufficient for today's needs. The header in the HW descriptor is used for HW loopback steering decision, without it packets will go directly to the wire with no questions asked. For TX loopback steering according to L2/L3/L4 headers, ConnectX-4 requires to copy the corresponding headers into the send queue(SQ) WQE HW descriptor so it can decide whether to loop it back or to forward to wire. For legacy E-Switch mode only L2 headers copy is required. For advanced steering (E-Switch offloads) more header layers may be required to be copied, the required mode will be advertised by FW to each VF and PF according to the corresponding E-Switch configuration. Changes V2: - Allocate query_nic_vport_context_out on the stack ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 5fc382d + cff92d7 commit 779d143

File tree

7 files changed

+105
-7
lines changed

7 files changed

+105
-7
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ static inline int mlx5_max_log_rq_size(int wq_type)
129129
}
130130
}
131131

132+
enum {
133+
MLX5E_INLINE_MODE_L2,
134+
MLX5E_INLINE_MODE_VPORT_CONTEXT,
135+
MLX5_INLINE_MODE_NOT_REQUIRED,
136+
};
137+
132138
struct mlx5e_tx_wqe {
133139
struct mlx5_wqe_ctrl_seg ctrl;
134140
struct mlx5_wqe_eth_seg eth;
@@ -188,6 +194,7 @@ struct mlx5e_params {
188194
bool lro_en;
189195
u32 lro_wqe_sz;
190196
u16 tx_max_inline;
197+
u8 tx_min_inline_mode;
191198
u8 rss_hfunc;
192199
u8 toeplitz_hash_key[40];
193200
u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
@@ -398,6 +405,7 @@ struct mlx5e_sq {
398405
u32 sqn;
399406
u16 bf_buf_size;
400407
u16 max_inline;
408+
u8 min_inline_mode;
401409
u16 edge;
402410
struct device *pdev;
403411
struct mlx5e_tstamp *tstamp;

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct mlx5e_sq_param {
5656
u32 sqc[MLX5_ST_SZ_DW(sqc)];
5757
struct mlx5_wq_param wq;
5858
u16 max_inline;
59+
u8 min_inline_mode;
5960
bool icosq;
6061
};
6162

@@ -649,6 +650,9 @@ static int mlx5e_create_sq(struct mlx5e_channel *c,
649650
}
650651
sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
651652
sq->max_inline = param->max_inline;
653+
sq->min_inline_mode =
654+
MLX5_CAP_ETH(mdev, wqe_inline_mode) == MLX5E_INLINE_MODE_VPORT_CONTEXT ?
655+
param->min_inline_mode : 0;
652656

653657
err = mlx5e_alloc_sq_db(sq, cpu_to_node(c->cpu));
654658
if (err)
@@ -731,6 +735,7 @@ static int mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param)
731735

732736
MLX5_SET(sqc, sqc, tis_num_0, param->icosq ? 0 : priv->tisn[sq->tc]);
733737
MLX5_SET(sqc, sqc, cqn, sq->cq.mcq.cqn);
738+
MLX5_SET(sqc, sqc, min_wqe_inline_mode, sq->min_inline_mode);
734739
MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
735740
MLX5_SET(sqc, sqc, tis_lst_sz, param->icosq ? 0 : 1);
736741
MLX5_SET(sqc, sqc, flush_in_error_en, 1);
@@ -1343,6 +1348,7 @@ static void mlx5e_build_sq_param(struct mlx5e_priv *priv,
13431348
MLX5_SET(wq, wq, log_wq_sz, priv->params.log_sq_size);
13441349

13451350
param->max_inline = priv->params.tx_max_inline;
1351+
param->min_inline_mode = priv->params.tx_min_inline_mode;
13461352
}
13471353

13481354
static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
@@ -2978,6 +2984,23 @@ void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
29782984
MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE;
29792985
}
29802986

2987+
static void mlx5e_query_min_inline(struct mlx5_core_dev *mdev,
2988+
u8 *min_inline_mode)
2989+
{
2990+
switch (MLX5_CAP_ETH(mdev, wqe_inline_mode)) {
2991+
case MLX5E_INLINE_MODE_L2:
2992+
*min_inline_mode = MLX5_INLINE_MODE_L2;
2993+
break;
2994+
case MLX5E_INLINE_MODE_VPORT_CONTEXT:
2995+
mlx5_query_nic_vport_min_inline(mdev,
2996+
min_inline_mode);
2997+
break;
2998+
case MLX5_INLINE_MODE_NOT_REQUIRED:
2999+
*min_inline_mode = MLX5_INLINE_MODE_NONE;
3000+
break;
3001+
}
3002+
}
3003+
29813004
static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
29823005
struct net_device *netdev,
29833006
const struct mlx5e_profile *profile,
@@ -3043,6 +3066,7 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
30433066
priv->params.tx_cq_moderation.pkts =
30443067
MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
30453068
priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev);
3069+
mlx5e_query_min_inline(mdev, &priv->params.tx_min_inline_mode);
30463070
priv->params.num_tc = 1;
30473071
priv->params.rss_hfunc = ETH_RSS_HASH_XOR;
30483072

drivers/net/ethernet/mellanox/mlx5/core/en_tx.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,57 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
128128
return priv->channeltc_to_txq_map[channel_ix][up];
129129
}
130130

131+
static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
132+
{
133+
#define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
134+
135+
return max(skb_network_offset(skb), MLX5E_MIN_INLINE);
136+
}
137+
138+
static inline int mlx5e_skb_l3_header_offset(struct sk_buff *skb)
139+
{
140+
struct flow_keys keys;
141+
142+
if (skb_transport_header_was_set(skb))
143+
return skb_transport_offset(skb);
144+
else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
145+
return keys.control.thoff;
146+
else
147+
return mlx5e_skb_l2_header_offset(skb);
148+
}
149+
150+
static inline unsigned int mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
151+
struct sk_buff *skb)
152+
{
153+
int hlen;
154+
155+
switch (mode) {
156+
case MLX5_INLINE_MODE_TCP_UDP:
157+
hlen = eth_get_headlen(skb->data, skb_headlen(skb));
158+
if (hlen == ETH_HLEN && !skb_vlan_tag_present(skb))
159+
hlen += VLAN_HLEN;
160+
return hlen;
161+
case MLX5_INLINE_MODE_IP:
162+
/* When transport header is set to zero, it means no transport
163+
* header. When transport header is set to 0xff's, it means
164+
* transport header wasn't set.
165+
*/
166+
if (skb_transport_offset(skb))
167+
return mlx5e_skb_l3_header_offset(skb);
168+
/* fall through */
169+
case MLX5_INLINE_MODE_L2:
170+
default:
171+
return mlx5e_skb_l2_header_offset(skb);
172+
}
173+
}
174+
131175
static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq,
132176
struct sk_buff *skb, bool bf)
133177
{
134178
/* Some NIC TX decisions, e.g loopback, are based on the packet
135179
* headers and occur before the data gather.
136180
* Therefore these headers must be copied into the WQE
137181
*/
138-
#define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
139-
140182
if (bf) {
141183
u16 ihs = skb_headlen(skb);
142184

@@ -146,8 +188,7 @@ static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq,
146188
if (ihs <= sq->max_inline)
147189
return skb_headlen(skb);
148190
}
149-
150-
return max(skb_network_offset(skb), MLX5E_MIN_INLINE);
191+
return mlx5e_calc_min_inline(sq->min_inline_mode, skb);
151192
}
152193

153194
static inline void mlx5e_tx_skb_pull_inline(unsigned char **skb_data,

drivers/net/ethernet/mellanox/mlx5/core/vport.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,18 @@ static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
135135
return mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out));
136136
}
137137

138+
void mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev,
139+
u8 *min_inline_mode)
140+
{
141+
u32 out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0};
142+
143+
mlx5_query_nic_vport_context(mdev, 0, out, sizeof(out));
144+
145+
*min_inline_mode = MLX5_GET(query_nic_vport_context_out, out,
146+
nic_vport_context.min_wqe_inline_mode);
147+
}
148+
EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_min_inline);
149+
138150
int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
139151
u16 vport, u8 *addr)
140152
{

include/linux/mlx5/device.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ __mlx5_mask(typ, fld))
129129
tmp; \
130130
})
131131

132+
enum mlx5_inline_modes {
133+
MLX5_INLINE_MODE_NONE,
134+
MLX5_INLINE_MODE_L2,
135+
MLX5_INLINE_MODE_IP,
136+
MLX5_INLINE_MODE_TCP_UDP,
137+
};
138+
132139
enum {
133140
MLX5_MAX_COMMANDS = 32,
134141
MLX5_CMD_DATA_BLOCK_SIZE = 512,

include/linux/mlx5/mlx5_ifc.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,8 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
536536
u8 self_lb_en_modifiable[0x1];
537537
u8 reserved_at_9[0x2];
538538
u8 max_lso_cap[0x5];
539-
u8 reserved_at_10[0x4];
539+
u8 reserved_at_10[0x2];
540+
u8 wqe_inline_mode[0x2];
540541
u8 rss_ind_tbl_cap[0x4];
541542
u8 reg_umr_sq[0x1];
542543
u8 scatter_fcs[0x1];
@@ -2270,7 +2271,8 @@ struct mlx5_ifc_sqc_bits {
22702271
u8 cd_master[0x1];
22712272
u8 fre[0x1];
22722273
u8 flush_in_error_en[0x1];
2273-
u8 reserved_at_4[0x4];
2274+
u8 reserved_at_4[0x1];
2275+
u8 min_wqe_inline_mode[0x3];
22742276
u8 state[0x4];
22752277
u8 reg_umr[0x1];
22762278
u8 reserved_at_d[0x13];
@@ -2367,7 +2369,9 @@ struct mlx5_ifc_rmpc_bits {
23672369
};
23682370

23692371
struct mlx5_ifc_nic_vport_context_bits {
2370-
u8 reserved_at_0[0x1f];
2372+
u8 reserved_at_0[0x5];
2373+
u8 min_wqe_inline_mode[0x3];
2374+
u8 reserved_at_8[0x17];
23712375
u8 roce_en[0x1];
23722376

23732377
u8 arm_change_event[0x1];

include/linux/mlx5/vport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
4343
u16 vport, u8 state);
4444
int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
4545
u16 vport, u8 *addr);
46+
void mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev,
47+
u8 *min_inline);
4648
int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev,
4749
u16 vport, u8 *addr);
4850
int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu);

0 commit comments

Comments
 (0)