aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-03-29 14:01:40 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-29 14:01:40 -0400
commit6e2135ce54b72f8b2b20cef2a06ae6acb77a3431 (patch)
treefd6b777d97d74bf40fb6f455f21413033d4453ed
parent038d49baab571800e3077b9d322a004f95c8aa8f (diff)
parentdb75373c91b0cfb6a68ad6ae88721e4e21ae6261 (diff)
Merge tag 'mlx5-updates-2018-03-27' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5-updates-2018-03-27 (Misc updates & SQ recovery) This series contains Misc updates and cleanups for mlx5e rx path and SQ recovery feature for tx path. From Tariq: (RX updates) - Disable Striding RQ when PCI devices, striding RQ limits the use of CQE compression feature, which is very critical for slow PCI devices performance, in this change we will prefer CQE compression over Striding RQ only on specific "slow" PCIe links. - RX path cleanups - Private flag to enable/disable striding RQ From Eran: (TX fast recovery) - TX timeout logic improvements, fast SQ recovery and TX error reporting if a HW error occurs while transmitting on a specific SQ, the driver will ignore such error and will wait for TX timeout to occur and reset all the rings. Instead, the current series improves the resiliency for such HW errors by detecting TX completions with errors, which will report them and perform a fast recover for the specific faulty SQ even before a TX timeout is detected. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c8
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h29
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c83
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c306
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tx.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/transobj.c25
-rw-r--r--include/linux/mlx5/cq.h6
-rw-r--r--include/linux/mlx5/transobj.h1
15 files changed, 368 insertions, 162 deletions
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 94a27d89a303..77d257ec899b 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -267,14 +267,8 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
267 267
268static void dump_cqe(struct mlx5_ib_dev *dev, struct mlx5_err_cqe *cqe) 268static void dump_cqe(struct mlx5_ib_dev *dev, struct mlx5_err_cqe *cqe)
269{ 269{
270 __be32 *p = (__be32 *)cqe;
271 int i;
272
273 mlx5_ib_warn(dev, "dump error cqe\n"); 270 mlx5_ib_warn(dev, "dump error cqe\n");
274 for (i = 0; i < sizeof(*cqe) / 16; i++, p += 4) 271 mlx5_dump_err_cqe(dev->mdev, cqe);
275 pr_info("%08x %08x %08x %08x\n", be32_to_cpu(p[0]),
276 be32_to_cpu(p[1]), be32_to_cpu(p[2]),
277 be32_to_cpu(p[3]));
278} 272}
279 273
280static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev, 274static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev,
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 85c612ac547a..0d0b0b8dad98 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -4739,26 +4739,14 @@ static int query_raw_packet_qp_sq_state(struct mlx5_ib_dev *dev,
4739 struct mlx5_ib_sq *sq, 4739 struct mlx5_ib_sq *sq,
4740 u8 *sq_state) 4740 u8 *sq_state)
4741{ 4741{
4742 void *out;
4743 void *sqc;
4744 int inlen;
4745 int err; 4742 int err;
4746 4743
4747 inlen = MLX5_ST_SZ_BYTES(query_sq_out); 4744 err = mlx5_core_query_sq_state(dev->mdev, sq->base.mqp.qpn, sq_state);
4748 out = kvzalloc(inlen, GFP_KERNEL);
4749 if (!out)
4750 return -ENOMEM;
4751
4752 err = mlx5_core_query_sq(dev->mdev, sq->base.mqp.qpn, out);
4753 if (err) 4745 if (err)
4754 goto out; 4746 goto out;
4755
4756 sqc = MLX5_ADDR_OF(query_sq_out, out, sq_context);
4757 *sq_state = MLX5_GET(sqc, sqc, state);
4758 sq->state = *sq_state; 4747 sq->state = *sq_state;
4759 4748
4760out: 4749out:
4761 kvfree(out);
4762 return err; 4750 return err;
4763} 4751}
4764 4752
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 294bc9f175a5..353ac6daa3dc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -93,8 +93,6 @@
93#define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \ 93#define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \
94 MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0) 94 MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0)
95#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) 95#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
96#define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \
97 MLX5_MPWRQ_WQE_PAGE_ORDER)
98 96
99#define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2) 97#define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2)
100#define MLX5E_REQUIRED_MTTS(wqes) \ 98#define MLX5E_REQUIRED_MTTS(wqes) \
@@ -124,6 +122,7 @@
124#define MLX5E_MAX_NUM_SQS (MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC) 122#define MLX5E_MAX_NUM_SQS (MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC)
125#define MLX5E_TX_CQ_POLL_BUDGET 128 123#define MLX5E_TX_CQ_POLL_BUDGET 128
126#define MLX5E_UPDATE_STATS_INTERVAL 200 /* msecs */ 124#define MLX5E_UPDATE_STATS_INTERVAL 200 /* msecs */
125#define MLX5E_SQ_RECOVER_MIN_INTERVAL 500 /* msecs */
127 126
128#define MLX5E_ICOSQ_MAX_WQEBBS \ 127#define MLX5E_ICOSQ_MAX_WQEBBS \
129 (DIV_ROUND_UP(sizeof(struct mlx5e_umr_wqe), MLX5_SEND_WQE_BB)) 128 (DIV_ROUND_UP(sizeof(struct mlx5e_umr_wqe), MLX5_SEND_WQE_BB))
@@ -207,12 +206,14 @@ static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
207 "rx_cqe_moder", 206 "rx_cqe_moder",
208 "tx_cqe_moder", 207 "tx_cqe_moder",
209 "rx_cqe_compress", 208 "rx_cqe_compress",
209 "rx_striding_rq",
210}; 210};
211 211
212enum mlx5e_priv_flag { 212enum mlx5e_priv_flag {
213 MLX5E_PFLAG_RX_CQE_BASED_MODER = (1 << 0), 213 MLX5E_PFLAG_RX_CQE_BASED_MODER = (1 << 0),
214 MLX5E_PFLAG_TX_CQE_BASED_MODER = (1 << 1), 214 MLX5E_PFLAG_TX_CQE_BASED_MODER = (1 << 1),
215 MLX5E_PFLAG_RX_CQE_COMPRESS = (1 << 2), 215 MLX5E_PFLAG_RX_CQE_COMPRESS = (1 << 2),
216 MLX5E_PFLAG_RX_STRIDING_RQ = (1 << 3),
216}; 217};
217 218
218#define MLX5E_SET_PFLAG(params, pflag, enable) \ 219#define MLX5E_SET_PFLAG(params, pflag, enable) \
@@ -232,9 +233,6 @@ enum mlx5e_priv_flag {
232struct mlx5e_params { 233struct mlx5e_params {
233 u8 log_sq_size; 234 u8 log_sq_size;
234 u8 rq_wq_type; 235 u8 rq_wq_type;
235 u16 rq_headroom;
236 u8 mpwqe_log_stride_sz;
237 u8 mpwqe_log_num_strides;
238 u8 log_rq_size; 236 u8 log_rq_size;
239 u16 num_channels; 237 u16 num_channels;
240 u8 num_tc; 238 u8 num_tc;
@@ -243,7 +241,6 @@ struct mlx5e_params {
243 struct net_dim_cq_moder tx_cq_moderation; 241 struct net_dim_cq_moder tx_cq_moderation;
244 bool lro_en; 242 bool lro_en;
245 u32 lro_wqe_sz; 243 u32 lro_wqe_sz;
246 u16 tx_max_inline;
247 u8 tx_min_inline_mode; 244 u8 tx_min_inline_mode;
248 u8 rss_hfunc; 245 u8 rss_hfunc;
249 u8 toeplitz_hash_key[40]; 246 u8 toeplitz_hash_key[40];
@@ -336,6 +333,7 @@ struct mlx5e_sq_dma {
336 333
337enum { 334enum {
338 MLX5E_SQ_STATE_ENABLED, 335 MLX5E_SQ_STATE_ENABLED,
336 MLX5E_SQ_STATE_RECOVERING,
339 MLX5E_SQ_STATE_IPSEC, 337 MLX5E_SQ_STATE_IPSEC,
340}; 338};
341 339
@@ -369,7 +367,6 @@ struct mlx5e_txqsq {
369 void __iomem *uar_map; 367 void __iomem *uar_map;
370 struct netdev_queue *txq; 368 struct netdev_queue *txq;
371 u32 sqn; 369 u32 sqn;
372 u16 max_inline;
373 u8 min_inline_mode; 370 u8 min_inline_mode;
374 u16 edge; 371 u16 edge;
375 struct device *pdev; 372 struct device *pdev;
@@ -383,6 +380,10 @@ struct mlx5e_txqsq {
383 struct mlx5e_channel *channel; 380 struct mlx5e_channel *channel;
384 int txq_ix; 381 int txq_ix;
385 u32 rate_limit; 382 u32 rate_limit;
383 struct mlx5e_txqsq_recover {
384 struct work_struct recover_work;
385 u64 last_recover;
386 } recover;
386} ____cacheline_aligned_in_smp; 387} ____cacheline_aligned_in_smp;
387 388
388struct mlx5e_xdpsq { 389struct mlx5e_xdpsq {
@@ -832,6 +833,10 @@ bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq);
832void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq); 833void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
833void mlx5e_free_xdpsq_descs(struct mlx5e_xdpsq *sq); 834void mlx5e_free_xdpsq_descs(struct mlx5e_xdpsq *sq);
834 835
836bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev);
837bool mlx5e_striding_rq_possible(struct mlx5_core_dev *mdev,
838 struct mlx5e_params *params);
839
835void mlx5e_page_release(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info, 840void mlx5e_page_release(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info,
836 bool recycle); 841 bool recycle);
837void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); 842void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
@@ -842,6 +847,11 @@ void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix);
842void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix); 847void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix);
843void mlx5e_free_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi); 848void mlx5e_free_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi);
844 849
850u8 mlx5e_mpwqe_get_log_stride_size(struct mlx5_core_dev *mdev,
851 struct mlx5e_params *params);
852u8 mlx5e_mpwqe_get_log_num_strides(struct mlx5_core_dev *mdev,
853 struct mlx5e_params *params);
854
845void mlx5e_update_stats(struct mlx5e_priv *priv); 855void mlx5e_update_stats(struct mlx5e_priv *priv);
846 856
847int mlx5e_create_flow_steering(struct mlx5e_priv *priv); 857int mlx5e_create_flow_steering(struct mlx5e_priv *priv);
@@ -917,9 +927,9 @@ void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params,
917 u8 cq_period_mode); 927 u8 cq_period_mode);
918void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, 928void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
919 u8 cq_period_mode); 929 u8 cq_period_mode);
930void mlx5e_set_rq_type(struct mlx5_core_dev *mdev, struct mlx5e_params *params);
920void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, 931void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev,
921 struct mlx5e_params *params, 932 struct mlx5e_params *params);
922 u8 rq_type);
923 933
924static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev) 934static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
925{ 935{
@@ -1011,7 +1021,6 @@ int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
1011 u16 rxq_index, u32 flow_id); 1021 u16 rxq_index, u32 flow_id);
1012#endif 1022#endif
1013 1023
1014u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev);
1015int mlx5e_create_tir(struct mlx5_core_dev *mdev, 1024int mlx5e_create_tir(struct mlx5_core_dev *mdev,
1016 struct mlx5e_tir *tir, u32 *in, int inlen); 1025 struct mlx5e_tir *tir, u32 *in, int inlen);
1017void mlx5e_destroy_tir(struct mlx5_core_dev *mdev, 1026void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index d415e67b557b..c57c929d7973 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -231,8 +231,8 @@ static u32 mlx5e_rx_wqes_to_packets(struct mlx5e_priv *priv, int rq_wq_type,
231 if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) 231 if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
232 return num_wqe; 232 return num_wqe;
233 233
234 stride_size = 1 << priv->channels.params.mpwqe_log_stride_sz; 234 stride_size = 1 << mlx5e_mpwqe_get_log_stride_size(priv->mdev, &priv->channels.params);
235 num_strides = 1 << priv->channels.params.mpwqe_log_num_strides; 235 num_strides = 1 << mlx5e_mpwqe_get_log_num_strides(priv->mdev, &priv->channels.params);
236 wqe_size = stride_size * num_strides; 236 wqe_size = stride_size * num_strides;
237 237
238 packets_per_wqe = wqe_size / 238 packets_per_wqe = wqe_size /
@@ -252,8 +252,8 @@ static u32 mlx5e_packets_to_rx_wqes(struct mlx5e_priv *priv, int rq_wq_type,
252 if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) 252 if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
253 return num_packets; 253 return num_packets;
254 254
255 stride_size = 1 << priv->channels.params.mpwqe_log_stride_sz; 255 stride_size = 1 << mlx5e_mpwqe_get_log_stride_size(priv->mdev, &priv->channels.params);
256 num_strides = 1 << priv->channels.params.mpwqe_log_num_strides; 256 num_strides = 1 << mlx5e_mpwqe_get_log_num_strides(priv->mdev, &priv->channels.params);
257 wqe_size = stride_size * num_strides; 257 wqe_size = stride_size * num_strides;
258 258
259 num_packets = (1 << order_base_2(num_packets)); 259 num_packets = (1 << order_base_2(num_packets));
@@ -1118,13 +1118,9 @@ static int mlx5e_get_tunable(struct net_device *dev,
1118 const struct ethtool_tunable *tuna, 1118 const struct ethtool_tunable *tuna,
1119 void *data) 1119 void *data)
1120{ 1120{
1121 const struct mlx5e_priv *priv = netdev_priv(dev); 1121 int err;
1122 int err = 0;
1123 1122
1124 switch (tuna->id) { 1123 switch (tuna->id) {
1125 case ETHTOOL_TX_COPYBREAK:
1126 *(u32 *)data = priv->channels.params.tx_max_inline;
1127 break;
1128 case ETHTOOL_PFC_PREVENTION_TOUT: 1124 case ETHTOOL_PFC_PREVENTION_TOUT:
1129 err = mlx5e_get_pfc_prevention_tout(dev, data); 1125 err = mlx5e_get_pfc_prevention_tout(dev, data);
1130 break; 1126 break;
@@ -1141,35 +1137,11 @@ static int mlx5e_set_tunable(struct net_device *dev,
1141 const void *data) 1137 const void *data)
1142{ 1138{
1143 struct mlx5e_priv *priv = netdev_priv(dev); 1139 struct mlx5e_priv *priv = netdev_priv(dev);
1144 struct mlx5_core_dev *mdev = priv->mdev; 1140 int err;
1145 struct mlx5e_channels new_channels = {};
1146 int err = 0;
1147 u32 val;
1148 1141
1149 mutex_lock(&priv->state_lock); 1142 mutex_lock(&priv->state_lock);
1150 1143
1151 switch (tuna->id) { 1144 switch (tuna->id) {
1152 case ETHTOOL_TX_COPYBREAK:
1153 val = *(u32 *)data;
1154 if (val > mlx5e_get_max_inline_cap(mdev)) {
1155 err = -EINVAL;
1156 break;
1157 }
1158
1159 new_channels.params = priv->channels.params;
1160 new_channels.params.tx_max_inline = val;
1161
1162 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1163 priv->channels.params = new_channels.params;
1164 break;
1165 }
1166
1167 err = mlx5e_open_channels(priv, &new_channels);
1168 if (err)
1169 break;
1170 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
1171
1172 break;
1173 case ETHTOOL_PFC_PREVENTION_TOUT: 1145 case ETHTOOL_PFC_PREVENTION_TOUT:
1174 err = mlx5e_set_pfc_prevention_tout(dev, *(u16 *)data); 1146 err = mlx5e_set_pfc_prevention_tout(dev, *(u16 *)data);
1175 break; 1147 break;
@@ -1561,11 +1533,6 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val
1561 new_channels.params = priv->channels.params; 1533 new_channels.params = priv->channels.params;
1562 MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val); 1534 MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val);
1563 1535
1564 new_channels.params.mpwqe_log_stride_sz =
1565 MLX5E_MPWQE_STRIDE_SZ(priv->mdev, new_val);
1566 new_channels.params.mpwqe_log_num_strides =
1567 MLX5_MPWRQ_LOG_WQE_SZ - new_channels.params.mpwqe_log_stride_sz;
1568
1569 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { 1536 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1570 priv->channels.params = new_channels.params; 1537 priv->channels.params = new_channels.params;
1571 return 0; 1538 return 0;
@@ -1603,6 +1570,38 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev,
1603 return 0; 1570 return 0;
1604} 1571}
1605 1572
1573static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
1574{
1575 struct mlx5e_priv *priv = netdev_priv(netdev);
1576 struct mlx5_core_dev *mdev = priv->mdev;
1577 struct mlx5e_channels new_channels = {};
1578 int err;
1579
1580 if (enable) {
1581 if (!mlx5e_check_fragmented_striding_rq_cap(mdev))
1582 return -EOPNOTSUPP;
1583 if (!mlx5e_striding_rq_possible(mdev, &priv->channels.params))
1584 return -EINVAL;
1585 }
1586
1587 new_channels.params = priv->channels.params;
1588
1589 MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_STRIDING_RQ, enable);
1590 mlx5e_set_rq_type(mdev, &new_channels.params);
1591
1592 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1593 priv->channels.params = new_channels.params;
1594 return 0;
1595 }
1596
1597 err = mlx5e_open_channels(priv, &new_channels);
1598 if (err)
1599 return err;
1600
1601 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
1602 return 0;
1603}
1604
1606static int mlx5e_handle_pflag(struct net_device *netdev, 1605static int mlx5e_handle_pflag(struct net_device *netdev,
1607 u32 wanted_flags, 1606 u32 wanted_flags,
1608 enum mlx5e_priv_flag flag, 1607 enum mlx5e_priv_flag flag,
@@ -1648,6 +1647,12 @@ static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
1648 err = mlx5e_handle_pflag(netdev, pflags, 1647 err = mlx5e_handle_pflag(netdev, pflags,
1649 MLX5E_PFLAG_RX_CQE_COMPRESS, 1648 MLX5E_PFLAG_RX_CQE_COMPRESS,
1650 set_pflag_rx_cqe_compress); 1649 set_pflag_rx_cqe_compress);
1650 if (err)
1651 goto out;
1652
1653 err = mlx5e_handle_pflag(netdev, pflags,
1654 MLX5E_PFLAG_RX_STRIDING_RQ,
1655 set_pflag_rx_striding_rq);
1651 1656
1652out: 1657out:
1653 mutex_unlock(&priv->state_lock); 1658 mutex_unlock(&priv->state_lock);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 1d36d7569f44..1b48dec67abf 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -71,56 +71,80 @@ struct mlx5e_channel_param {
71 struct mlx5e_cq_param icosq_cq; 71 struct mlx5e_cq_param icosq_cq;
72}; 72};
73 73
74static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) 74bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
75{ 75{
76 return MLX5_CAP_GEN(mdev, striding_rq) && 76 return MLX5_CAP_GEN(mdev, striding_rq) &&
77 MLX5_CAP_GEN(mdev, umr_ptr_rlky) && 77 MLX5_CAP_GEN(mdev, umr_ptr_rlky) &&
78 MLX5_CAP_ETH(mdev, reg_umr_sq); 78 MLX5_CAP_ETH(mdev, reg_umr_sq);
79} 79}
80 80
81u8 mlx5e_mpwqe_get_log_stride_size(struct mlx5_core_dev *mdev,
82 struct mlx5e_params *params)
83{
84 return MLX5E_MPWQE_STRIDE_SZ(mdev,
85 MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS));
86}
87
88u8 mlx5e_mpwqe_get_log_num_strides(struct mlx5_core_dev *mdev,
89 struct mlx5e_params *params)
90{
91 return MLX5_MPWRQ_LOG_WQE_SZ -
92 mlx5e_mpwqe_get_log_stride_size(mdev, params);
93}
94
95static u16 mlx5e_get_rq_headroom(struct mlx5e_params *params)
96{
97 u16 linear_rq_headroom = params->xdp_prog ?
98 XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM;
99
100 linear_rq_headroom += NET_IP_ALIGN;
101
102 if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST)
103 return linear_rq_headroom;
104
105 return 0;
106}
107
81void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, 108void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev,
82 struct mlx5e_params *params, u8 rq_type) 109 struct mlx5e_params *params)
83{ 110{
84 params->rq_wq_type = rq_type;
85 params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; 111 params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
86 switch (params->rq_wq_type) { 112 switch (params->rq_wq_type) {
87 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: 113 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
88 params->log_rq_size = is_kdump_kernel() ? 114 params->log_rq_size = is_kdump_kernel() ?
89 MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW : 115 MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW :
90 MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW; 116 MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW;
91 params->mpwqe_log_stride_sz = MLX5E_MPWQE_STRIDE_SZ(mdev,
92 MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS));
93 params->mpwqe_log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ -
94 params->mpwqe_log_stride_sz;
95 break; 117 break;
96 default: /* MLX5_WQ_TYPE_LINKED_LIST */ 118 default: /* MLX5_WQ_TYPE_LINKED_LIST */
97 params->log_rq_size = is_kdump_kernel() ? 119 params->log_rq_size = is_kdump_kernel() ?
98 MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE : 120 MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE :
99 MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE; 121 MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
100 params->rq_headroom = params->xdp_prog ?
101 XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM;
102 params->rq_headroom += NET_IP_ALIGN;
103 122
104 /* Extra room needed for build_skb */ 123 /* Extra room needed for build_skb */
105 params->lro_wqe_sz -= params->rq_headroom + 124 params->lro_wqe_sz -= mlx5e_get_rq_headroom(params) +
106 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); 125 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
107 } 126 }
108 127
109 mlx5_core_info(mdev, "MLX5E: StrdRq(%d) RqSz(%ld) StrdSz(%ld) RxCqeCmprss(%d)\n", 128 mlx5_core_info(mdev, "MLX5E: StrdRq(%d) RqSz(%ld) StrdSz(%ld) RxCqeCmprss(%d)\n",
110 params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ, 129 params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ,
111 BIT(params->log_rq_size), 130 BIT(params->log_rq_size),
112 BIT(params->mpwqe_log_stride_sz), 131 BIT(mlx5e_mpwqe_get_log_stride_size(mdev, params)),
113 MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); 132 MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS));
114} 133}
115 134
116static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, 135bool mlx5e_striding_rq_possible(struct mlx5_core_dev *mdev,
117 struct mlx5e_params *params) 136 struct mlx5e_params *params)
118{ 137{
119 u8 rq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) && 138 return mlx5e_check_fragmented_striding_rq_cap(mdev) &&
120 !params->xdp_prog && !MLX5_IPSEC_DEV(mdev) ? 139 !params->xdp_prog && !MLX5_IPSEC_DEV(mdev);
121 MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ : 140}
122 MLX5_WQ_TYPE_LINKED_LIST; 141
123 mlx5e_init_rq_type_params(mdev, params, rq_type); 142void mlx5e_set_rq_type(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
143{
144 params->rq_wq_type = mlx5e_striding_rq_possible(mdev, params) &&
145 MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ) ?
146 MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ :
147 MLX5_WQ_TYPE_LINKED_LIST;
124} 148}
125 149
126static void mlx5e_update_carrier(struct mlx5e_priv *priv) 150static void mlx5e_update_carrier(struct mlx5e_priv *priv)
@@ -153,26 +177,6 @@ static void mlx5e_update_carrier_work(struct work_struct *work)
153 mutex_unlock(&priv->state_lock); 177 mutex_unlock(&priv->state_lock);
154} 178}
155 179
156static void mlx5e_tx_timeout_work(struct work_struct *work)
157{
158 struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
159 tx_timeout_work);
160 int err;
161
162 rtnl_lock();
163 mutex_lock(&priv->state_lock);
164 if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
165 goto unlock;
166 mlx5e_close_locked(priv->netdev);
167 err = mlx5e_open_locked(priv->netdev);
168 if (err)
169 netdev_err(priv->netdev, "mlx5e_open_locked failed recovering from a tx_timeout, err(%d).\n",
170 err);
171unlock:
172 mutex_unlock(&priv->state_lock);
173 rtnl_unlock();
174}
175
176void mlx5e_update_stats(struct mlx5e_priv *priv) 180void mlx5e_update_stats(struct mlx5e_priv *priv)
177{ 181{
178 int i; 182 int i;
@@ -428,7 +432,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
428 goto err_rq_wq_destroy; 432 goto err_rq_wq_destroy;
429 433
430 rq->buff.map_dir = rq->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE; 434 rq->buff.map_dir = rq->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
431 rq->buff.headroom = params->rq_headroom; 435 rq->buff.headroom = mlx5e_get_rq_headroom(params);
432 436
433 switch (rq->wq_type) { 437 switch (rq->wq_type) {
434 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: 438 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
@@ -450,8 +454,8 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
450 goto err_rq_wq_destroy; 454 goto err_rq_wq_destroy;
451 } 455 }
452 456
453 rq->mpwqe.log_stride_sz = params->mpwqe_log_stride_sz; 457 rq->mpwqe.log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params);
454 rq->mpwqe.num_strides = BIT(params->mpwqe_log_num_strides); 458 rq->mpwqe.num_strides = BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params));
455 459
456 byte_count = rq->mpwqe.num_strides << rq->mpwqe.log_stride_sz; 460 byte_count = rq->mpwqe.num_strides << rq->mpwqe.log_stride_sz;
457 461
@@ -952,6 +956,7 @@ static int mlx5e_alloc_txqsq_db(struct mlx5e_txqsq *sq, int numa)
952 return 0; 956 return 0;
953} 957}
954 958
959static void mlx5e_sq_recover(struct work_struct *work);
955static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, 960static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
956 int txq_ix, 961 int txq_ix,
957 struct mlx5e_params *params, 962 struct mlx5e_params *params,
@@ -969,8 +974,8 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
969 sq->channel = c; 974 sq->channel = c;
970 sq->txq_ix = txq_ix; 975 sq->txq_ix = txq_ix;
971 sq->uar_map = mdev->mlx5e_res.bfreg.map; 976 sq->uar_map = mdev->mlx5e_res.bfreg.map;
972 sq->max_inline = params->tx_max_inline;
973 sq->min_inline_mode = params->tx_min_inline_mode; 977 sq->min_inline_mode = params->tx_min_inline_mode;
978 INIT_WORK(&sq->recover.recover_work, mlx5e_sq_recover);
974 if (MLX5_IPSEC_DEV(c->priv->mdev)) 979 if (MLX5_IPSEC_DEV(c->priv->mdev))
975 set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state); 980 set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
976 981
@@ -1037,6 +1042,7 @@ static int mlx5e_create_sq(struct mlx5_core_dev *mdev,
1037 MLX5_SET(sqc, sqc, min_wqe_inline_mode, csp->min_inline_mode); 1042 MLX5_SET(sqc, sqc, min_wqe_inline_mode, csp->min_inline_mode);
1038 1043
1039 MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST); 1044 MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
1045 MLX5_SET(sqc, sqc, flush_in_error_en, 1);
1040 1046
1041 MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC); 1047 MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
1042 MLX5_SET(wq, wq, uar_page, mdev->mlx5e_res.bfreg.index); 1048 MLX5_SET(wq, wq, uar_page, mdev->mlx5e_res.bfreg.index);
@@ -1155,9 +1161,20 @@ err_free_txqsq:
1155 return err; 1161 return err;
1156} 1162}
1157 1163
1164static void mlx5e_reset_txqsq_cc_pc(struct mlx5e_txqsq *sq)
1165{
1166 WARN_ONCE(sq->cc != sq->pc,
1167 "SQ 0x%x: cc (0x%x) != pc (0x%x)\n",
1168 sq->sqn, sq->cc, sq->pc);
1169 sq->cc = 0;
1170 sq->dma_fifo_cc = 0;
1171 sq->pc = 0;
1172}
1173
1158static void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq) 1174static void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq)
1159{ 1175{
1160 sq->txq = netdev_get_tx_queue(sq->channel->netdev, sq->txq_ix); 1176 sq->txq = netdev_get_tx_queue(sq->channel->netdev, sq->txq_ix);
1177 clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state);
1161 set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state); 1178 set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
1162 netdev_tx_reset_queue(sq->txq); 1179 netdev_tx_reset_queue(sq->txq);
1163 netif_tx_start_queue(sq->txq); 1180 netif_tx_start_queue(sq->txq);
@@ -1202,6 +1219,107 @@ static void mlx5e_close_txqsq(struct mlx5e_txqsq *sq)
1202 mlx5e_free_txqsq(sq); 1219 mlx5e_free_txqsq(sq);
1203} 1220}
1204 1221
1222static int mlx5e_wait_for_sq_flush(struct mlx5e_txqsq *sq)
1223{
1224 unsigned long exp_time = jiffies + msecs_to_jiffies(2000);
1225
1226 while (time_before(jiffies, exp_time)) {
1227 if (sq->cc == sq->pc)
1228 return 0;
1229
1230 msleep(20);
1231 }
1232
1233 netdev_err(sq->channel->netdev,
1234 "Wait for SQ 0x%x flush timeout (sq cc = 0x%x, sq pc = 0x%x)\n",
1235 sq->sqn, sq->cc, sq->pc);
1236
1237 return -ETIMEDOUT;
1238}
1239
1240static int mlx5e_sq_to_ready(struct mlx5e_txqsq *sq, int curr_state)
1241{
1242 struct mlx5_core_dev *mdev = sq->channel->mdev;
1243 struct net_device *dev = sq->channel->netdev;
1244 struct mlx5e_modify_sq_param msp = {0};
1245 int err;
1246
1247 msp.curr_state = curr_state;
1248 msp.next_state = MLX5_SQC_STATE_RST;
1249
1250 err = mlx5e_modify_sq(mdev, sq->sqn, &msp);
1251 if (err) {
1252 netdev_err(dev, "Failed to move sq 0x%x to reset\n", sq->sqn);
1253 return err;
1254 }
1255
1256 memset(&msp, 0, sizeof(msp));
1257 msp.curr_state = MLX5_SQC_STATE_RST;
1258 msp.next_state = MLX5_SQC_STATE_RDY;
1259
1260 err = mlx5e_modify_sq(mdev, sq->sqn, &msp);
1261 if (err) {
1262 netdev_err(dev, "Failed to move sq 0x%x to ready\n", sq->sqn);
1263 return err;
1264 }
1265
1266 return 0;
1267}
1268
1269static void mlx5e_sq_recover(struct work_struct *work)
1270{
1271 struct mlx5e_txqsq_recover *recover =
1272 container_of(work, struct mlx5e_txqsq_recover,
1273 recover_work);
1274 struct mlx5e_txqsq *sq = container_of(recover, struct mlx5e_txqsq,
1275 recover);
1276 struct mlx5_core_dev *mdev = sq->channel->mdev;
1277 struct net_device *dev = sq->channel->netdev;
1278 u8 state;
1279 int err;
1280
1281 err = mlx5_core_query_sq_state(mdev, sq->sqn, &state);
1282 if (err) {
1283 netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n",
1284 sq->sqn, err);
1285 return;
1286 }
1287
1288 if (state != MLX5_RQC_STATE_ERR) {
1289 netdev_err(dev, "SQ 0x%x not in ERROR state\n", sq->sqn);
1290 return;
1291 }
1292
1293 netif_tx_disable_queue(sq->txq);
1294
1295 if (mlx5e_wait_for_sq_flush(sq))
1296 return;
1297
1298 /* If the interval between two consecutive recovers per SQ is too
1299 * short, don't recover to avoid infinite loop of ERR_CQE -> recover.
1300 * If we reached this state, there is probably a bug that needs to be
1301 * fixed. let's keep the queue close and let tx timeout cleanup.
1302 */
1303 if (jiffies_to_msecs(jiffies - recover->last_recover) <
1304 MLX5E_SQ_RECOVER_MIN_INTERVAL) {
1305 netdev_err(dev, "Recover SQ 0x%x canceled, too many error CQEs\n",
1306 sq->sqn);
1307 return;
1308 }
1309
1310 /* At this point, no new packets will arrive from the stack as TXQ is
1311 * marked with QUEUE_STATE_DRV_XOFF. In addition, NAPI cleared all
1312 * pending WQEs. SQ can safely reset the SQ.
1313 */
1314 if (mlx5e_sq_to_ready(sq, state))
1315 return;
1316
1317 mlx5e_reset_txqsq_cc_pc(sq);
1318 sq->stats.recover++;
1319 recover->last_recover = jiffies;
1320 mlx5e_activate_txqsq(sq);
1321}
1322
1205static int mlx5e_open_icosq(struct mlx5e_channel *c, 1323static int mlx5e_open_icosq(struct mlx5e_channel *c,
1206 struct mlx5e_params *params, 1324 struct mlx5e_params *params,
1207 struct mlx5e_sq_param *param, 1325 struct mlx5e_sq_param *param,
@@ -1742,13 +1860,16 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
1742 struct mlx5e_params *params, 1860 struct mlx5e_params *params,
1743 struct mlx5e_rq_param *param) 1861 struct mlx5e_rq_param *param)
1744{ 1862{
1863 struct mlx5_core_dev *mdev = priv->mdev;
1745 void *rqc = param->rqc; 1864 void *rqc = param->rqc;
1746 void *wq = MLX5_ADDR_OF(rqc, rqc, wq); 1865 void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
1747 1866
1748 switch (params->rq_wq_type) { 1867 switch (params->rq_wq_type) {
1749 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: 1868 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
1750 MLX5_SET(wq, wq, log_wqe_num_of_strides, params->mpwqe_log_num_strides - 9); 1869 MLX5_SET(wq, wq, log_wqe_num_of_strides,
1751 MLX5_SET(wq, wq, log_wqe_stride_size, params->mpwqe_log_stride_sz - 6); 1870 mlx5e_mpwqe_get_log_num_strides(mdev, params) - 9);
1871 MLX5_SET(wq, wq, log_wqe_stride_size,
1872 mlx5e_mpwqe_get_log_stride_size(mdev, params) - 6);
1752 MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ); 1873 MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ);
1753 break; 1874 break;
1754 default: /* MLX5_WQ_TYPE_LINKED_LIST */ 1875 default: /* MLX5_WQ_TYPE_LINKED_LIST */
@@ -1758,12 +1879,12 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
1758 MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN); 1879 MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);
1759 MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe))); 1880 MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe)));
1760 MLX5_SET(wq, wq, log_wq_sz, params->log_rq_size); 1881 MLX5_SET(wq, wq, log_wq_sz, params->log_rq_size);
1761 MLX5_SET(wq, wq, pd, priv->mdev->mlx5e_res.pdn); 1882 MLX5_SET(wq, wq, pd, mdev->mlx5e_res.pdn);
1762 MLX5_SET(rqc, rqc, counter_set_id, priv->q_counter); 1883 MLX5_SET(rqc, rqc, counter_set_id, priv->q_counter);
1763 MLX5_SET(rqc, rqc, vsd, params->vlan_strip_disable); 1884 MLX5_SET(rqc, rqc, vsd, params->vlan_strip_disable);
1764 MLX5_SET(rqc, rqc, scatter_fcs, params->scatter_fcs_en); 1885 MLX5_SET(rqc, rqc, scatter_fcs, params->scatter_fcs_en);
1765 1886
1766 param->wq.buf_numa_node = dev_to_node(&priv->mdev->pdev->dev); 1887 param->wq.buf_numa_node = dev_to_node(&mdev->pdev->dev);
1767 param->wq.linear = 1; 1888 param->wq.linear = 1;
1768} 1889}
1769 1890
@@ -1822,7 +1943,8 @@ static void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
1822 1943
1823 switch (params->rq_wq_type) { 1944 switch (params->rq_wq_type) {
1824 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: 1945 case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
1825 log_cq_size = params->log_rq_size + params->mpwqe_log_num_strides; 1946 log_cq_size = params->log_rq_size +
1947 mlx5e_mpwqe_get_log_num_strides(priv->mdev, params);
1826 break; 1948 break;
1827 default: /* MLX5_WQ_TYPE_LINKED_LIST */ 1949 default: /* MLX5_WQ_TYPE_LINKED_LIST */
1828 log_cq_size = params->log_rq_size; 1950 log_cq_size = params->log_rq_size;
@@ -3631,13 +3753,19 @@ static bool mlx5e_tx_timeout_eq_recover(struct net_device *dev,
3631 return true; 3753 return true;
3632} 3754}
3633 3755
3634static void mlx5e_tx_timeout(struct net_device *dev) 3756static void mlx5e_tx_timeout_work(struct work_struct *work)
3635{ 3757{
3636 struct mlx5e_priv *priv = netdev_priv(dev); 3758 struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
3759 tx_timeout_work);
3760 struct net_device *dev = priv->netdev;
3637 bool reopen_channels = false; 3761 bool reopen_channels = false;
3638 int i; 3762 int i, err;
3639 3763
3640 netdev_err(dev, "TX timeout detected\n"); 3764 rtnl_lock();
3765 mutex_lock(&priv->state_lock);
3766
3767 if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
3768 goto unlock;
3641 3769
3642 for (i = 0; i < priv->channels.num * priv->channels.params.num_tc; i++) { 3770 for (i = 0; i < priv->channels.num * priv->channels.params.num_tc; i++) {
3643 struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, i); 3771 struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, i);
@@ -3645,7 +3773,9 @@ static void mlx5e_tx_timeout(struct net_device *dev)
3645 3773
3646 if (!netif_xmit_stopped(dev_queue)) 3774 if (!netif_xmit_stopped(dev_queue))
3647 continue; 3775 continue;
3648 netdev_err(dev, "TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x, usecs since last trans: %u\n", 3776
3777 netdev_err(dev,
3778 "TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x, usecs since last trans: %u\n",
3649 i, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc, 3779 i, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc,
3650 jiffies_to_usecs(jiffies - dev_queue->trans_start)); 3780 jiffies_to_usecs(jiffies - dev_queue->trans_start));
3651 3781
@@ -3658,8 +3788,27 @@ static void mlx5e_tx_timeout(struct net_device *dev)
3658 } 3788 }
3659 } 3789 }
3660 3790
3661 if (reopen_channels && test_bit(MLX5E_STATE_OPENED, &priv->state)) 3791 if (!reopen_channels)
3662 schedule_work(&priv->tx_timeout_work); 3792 goto unlock;
3793
3794 mlx5e_close_locked(dev);
3795 err = mlx5e_open_locked(dev);
3796 if (err)
3797 netdev_err(priv->netdev,
3798 "mlx5e_open_locked failed recovering from a tx_timeout, err(%d).\n",
3799 err);
3800
3801unlock:
3802 mutex_unlock(&priv->state_lock);
3803 rtnl_unlock();
3804}
3805
3806static void mlx5e_tx_timeout(struct net_device *dev)
3807{
3808 struct mlx5e_priv *priv = netdev_priv(dev);
3809
3810 netdev_err(dev, "TX timeout detected\n");
3811 queue_work(priv->wq, &priv->tx_timeout_work);
3663} 3812}
3664 3813
3665static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog) 3814static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
@@ -3709,7 +3858,7 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
3709 bpf_prog_put(old_prog); 3858 bpf_prog_put(old_prog);
3710 3859
3711 if (reset) /* change RQ type according to priv->xdp_prog */ 3860 if (reset) /* change RQ type according to priv->xdp_prog */
3712 mlx5e_set_rq_params(priv->mdev, &priv->channels.params); 3861 mlx5e_set_rq_type(priv->mdev, &priv->channels.params);
3713 3862
3714 if (was_opened && reset) 3863 if (was_opened && reset)
3715 mlx5e_open_locked(netdev); 3864 mlx5e_open_locked(netdev);
@@ -3854,15 +4003,6 @@ static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
3854 return 0; 4003 return 0;
3855} 4004}
3856 4005
3857u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)
3858{
3859 int bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
3860
3861 return bf_buf_size -
3862 sizeof(struct mlx5e_tx_wqe) +
3863 2 /*sizeof(mlx5e_tx_wqe.inline_hdr_start)*/;
3864}
3865
3866void mlx5e_build_default_indir_rqt(u32 *indirection_rqt, int len, 4006void mlx5e_build_default_indir_rqt(u32 *indirection_rqt, int len,
3867 int num_channels) 4007 int num_channels)
3868{ 4008{
@@ -3902,16 +4042,20 @@ static int mlx5e_get_pci_bw(struct mlx5_core_dev *mdev, u32 *pci_bw)
3902 return 0; 4042 return 0;
3903} 4043}
3904 4044
3905static bool cqe_compress_heuristic(u32 link_speed, u32 pci_bw) 4045static bool slow_pci_heuristic(struct mlx5_core_dev *mdev)
3906{ 4046{
3907 return (link_speed && pci_bw && 4047 u32 link_speed = 0;
3908 (pci_bw < 40000) && (pci_bw < link_speed)); 4048 u32 pci_bw = 0;
3909}
3910 4049
3911static bool hw_lro_heuristic(u32 link_speed, u32 pci_bw) 4050 mlx5e_get_max_linkspeed(mdev, &link_speed);
3912{ 4051 mlx5e_get_pci_bw(mdev, &pci_bw);
3913 return !(link_speed && pci_bw && 4052 mlx5_core_dbg_once(mdev, "Max link speed = %d, PCI BW = %d\n",
3914 (pci_bw <= 16000) && (pci_bw < link_speed)); 4053 link_speed, pci_bw);
4054
4055#define MLX5E_SLOW_PCI_RATIO (2)
4056
4057 return link_speed && pci_bw &&
4058 link_speed > MLX5E_SLOW_PCI_RATIO * pci_bw;
3915} 4059}
3916 4060
3917void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode) 4061void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
@@ -3980,17 +4124,10 @@ void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
3980 u16 max_channels) 4124 u16 max_channels)
3981{ 4125{
3982 u8 cq_period_mode = 0; 4126 u8 cq_period_mode = 0;
3983 u32 link_speed = 0;
3984 u32 pci_bw = 0;
3985 4127
3986 params->num_channels = max_channels; 4128 params->num_channels = max_channels;
3987 params->num_tc = 1; 4129 params->num_tc = 1;
3988 4130
3989 mlx5e_get_max_linkspeed(mdev, &link_speed);
3990 mlx5e_get_pci_bw(mdev, &pci_bw);
3991 mlx5_core_dbg(mdev, "Max link speed = %d, PCI BW = %d\n",
3992 link_speed, pci_bw);
3993
3994 /* SQ */ 4131 /* SQ */
3995 params->log_sq_size = is_kdump_kernel() ? 4132 params->log_sq_size = is_kdump_kernel() ?
3996 MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE : 4133 MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE :
@@ -4000,18 +4137,22 @@ void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
4000 params->rx_cqe_compress_def = false; 4137 params->rx_cqe_compress_def = false;
4001 if (MLX5_CAP_GEN(mdev, cqe_compression) && 4138 if (MLX5_CAP_GEN(mdev, cqe_compression) &&
4002 MLX5_CAP_GEN(mdev, vport_group_manager)) 4139 MLX5_CAP_GEN(mdev, vport_group_manager))
4003 params->rx_cqe_compress_def = cqe_compress_heuristic(link_speed, pci_bw); 4140 params->rx_cqe_compress_def = slow_pci_heuristic(mdev);
4004 4141
4005 MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def); 4142 MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
4006 4143
4007 /* RQ */ 4144 /* RQ */
4008 mlx5e_set_rq_params(mdev, params); 4145 if (mlx5e_striding_rq_possible(mdev, params))
4146 MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ,
4147 !slow_pci_heuristic(mdev));
4148 mlx5e_set_rq_type(mdev, params);
4149 mlx5e_init_rq_type_params(mdev, params);
4009 4150
4010 /* HW LRO */ 4151 /* HW LRO */
4011 4152
4012 /* TODO: && MLX5_CAP_ETH(mdev, lro_cap) */ 4153 /* TODO: && MLX5_CAP_ETH(mdev, lro_cap) */
4013 if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) 4154 if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
4014 params->lro_en = hw_lro_heuristic(link_speed, pci_bw); 4155 params->lro_en = !slow_pci_heuristic(mdev);
4015 params->lro_timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT); 4156 params->lro_timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT);
4016 4157
4017 /* CQ moderation params */ 4158 /* CQ moderation params */
@@ -4023,7 +4164,6 @@ void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
4023 mlx5e_set_tx_cq_mode_params(params, cq_period_mode); 4164 mlx5e_set_tx_cq_mode_params(params, cq_period_mode);
4024 4165
4025 /* TX inline */ 4166 /* TX inline */
4026 params->tx_max_inline = mlx5e_get_max_inline_cap(mdev);
4027 params->tx_min_inline_mode = mlx5e_params_calculate_tx_min_inline(mdev); 4167 params->tx_min_inline_mode = mlx5e_params_calculate_tx_min_inline(mdev);
4028 4168
4029 /* RSS */ 4169 /* RSS */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index ea4b255380a2..dd32f3e390ff 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -884,7 +884,6 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
884 params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation); 884 params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
885 mlx5e_set_rx_cq_mode_params(params, cq_period_mode); 885 mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
886 886
887 params->tx_max_inline = mlx5e_get_max_inline_cap(mdev);
888 params->num_tc = 1; 887 params->num_tc = 1;
889 params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; 888 params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
890 889
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 8cce90dc461d..781b8f21d6d1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -333,9 +333,8 @@ mlx5e_copy_skb_header_mpwqe(struct device *pdev,
333 len = ALIGN(headlen_pg, sizeof(long)); 333 len = ALIGN(headlen_pg, sizeof(long));
334 dma_sync_single_for_cpu(pdev, dma_info->addr + offset, len, 334 dma_sync_single_for_cpu(pdev, dma_info->addr + offset, len,
335 DMA_FROM_DEVICE); 335 DMA_FROM_DEVICE);
336 skb_copy_to_linear_data_offset(skb, 0, 336 skb_copy_to_linear_data(skb, page_address(dma_info->page) + offset, len);
337 page_address(dma_info->page) + offset, 337
338 len);
339 if (unlikely(offset + headlen > PAGE_SIZE)) { 338 if (unlikely(offset + headlen > PAGE_SIZE)) {
340 dma_info++; 339 dma_info++;
341 headlen_pg = len; 340 headlen_pg = len;
@@ -870,10 +869,8 @@ struct sk_buff *skb_from_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
870 data = va + rx_headroom; 869 data = va + rx_headroom;
871 frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + cqe_bcnt); 870 frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + cqe_bcnt);
872 871
873 dma_sync_single_range_for_cpu(rq->pdev, 872 dma_sync_single_range_for_cpu(rq->pdev, di->addr, wi->offset,
874 di->addr + wi->offset, 873 frag_size, DMA_FROM_DEVICE);
875 0, frag_size,
876 DMA_FROM_DEVICE);
877 prefetch(data); 874 prefetch(data);
878 wi->offset += frag_size; 875 wi->offset += frag_size;
879 876
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
index c0dab9a8969e..b08c94422907 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
@@ -60,6 +60,8 @@ static const struct counter_desc sw_stats_desc[] = {
60 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_wake) }, 60 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_wake) },
61 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_dropped) }, 61 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_dropped) },
62 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xmit_more) }, 62 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xmit_more) },
63 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_cqe_err) },
64 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_recover) },
63 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, 65 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) },
64 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler) }, 66 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler) },
65 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) }, 67 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) },
@@ -153,6 +155,8 @@ static void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv)
153 s->tx_queue_stopped += sq_stats->stopped; 155 s->tx_queue_stopped += sq_stats->stopped;
154 s->tx_queue_wake += sq_stats->wake; 156 s->tx_queue_wake += sq_stats->wake;
155 s->tx_queue_dropped += sq_stats->dropped; 157 s->tx_queue_dropped += sq_stats->dropped;
158 s->tx_cqe_err += sq_stats->cqe_err;
159 s->tx_recover += sq_stats->recover;
156 s->tx_xmit_more += sq_stats->xmit_more; 160 s->tx_xmit_more += sq_stats->xmit_more;
157 s->tx_csum_partial_inner += sq_stats->csum_partial_inner; 161 s->tx_csum_partial_inner += sq_stats->csum_partial_inner;
158 s->tx_csum_none += sq_stats->csum_none; 162 s->tx_csum_none += sq_stats->csum_none;
@@ -1103,6 +1107,8 @@ static const struct counter_desc sq_stats_desc[] = {
1103 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, wake) }, 1107 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, wake) },
1104 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, dropped) }, 1108 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, dropped) },
1105 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, xmit_more) }, 1109 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, xmit_more) },
1110 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, cqe_err) },
1111 { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, recover) },
1106}; 1112};
1107 1113
1108static const struct counter_desc ch_stats_desc[] = { 1114static const struct counter_desc ch_stats_desc[] = {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
index 43a72efa28c0..53111a2df587 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
@@ -78,6 +78,8 @@ struct mlx5e_sw_stats {
78 u64 tx_queue_wake; 78 u64 tx_queue_wake;
79 u64 tx_queue_dropped; 79 u64 tx_queue_dropped;
80 u64 tx_xmit_more; 80 u64 tx_xmit_more;
81 u64 tx_cqe_err;
82 u64 tx_recover;
81 u64 rx_wqe_err; 83 u64 rx_wqe_err;
82 u64 rx_mpwqe_filler; 84 u64 rx_mpwqe_filler;
83 u64 rx_buff_alloc_err; 85 u64 rx_buff_alloc_err;
@@ -197,6 +199,8 @@ struct mlx5e_sq_stats {
197 u64 stopped; 199 u64 stopped;
198 u64 wake; 200 u64 wake;
199 u64 dropped; 201 u64 dropped;
202 u64 cqe_err;
203 u64 recover;
200}; 204};
201 205
202struct mlx5e_ch_stats { 206struct mlx5e_ch_stats {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index 11b4f1089d1c..20297108528a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -417,6 +417,18 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev)
417 return mlx5e_sq_xmit(sq, skb, wqe, pi); 417 return mlx5e_sq_xmit(sq, skb, wqe, pi);
418} 418}
419 419
420static void mlx5e_dump_error_cqe(struct mlx5e_txqsq *sq,
421 struct mlx5_err_cqe *err_cqe)
422{
423 u32 ci = mlx5_cqwq_get_ci(&sq->cq.wq);
424
425 netdev_err(sq->channel->netdev,
426 "Error cqe on cqn 0x%x, ci 0x%x, sqn 0x%x, syndrome 0x%x, vendor syndrome 0x%x\n",
427 sq->cq.mcq.cqn, ci, sq->sqn, err_cqe->syndrome,
428 err_cqe->vendor_err_synd);
429 mlx5_dump_err_cqe(sq->cq.mdev, err_cqe);
430}
431
420bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) 432bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
421{ 433{
422 struct mlx5e_txqsq *sq; 434 struct mlx5e_txqsq *sq;
@@ -456,6 +468,17 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
456 468
457 wqe_counter = be16_to_cpu(cqe->wqe_counter); 469 wqe_counter = be16_to_cpu(cqe->wqe_counter);
458 470
471 if (unlikely(cqe->op_own >> 4 == MLX5_CQE_REQ_ERR)) {
472 if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING,
473 &sq->state)) {
474 mlx5e_dump_error_cqe(sq,
475 (struct mlx5_err_cqe *)cqe);
476 queue_work(cq->channel->priv->wq,
477 &sq->recover.recover_work);
478 }
479 sq->stats.cqe_err++;
480 }
481
459 do { 482 do {
460 struct mlx5e_tx_wqe_info *wi; 483 struct mlx5e_tx_wqe_info *wi;
461 struct sk_buff *skb; 484 struct sk_buff *skb;
@@ -509,7 +532,9 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
509 netdev_tx_completed_queue(sq->txq, npkts, nbytes); 532 netdev_tx_completed_queue(sq->txq, npkts, nbytes);
510 533
511 if (netif_tx_queue_stopped(sq->txq) && 534 if (netif_tx_queue_stopped(sq->txq) &&
512 mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, MLX5E_SQ_STOP_ROOM)) { 535 mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc,
536 MLX5E_SQ_STOP_ROOM) &&
537 !test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) {
513 netif_tx_wake_queue(sq->txq); 538 netif_tx_wake_queue(sq->txq);
514 sq->stats.wake++; 539 sq->stats.wake++;
515 } 540 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
index f953378bd13d..a35608faf8d2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
@@ -56,7 +56,9 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
56 struct mlx5e_params *params) 56 struct mlx5e_params *params)
57{ 57{
58 /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */ 58 /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */
59 mlx5e_init_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); 59 MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ, false);
60 mlx5e_set_rq_type(mdev, params);
61 mlx5e_init_rq_type_params(mdev, params);
60 62
61 /* RQ size in ipoib by default is 512 */ 63 /* RQ size in ipoib by default is 512 */
62 params->log_rq_size = is_kdump_kernel() ? 64 params->log_rq_size = is_kdump_kernel() ?
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 4e25f2b2e0bc..7d001fe6e631 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -50,6 +50,11 @@ extern uint mlx5_core_debug_mask;
50 __func__, __LINE__, current->pid, \ 50 __func__, __LINE__, current->pid, \
51 ##__VA_ARGS__) 51 ##__VA_ARGS__)
52 52
53#define mlx5_core_dbg_once(__dev, format, ...) \
54 dev_dbg_once(&(__dev)->pdev->dev, "%s:%d:(pid %d): " format, \
55 __func__, __LINE__, current->pid, \
56 ##__VA_ARGS__)
57
53#define mlx5_core_dbg_mask(__dev, mask, format, ...) \ 58#define mlx5_core_dbg_mask(__dev, mask, format, ...) \
54do { \ 59do { \
55 if ((mask) & mlx5_core_debug_mask) \ 60 if ((mask) & mlx5_core_debug_mask) \
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c
index 9e38343a951f..c64957b5ef47 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c
@@ -157,6 +157,31 @@ int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out)
157} 157}
158EXPORT_SYMBOL(mlx5_core_query_sq); 158EXPORT_SYMBOL(mlx5_core_query_sq);
159 159
160int mlx5_core_query_sq_state(struct mlx5_core_dev *dev, u32 sqn, u8 *state)
161{
162 void *out;
163 void *sqc;
164 int inlen;
165 int err;
166
167 inlen = MLX5_ST_SZ_BYTES(query_sq_out);
168 out = kvzalloc(inlen, GFP_KERNEL);
169 if (!out)
170 return -ENOMEM;
171
172 err = mlx5_core_query_sq(dev, sqn, out);
173 if (err)
174 goto out;
175
176 sqc = MLX5_ADDR_OF(query_sq_out, out, sq_context);
177 *state = MLX5_GET(sqc, sqc, state);
178
179out:
180 kvfree(out);
181 return err;
182}
183EXPORT_SYMBOL_GPL(mlx5_core_query_sq_state);
184
160int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen, 185int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
161 u32 *tirn) 186 u32 *tirn)
162{ 187{
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index 445ad194e0fe..0ef6138eca49 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -193,6 +193,12 @@ int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
193int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev, 193int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,
194 struct mlx5_core_cq *cq, u16 cq_period, 194 struct mlx5_core_cq *cq, u16 cq_period,
195 u16 cq_max_count); 195 u16 cq_max_count);
196static inline void mlx5_dump_err_cqe(struct mlx5_core_dev *dev,
197 struct mlx5_err_cqe *err_cqe)
198{
199 print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, err_cqe,
200 sizeof(*err_cqe), false);
201}
196int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); 202int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
197void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); 203void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
198 204
diff --git a/include/linux/mlx5/transobj.h b/include/linux/mlx5/transobj.h
index 7e8f281f8c00..80d7aa8b2831 100644
--- a/include/linux/mlx5/transobj.h
+++ b/include/linux/mlx5/transobj.h
@@ -47,6 +47,7 @@ int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen,
47int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen); 47int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen);
48void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn); 48void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn);
49int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out); 49int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out);
50int mlx5_core_query_sq_state(struct mlx5_core_dev *dev, u32 sqn, u8 *state);
50int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen, 51int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
51 u32 *tirn); 52 u32 *tirn);
52int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in, 53int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in,