diff options
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en.h | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 24 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 49 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/vport.c | 12 | ||||
| -rw-r--r-- | include/linux/mlx5/device.h | 7 | ||||
| -rw-r--r-- | include/linux/mlx5/mlx5_ifc.h | 10 | ||||
| -rw-r--r-- | include/linux/mlx5/vport.h | 2 |
7 files changed, 105 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 4cbd452fec25..1b495efa7490 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
| @@ -129,6 +129,12 @@ static inline int mlx5_max_log_rq_size(int wq_type) | |||
| 129 | } | 129 | } |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | enum { | ||
| 133 | MLX5E_INLINE_MODE_L2, | ||
| 134 | MLX5E_INLINE_MODE_VPORT_CONTEXT, | ||
| 135 | MLX5_INLINE_MODE_NOT_REQUIRED, | ||
| 136 | }; | ||
| 137 | |||
| 132 | struct mlx5e_tx_wqe { | 138 | struct mlx5e_tx_wqe { |
| 133 | struct mlx5_wqe_ctrl_seg ctrl; | 139 | struct mlx5_wqe_ctrl_seg ctrl; |
| 134 | struct mlx5_wqe_eth_seg eth; | 140 | struct mlx5_wqe_eth_seg eth; |
| @@ -188,6 +194,7 @@ struct mlx5e_params { | |||
| 188 | bool lro_en; | 194 | bool lro_en; |
| 189 | u32 lro_wqe_sz; | 195 | u32 lro_wqe_sz; |
| 190 | u16 tx_max_inline; | 196 | u16 tx_max_inline; |
| 197 | u8 tx_min_inline_mode; | ||
| 191 | u8 rss_hfunc; | 198 | u8 rss_hfunc; |
| 192 | u8 toeplitz_hash_key[40]; | 199 | u8 toeplitz_hash_key[40]; |
| 193 | u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE]; | 200 | u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE]; |
| @@ -398,6 +405,7 @@ struct mlx5e_sq { | |||
| 398 | u32 sqn; | 405 | u32 sqn; |
| 399 | u16 bf_buf_size; | 406 | u16 bf_buf_size; |
| 400 | u16 max_inline; | 407 | u16 max_inline; |
| 408 | u8 min_inline_mode; | ||
| 401 | u16 edge; | 409 | u16 edge; |
| 402 | struct device *pdev; | 410 | struct device *pdev; |
| 403 | struct mlx5e_tstamp *tstamp; | 411 | struct mlx5e_tstamp *tstamp; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index bdcb699fe63e..870bea37c57c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
| @@ -56,6 +56,7 @@ struct mlx5e_sq_param { | |||
| 56 | u32 sqc[MLX5_ST_SZ_DW(sqc)]; | 56 | u32 sqc[MLX5_ST_SZ_DW(sqc)]; |
| 57 | struct mlx5_wq_param wq; | 57 | struct mlx5_wq_param wq; |
| 58 | u16 max_inline; | 58 | u16 max_inline; |
| 59 | u8 min_inline_mode; | ||
| 59 | bool icosq; | 60 | bool icosq; |
| 60 | }; | 61 | }; |
| 61 | 62 | ||
| @@ -649,6 +650,9 @@ static int mlx5e_create_sq(struct mlx5e_channel *c, | |||
| 649 | } | 650 | } |
| 650 | sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2; | 651 | sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2; |
| 651 | sq->max_inline = param->max_inline; | 652 | 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; | ||
| 652 | 656 | ||
| 653 | err = mlx5e_alloc_sq_db(sq, cpu_to_node(c->cpu)); | 657 | err = mlx5e_alloc_sq_db(sq, cpu_to_node(c->cpu)); |
| 654 | if (err) | 658 | if (err) |
| @@ -731,6 +735,7 @@ static int mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param) | |||
| 731 | 735 | ||
| 732 | MLX5_SET(sqc, sqc, tis_num_0, param->icosq ? 0 : priv->tisn[sq->tc]); | 736 | MLX5_SET(sqc, sqc, tis_num_0, param->icosq ? 0 : priv->tisn[sq->tc]); |
| 733 | MLX5_SET(sqc, sqc, cqn, sq->cq.mcq.cqn); | 737 | MLX5_SET(sqc, sqc, cqn, sq->cq.mcq.cqn); |
| 738 | MLX5_SET(sqc, sqc, min_wqe_inline_mode, sq->min_inline_mode); | ||
| 734 | MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST); | 739 | MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST); |
| 735 | MLX5_SET(sqc, sqc, tis_lst_sz, param->icosq ? 0 : 1); | 740 | MLX5_SET(sqc, sqc, tis_lst_sz, param->icosq ? 0 : 1); |
| 736 | MLX5_SET(sqc, sqc, flush_in_error_en, 1); | 741 | MLX5_SET(sqc, sqc, flush_in_error_en, 1); |
| @@ -1343,6 +1348,7 @@ static void mlx5e_build_sq_param(struct mlx5e_priv *priv, | |||
| 1343 | MLX5_SET(wq, wq, log_wq_sz, priv->params.log_sq_size); | 1348 | MLX5_SET(wq, wq, log_wq_sz, priv->params.log_sq_size); |
| 1344 | 1349 | ||
| 1345 | param->max_inline = priv->params.tx_max_inline; | 1350 | param->max_inline = priv->params.tx_max_inline; |
| 1351 | param->min_inline_mode = priv->params.tx_min_inline_mode; | ||
| 1346 | } | 1352 | } |
| 1347 | 1353 | ||
| 1348 | static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv, | 1354 | 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) | |||
| 2978 | MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE; | 2984 | MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE; |
| 2979 | } | 2985 | } |
| 2980 | 2986 | ||
| 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 | |||
| 2981 | static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, | 3004 | static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, |
| 2982 | struct net_device *netdev, | 3005 | struct net_device *netdev, |
| 2983 | const struct mlx5e_profile *profile, | 3006 | const struct mlx5e_profile *profile, |
| @@ -3043,6 +3066,7 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, | |||
| 3043 | priv->params.tx_cq_moderation.pkts = | 3066 | priv->params.tx_cq_moderation.pkts = |
| 3044 | MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS; | 3067 | MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS; |
| 3045 | priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev); | 3068 | priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev); |
| 3069 | mlx5e_query_min_inline(mdev, &priv->params.tx_min_inline_mode); | ||
| 3046 | priv->params.num_tc = 1; | 3070 | priv->params.num_tc = 1; |
| 3047 | priv->params.rss_hfunc = ETH_RSS_HASH_XOR; | 3071 | priv->params.rss_hfunc = ETH_RSS_HASH_XOR; |
| 3048 | 3072 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index 5740b465ef84..e073bf59890d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | |||
| @@ -128,6 +128,50 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
| 128 | return priv->channeltc_to_txq_map[channel_ix][up]; | 128 | return priv->channeltc_to_txq_map[channel_ix][up]; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 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 | |||
| 131 | static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq, | 175 | static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq, |
| 132 | struct sk_buff *skb, bool bf) | 176 | struct sk_buff *skb, bool bf) |
| 133 | { | 177 | { |
| @@ -135,8 +179,6 @@ static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq, | |||
| 135 | * headers and occur before the data gather. | 179 | * headers and occur before the data gather. |
| 136 | * Therefore these headers must be copied into the WQE | 180 | * Therefore these headers must be copied into the WQE |
| 137 | */ | 181 | */ |
| 138 | #define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN) | ||
| 139 | |||
| 140 | if (bf) { | 182 | if (bf) { |
| 141 | u16 ihs = skb_headlen(skb); | 183 | u16 ihs = skb_headlen(skb); |
| 142 | 184 | ||
| @@ -146,8 +188,7 @@ static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq, | |||
| 146 | if (ihs <= sq->max_inline) | 188 | if (ihs <= sq->max_inline) |
| 147 | return skb_headlen(skb); | 189 | return skb_headlen(skb); |
| 148 | } | 190 | } |
| 149 | 191 | return mlx5e_calc_min_inline(sq->min_inline_mode, skb); | |
| 150 | return max(skb_network_offset(skb), MLX5E_MIN_INLINE); | ||
| 151 | } | 192 | } |
| 152 | 193 | ||
| 153 | static inline void mlx5e_tx_skb_pull_inline(unsigned char **skb_data, | 194 | static inline void mlx5e_tx_skb_pull_inline(unsigned char **skb_data, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index 91846dfcbe9c..21365d06982b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c | |||
| @@ -135,6 +135,18 @@ static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in, | |||
| 135 | return mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out)); | 135 | return mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out)); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 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 | |||
| 138 | int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, | 150 | int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, |
| 139 | u16 vport, u8 *addr) | 151 | u16 vport, u8 *addr) |
| 140 | { | 152 | { |
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index e0a3ed758287..0b6d15cddb2f 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h | |||
| @@ -129,6 +129,13 @@ __mlx5_mask(typ, fld)) | |||
| 129 | tmp; \ | 129 | tmp; \ |
| 130 | }) | 130 | }) |
| 131 | 131 | ||
| 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 | |||
| 132 | enum { | 139 | enum { |
| 133 | MLX5_MAX_COMMANDS = 32, | 140 | MLX5_MAX_COMMANDS = 32, |
| 134 | MLX5_CMD_DATA_BLOCK_SIZE = 512, | 141 | MLX5_CMD_DATA_BLOCK_SIZE = 512, |
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index d671e4e8e7db..21bc4557b67a 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h | |||
| @@ -536,7 +536,8 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits { | |||
| 536 | u8 self_lb_en_modifiable[0x1]; | 536 | u8 self_lb_en_modifiable[0x1]; |
| 537 | u8 reserved_at_9[0x2]; | 537 | u8 reserved_at_9[0x2]; |
| 538 | u8 max_lso_cap[0x5]; | 538 | u8 max_lso_cap[0x5]; |
| 539 | u8 reserved_at_10[0x4]; | 539 | u8 reserved_at_10[0x2]; |
| 540 | u8 wqe_inline_mode[0x2]; | ||
| 540 | u8 rss_ind_tbl_cap[0x4]; | 541 | u8 rss_ind_tbl_cap[0x4]; |
| 541 | u8 reg_umr_sq[0x1]; | 542 | u8 reg_umr_sq[0x1]; |
| 542 | u8 scatter_fcs[0x1]; | 543 | u8 scatter_fcs[0x1]; |
| @@ -2270,7 +2271,8 @@ struct mlx5_ifc_sqc_bits { | |||
| 2270 | u8 cd_master[0x1]; | 2271 | u8 cd_master[0x1]; |
| 2271 | u8 fre[0x1]; | 2272 | u8 fre[0x1]; |
| 2272 | u8 flush_in_error_en[0x1]; | 2273 | 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]; | ||
| 2274 | u8 state[0x4]; | 2276 | u8 state[0x4]; |
| 2275 | u8 reg_umr[0x1]; | 2277 | u8 reg_umr[0x1]; |
| 2276 | u8 reserved_at_d[0x13]; | 2278 | u8 reserved_at_d[0x13]; |
| @@ -2367,7 +2369,9 @@ struct mlx5_ifc_rmpc_bits { | |||
| 2367 | }; | 2369 | }; |
| 2368 | 2370 | ||
| 2369 | struct mlx5_ifc_nic_vport_context_bits { | 2371 | 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]; | ||
| 2371 | u8 roce_en[0x1]; | 2375 | u8 roce_en[0x1]; |
| 2372 | 2376 | ||
| 2373 | u8 arm_change_event[0x1]; | 2377 | u8 arm_change_event[0x1]; |
diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index 6c16c198f680..e087b7d047ac 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h | |||
| @@ -43,6 +43,8 @@ int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod, | |||
| 43 | u16 vport, u8 state); | 43 | u16 vport, u8 state); |
| 44 | int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, | 44 | int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, |
| 45 | u16 vport, u8 *addr); | 45 | u16 vport, u8 *addr); |
| 46 | void mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev, | ||
| 47 | u8 *min_inline); | ||
| 46 | int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev, | 48 | int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev, |
| 47 | u16 vport, u8 *addr); | 49 | u16 vport, u8 *addr); |
| 48 | int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu); | 50 | int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu); |
