aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-10-29 12:00:41 -0400
committerDavid S. Miller <davem@davemloft.net>2016-10-29 12:00:41 -0400
commit58a86c45866970ebc9c8cf99fabeb82457a959c6 (patch)
tree2fbd8a81031683406fa5fbd8a50f310aea4be4fc
parentbf911e985d6bbaa328c20c3e05f4eb03de11fdd6 (diff)
parent6b276190c50a12511d889d9079ffb901ff94a822 (diff)
Merge branch 'mlx5-fixes'
Saeed Mahameed says: ==================== Mellanox 100G mlx5 fixes 2016-10-25 This series contains some bug fixes for the mlx5 core and mlx5e driver. From Daniel: - Cache line size determination at runtime, instead of using L1_CACHE_BYTES hard coded value, use cache_line_size() - Always Query HCA caps after setting them even on reset flow From Mohamad: - Reorder netdev cleanup to uregister netdev before detaching it for the kernel to not complain about open resources such as vlans - Change the acl enable prototype to return status, for better error resiliency - Clear health sick bit when starting health poll after reset flow - Fix race between PCI error handlers and health work - PCI error recovery health care simulation, in case when the kernel PCI error handlers are not triggered for some internal firmware errors From Noa: - Avoid passing dma address 0 to firmware when mapping system pages to the firmware From Paul: Some straight forward flow steering fixes - Keep autogroups list ordered - Fix autogroups groups num not decreasing - Correctly initialize last use of flow counters From Saeed: - Choose the nearest LRO timeout to the wanted one instead of blindly choosing "dev_cap.lro_timeout[2]" This series has no conflict with the for-next pull request posted earlier today ("Mellanox mlx5 core driver updates 2016-10-25"). ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/infiniband/hw/mlx5/main.c2
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/alloc.c31
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c21
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c50
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/health.c76
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c26
-rw-r--r--include/linux/mlx5/driver.h16
14 files changed, 210 insertions, 69 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 22174774dbb8..63036c731626 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1019,7 +1019,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1019 resp.qp_tab_size = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp); 1019 resp.qp_tab_size = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp);
1020 if (mlx5_core_is_pf(dev->mdev) && MLX5_CAP_GEN(dev->mdev, bf)) 1020 if (mlx5_core_is_pf(dev->mdev) && MLX5_CAP_GEN(dev->mdev, bf))
1021 resp.bf_reg_size = 1 << MLX5_CAP_GEN(dev->mdev, log_bf_reg_size); 1021 resp.bf_reg_size = 1 << MLX5_CAP_GEN(dev->mdev, log_bf_reg_size);
1022 resp.cache_line_size = L1_CACHE_BYTES; 1022 resp.cache_line_size = cache_line_size();
1023 resp.max_sq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq); 1023 resp.max_sq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq);
1024 resp.max_rq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq); 1024 resp.max_rq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq);
1025 resp.max_send_wqebb = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz); 1025 resp.max_send_wqebb = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 41f4c2afbcdd..7ce97daf26c6 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -52,7 +52,6 @@ enum {
52 52
53enum { 53enum {
54 MLX5_IB_SQ_STRIDE = 6, 54 MLX5_IB_SQ_STRIDE = 6,
55 MLX5_IB_CACHE_LINE_SIZE = 64,
56}; 55};
57 56
58static const u32 mlx5_ib_opcode[] = { 57static const u32 mlx5_ib_opcode[] = {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
index 6cb38304669f..2c6e3c7b7417 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
@@ -41,6 +41,13 @@
41 41
42#include "mlx5_core.h" 42#include "mlx5_core.h"
43 43
44struct mlx5_db_pgdir {
45 struct list_head list;
46 unsigned long *bitmap;
47 __be32 *db_page;
48 dma_addr_t db_dma;
49};
50
44/* Handling for queue buffers -- we allocate a bunch of memory and 51/* Handling for queue buffers -- we allocate a bunch of memory and
45 * register it in a memory region at HCA virtual address 0. 52 * register it in a memory region at HCA virtual address 0.
46 */ 53 */
@@ -102,17 +109,28 @@ EXPORT_SYMBOL_GPL(mlx5_buf_free);
102static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev, 109static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev,
103 int node) 110 int node)
104{ 111{
112 u32 db_per_page = PAGE_SIZE / cache_line_size();
105 struct mlx5_db_pgdir *pgdir; 113 struct mlx5_db_pgdir *pgdir;
106 114
107 pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL); 115 pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL);
108 if (!pgdir) 116 if (!pgdir)
109 return NULL; 117 return NULL;
110 118
111 bitmap_fill(pgdir->bitmap, MLX5_DB_PER_PAGE); 119 pgdir->bitmap = kcalloc(BITS_TO_LONGS(db_per_page),
120 sizeof(unsigned long),
121 GFP_KERNEL);
122
123 if (!pgdir->bitmap) {
124 kfree(pgdir);
125 return NULL;
126 }
127
128 bitmap_fill(pgdir->bitmap, db_per_page);
112 129
113 pgdir->db_page = mlx5_dma_zalloc_coherent_node(dev, PAGE_SIZE, 130 pgdir->db_page = mlx5_dma_zalloc_coherent_node(dev, PAGE_SIZE,
114 &pgdir->db_dma, node); 131 &pgdir->db_dma, node);
115 if (!pgdir->db_page) { 132 if (!pgdir->db_page) {
133 kfree(pgdir->bitmap);
116 kfree(pgdir); 134 kfree(pgdir);
117 return NULL; 135 return NULL;
118 } 136 }
@@ -123,18 +141,19 @@ static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev,
123static int mlx5_alloc_db_from_pgdir(struct mlx5_db_pgdir *pgdir, 141static int mlx5_alloc_db_from_pgdir(struct mlx5_db_pgdir *pgdir,
124 struct mlx5_db *db) 142 struct mlx5_db *db)
125{ 143{
144 u32 db_per_page = PAGE_SIZE / cache_line_size();
126 int offset; 145 int offset;
127 int i; 146 int i;
128 147
129 i = find_first_bit(pgdir->bitmap, MLX5_DB_PER_PAGE); 148 i = find_first_bit(pgdir->bitmap, db_per_page);
130 if (i >= MLX5_DB_PER_PAGE) 149 if (i >= db_per_page)
131 return -ENOMEM; 150 return -ENOMEM;
132 151
133 __clear_bit(i, pgdir->bitmap); 152 __clear_bit(i, pgdir->bitmap);
134 153
135 db->u.pgdir = pgdir; 154 db->u.pgdir = pgdir;
136 db->index = i; 155 db->index = i;
137 offset = db->index * L1_CACHE_BYTES; 156 offset = db->index * cache_line_size();
138 db->db = pgdir->db_page + offset / sizeof(*pgdir->db_page); 157 db->db = pgdir->db_page + offset / sizeof(*pgdir->db_page);
139 db->dma = pgdir->db_dma + offset; 158 db->dma = pgdir->db_dma + offset;
140 159
@@ -181,14 +200,16 @@ EXPORT_SYMBOL_GPL(mlx5_db_alloc);
181 200
182void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db) 201void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db)
183{ 202{
203 u32 db_per_page = PAGE_SIZE / cache_line_size();
184 mutex_lock(&dev->priv.pgdir_mutex); 204 mutex_lock(&dev->priv.pgdir_mutex);
185 205
186 __set_bit(db->index, db->u.pgdir->bitmap); 206 __set_bit(db->index, db->u.pgdir->bitmap);
187 207
188 if (bitmap_full(db->u.pgdir->bitmap, MLX5_DB_PER_PAGE)) { 208 if (bitmap_full(db->u.pgdir->bitmap, db_per_page)) {
189 dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, 209 dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
190 db->u.pgdir->db_page, db->u.pgdir->db_dma); 210 db->u.pgdir->db_page, db->u.pgdir->db_dma);
191 list_del(&db->u.pgdir->list); 211 list_del(&db->u.pgdir->list);
212 kfree(db->u.pgdir->bitmap);
192 kfree(db->u.pgdir); 213 kfree(db->u.pgdir);
193 } 214 }
194 215
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 460363b66cb1..7a43502a89cc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -85,6 +85,9 @@
85#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128) 85#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
86 86
87#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024) 87#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
88#define MLX5E_DEFAULT_LRO_TIMEOUT 32
89#define MLX5E_LRO_TIMEOUT_ARR_SIZE 4
90
88#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC 0x10 91#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC 0x10
89#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE 0x3 92#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE 0x3
90#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS 0x20 93#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS 0x20
@@ -221,6 +224,7 @@ struct mlx5e_params {
221 struct ieee_ets ets; 224 struct ieee_ets ets;
222#endif 225#endif
223 bool rx_am_enabled; 226 bool rx_am_enabled;
227 u32 lro_timeout;
224}; 228};
225 229
226struct mlx5e_tstamp { 230struct mlx5e_tstamp {
@@ -888,5 +892,6 @@ int mlx5e_attach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
888void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev); 892void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
889struct rtnl_link_stats64 * 893struct rtnl_link_stats64 *
890mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats); 894mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);
895u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout);
891 896
892#endif /* __MLX5_EN_H__ */ 897#endif /* __MLX5_EN_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 7eaf38020a8f..f4c687ce4c59 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1971,9 +1971,7 @@ static void mlx5e_build_tir_ctx_lro(void *tirc, struct mlx5e_priv *priv)
1971 MLX5_SET(tirc, tirc, lro_max_ip_payload_size, 1971 MLX5_SET(tirc, tirc, lro_max_ip_payload_size,
1972 (priv->params.lro_wqe_sz - 1972 (priv->params.lro_wqe_sz -
1973 ROUGH_MAX_L2_L3_HDR_SZ) >> 8); 1973 ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
1974 MLX5_SET(tirc, tirc, lro_timeout_period_usecs, 1974 MLX5_SET(tirc, tirc, lro_timeout_period_usecs, priv->params.lro_timeout);
1975 MLX5_CAP_ETH(priv->mdev,
1976 lro_timer_supported_periods[2]));
1977} 1975}
1978 1976
1979void mlx5e_build_tir_ctx_hash(void *tirc, struct mlx5e_priv *priv) 1977void mlx5e_build_tir_ctx_hash(void *tirc, struct mlx5e_priv *priv)
@@ -3401,6 +3399,18 @@ static void mlx5e_query_min_inline(struct mlx5_core_dev *mdev,
3401 } 3399 }
3402} 3400}
3403 3401
3402u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout)
3403{
3404 int i;
3405
3406 /* The supported periods are organized in ascending order */
3407 for (i = 0; i < MLX5E_LRO_TIMEOUT_ARR_SIZE - 1; i++)
3408 if (MLX5_CAP_ETH(mdev, lro_timer_supported_periods[i]) >= wanted_timeout)
3409 break;
3410
3411 return MLX5_CAP_ETH(mdev, lro_timer_supported_periods[i]);
3412}
3413
3404static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, 3414static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
3405 struct net_device *netdev, 3415 struct net_device *netdev,
3406 const struct mlx5e_profile *profile, 3416 const struct mlx5e_profile *profile,
@@ -3419,6 +3429,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
3419 priv->profile = profile; 3429 priv->profile = profile;
3420 priv->ppriv = ppriv; 3430 priv->ppriv = ppriv;
3421 3431
3432 priv->params.lro_timeout =
3433 mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT);
3434
3422 priv->params.log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE; 3435 priv->params.log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
3423 3436
3424 /* set CQE compression */ 3437 /* set CQE compression */
@@ -4035,7 +4048,6 @@ void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv)
4035 const struct mlx5e_profile *profile = priv->profile; 4048 const struct mlx5e_profile *profile = priv->profile;
4036 struct net_device *netdev = priv->netdev; 4049 struct net_device *netdev = priv->netdev;
4037 4050
4038 unregister_netdev(netdev);
4039 destroy_workqueue(priv->wq); 4051 destroy_workqueue(priv->wq);
4040 if (profile->cleanup) 4052 if (profile->cleanup)
4041 profile->cleanup(priv); 4053 profile->cleanup(priv);
@@ -4052,6 +4064,7 @@ static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
4052 for (vport = 1; vport < total_vfs; vport++) 4064 for (vport = 1; vport < total_vfs; vport++)
4053 mlx5_eswitch_unregister_vport_rep(esw, vport); 4065 mlx5_eswitch_unregister_vport_rep(esw, vport);
4054 4066
4067 unregister_netdev(priv->netdev);
4055 mlx5e_detach(mdev, vpriv); 4068 mlx5e_detach(mdev, vpriv);
4056 mlx5e_destroy_netdev(mdev, priv); 4069 mlx5e_destroy_netdev(mdev, priv);
4057} 4070}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 3c97da103d30..7fe6559e4ab3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -457,6 +457,7 @@ void mlx5e_vport_rep_unload(struct mlx5_eswitch *esw,
457 struct mlx5e_priv *priv = rep->priv_data; 457 struct mlx5e_priv *priv = rep->priv_data;
458 struct net_device *netdev = priv->netdev; 458 struct net_device *netdev = priv->netdev;
459 459
460 unregister_netdev(netdev);
460 mlx5e_detach_netdev(esw->dev, netdev); 461 mlx5e_detach_netdev(esw->dev, netdev);
461 mlx5e_destroy_netdev(esw->dev, priv); 462 mlx5e_destroy_netdev(esw->dev, priv);
462} 463}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index abbf2c369923..be1f7333ab7f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -931,8 +931,8 @@ static void esw_vport_change_handler(struct work_struct *work)
931 mutex_unlock(&esw->state_lock); 931 mutex_unlock(&esw->state_lock);
932} 932}
933 933
934static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw, 934static int esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
935 struct mlx5_vport *vport) 935 struct mlx5_vport *vport)
936{ 936{
937 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 937 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
938 struct mlx5_flow_group *vlan_grp = NULL; 938 struct mlx5_flow_group *vlan_grp = NULL;
@@ -949,9 +949,11 @@ static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
949 int table_size = 2; 949 int table_size = 2;
950 int err = 0; 950 int err = 0;
951 951
952 if (!MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support) || 952 if (!MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support))
953 !IS_ERR_OR_NULL(vport->egress.acl)) 953 return -EOPNOTSUPP;
954 return; 954
955 if (!IS_ERR_OR_NULL(vport->egress.acl))
956 return 0;
955 957
956 esw_debug(dev, "Create vport[%d] egress ACL log_max_size(%d)\n", 958 esw_debug(dev, "Create vport[%d] egress ACL log_max_size(%d)\n",
957 vport->vport, MLX5_CAP_ESW_EGRESS_ACL(dev, log_max_ft_size)); 959 vport->vport, MLX5_CAP_ESW_EGRESS_ACL(dev, log_max_ft_size));
@@ -959,12 +961,12 @@ static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
959 root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS); 961 root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS);
960 if (!root_ns) { 962 if (!root_ns) {
961 esw_warn(dev, "Failed to get E-Switch egress flow namespace\n"); 963 esw_warn(dev, "Failed to get E-Switch egress flow namespace\n");
962 return; 964 return -EIO;
963 } 965 }
964 966
965 flow_group_in = mlx5_vzalloc(inlen); 967 flow_group_in = mlx5_vzalloc(inlen);
966 if (!flow_group_in) 968 if (!flow_group_in)
967 return; 969 return -ENOMEM;
968 970
969 acl = mlx5_create_vport_flow_table(root_ns, 0, table_size, 0, vport->vport); 971 acl = mlx5_create_vport_flow_table(root_ns, 0, table_size, 0, vport->vport);
970 if (IS_ERR(acl)) { 972 if (IS_ERR(acl)) {
@@ -1009,6 +1011,7 @@ out:
1009 mlx5_destroy_flow_group(vlan_grp); 1011 mlx5_destroy_flow_group(vlan_grp);
1010 if (err && !IS_ERR_OR_NULL(acl)) 1012 if (err && !IS_ERR_OR_NULL(acl))
1011 mlx5_destroy_flow_table(acl); 1013 mlx5_destroy_flow_table(acl);
1014 return err;
1012} 1015}
1013 1016
1014static void esw_vport_cleanup_egress_rules(struct mlx5_eswitch *esw, 1017static void esw_vport_cleanup_egress_rules(struct mlx5_eswitch *esw,
@@ -1041,8 +1044,8 @@ static void esw_vport_disable_egress_acl(struct mlx5_eswitch *esw,
1041 vport->egress.acl = NULL; 1044 vport->egress.acl = NULL;
1042} 1045}
1043 1046
1044static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw, 1047static int esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
1045 struct mlx5_vport *vport) 1048 struct mlx5_vport *vport)
1046{ 1049{
1047 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1050 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1048 struct mlx5_core_dev *dev = esw->dev; 1051 struct mlx5_core_dev *dev = esw->dev;
@@ -1063,9 +1066,11 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
1063 int table_size = 4; 1066 int table_size = 4;
1064 int err = 0; 1067 int err = 0;
1065 1068
1066 if (!MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support) || 1069 if (!MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support))
1067 !IS_ERR_OR_NULL(vport->ingress.acl)) 1070 return -EOPNOTSUPP;
1068 return; 1071
1072 if (!IS_ERR_OR_NULL(vport->ingress.acl))
1073 return 0;
1069 1074
1070 esw_debug(dev, "Create vport[%d] ingress ACL log_max_size(%d)\n", 1075 esw_debug(dev, "Create vport[%d] ingress ACL log_max_size(%d)\n",
1071 vport->vport, MLX5_CAP_ESW_INGRESS_ACL(dev, log_max_ft_size)); 1076 vport->vport, MLX5_CAP_ESW_INGRESS_ACL(dev, log_max_ft_size));
@@ -1073,12 +1078,12 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
1073 root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS); 1078 root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS);
1074 if (!root_ns) { 1079 if (!root_ns) {
1075 esw_warn(dev, "Failed to get E-Switch ingress flow namespace\n"); 1080 esw_warn(dev, "Failed to get E-Switch ingress flow namespace\n");
1076 return; 1081 return -EIO;
1077 } 1082 }
1078 1083
1079 flow_group_in = mlx5_vzalloc(inlen); 1084 flow_group_in = mlx5_vzalloc(inlen);
1080 if (!flow_group_in) 1085 if (!flow_group_in)
1081 return; 1086 return -ENOMEM;
1082 1087
1083 acl = mlx5_create_vport_flow_table(root_ns, 0, table_size, 0, vport->vport); 1088 acl = mlx5_create_vport_flow_table(root_ns, 0, table_size, 0, vport->vport);
1084 if (IS_ERR(acl)) { 1089 if (IS_ERR(acl)) {
@@ -1167,6 +1172,7 @@ out:
1167 } 1172 }
1168 1173
1169 kvfree(flow_group_in); 1174 kvfree(flow_group_in);
1175 return err;
1170} 1176}
1171 1177
1172static void esw_vport_cleanup_ingress_rules(struct mlx5_eswitch *esw, 1178static void esw_vport_cleanup_ingress_rules(struct mlx5_eswitch *esw,
@@ -1225,7 +1231,13 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
1225 return 0; 1231 return 0;
1226 } 1232 }
1227 1233
1228 esw_vport_enable_ingress_acl(esw, vport); 1234 err = esw_vport_enable_ingress_acl(esw, vport);
1235 if (err) {
1236 mlx5_core_warn(esw->dev,
1237 "failed to enable ingress acl (%d) on vport[%d]\n",
1238 err, vport->vport);
1239 return err;
1240 }
1229 1241
1230 esw_debug(esw->dev, 1242 esw_debug(esw->dev,
1231 "vport[%d] configure ingress rules, vlan(%d) qos(%d)\n", 1243 "vport[%d] configure ingress rules, vlan(%d) qos(%d)\n",
@@ -1299,7 +1311,13 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw,
1299 return 0; 1311 return 0;
1300 } 1312 }
1301 1313
1302 esw_vport_enable_egress_acl(esw, vport); 1314 err = esw_vport_enable_egress_acl(esw, vport);
1315 if (err) {
1316 mlx5_core_warn(esw->dev,
1317 "failed to enable egress acl (%d) on vport[%d]\n",
1318 err, vport->vport);
1319 return err;
1320 }
1303 1321
1304 esw_debug(esw->dev, 1322 esw_debug(esw->dev,
1305 "vport[%d] configure egress rules, vlan(%d) qos(%d)\n", 1323 "vport[%d] configure egress rules, vlan(%d) qos(%d)\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 5da2cc878582..89696048b045 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -436,6 +436,9 @@ static void del_flow_group(struct fs_node *node)
436 fs_get_obj(ft, fg->node.parent); 436 fs_get_obj(ft, fg->node.parent);
437 dev = get_dev(&ft->node); 437 dev = get_dev(&ft->node);
438 438
439 if (ft->autogroup.active)
440 ft->autogroup.num_groups--;
441
439 if (mlx5_cmd_destroy_flow_group(dev, ft, fg->id)) 442 if (mlx5_cmd_destroy_flow_group(dev, ft, fg->id))
440 mlx5_core_warn(dev, "flow steering can't destroy fg %d of ft %d\n", 443 mlx5_core_warn(dev, "flow steering can't destroy fg %d of ft %d\n",
441 fg->id, ft->id); 444 fg->id, ft->id);
@@ -879,7 +882,7 @@ static struct mlx5_flow_group *create_flow_group_common(struct mlx5_flow_table *
879 tree_init_node(&fg->node, !is_auto_fg, del_flow_group); 882 tree_init_node(&fg->node, !is_auto_fg, del_flow_group);
880 tree_add_node(&fg->node, &ft->node); 883 tree_add_node(&fg->node, &ft->node);
881 /* Add node to group list */ 884 /* Add node to group list */
882 list_add(&fg->node.list, ft->node.children.prev); 885 list_add(&fg->node.list, prev_fg);
883 886
884 return fg; 887 return fg;
885} 888}
@@ -893,7 +896,7 @@ struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft,
893 return ERR_PTR(-EPERM); 896 return ERR_PTR(-EPERM);
894 897
895 lock_ref_node(&ft->node); 898 lock_ref_node(&ft->node);
896 fg = create_flow_group_common(ft, fg_in, &ft->node.children, false); 899 fg = create_flow_group_common(ft, fg_in, ft->node.children.prev, false);
897 unlock_ref_node(&ft->node); 900 unlock_ref_node(&ft->node);
898 901
899 return fg; 902 return fg;
@@ -1012,7 +1015,7 @@ static struct mlx5_flow_group *create_autogroup(struct mlx5_flow_table *ft,
1012 u32 *match_criteria) 1015 u32 *match_criteria)
1013{ 1016{
1014 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1017 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1015 struct list_head *prev = &ft->node.children; 1018 struct list_head *prev = ft->node.children.prev;
1016 unsigned int candidate_index = 0; 1019 unsigned int candidate_index = 0;
1017 struct mlx5_flow_group *fg; 1020 struct mlx5_flow_group *fg;
1018 void *match_criteria_addr; 1021 void *match_criteria_addr;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
index 3a9195b4169d..3b026c151cf2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
@@ -218,6 +218,7 @@ struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging)
218 goto err_out; 218 goto err_out;
219 219
220 if (aging) { 220 if (aging) {
221 counter->cache.lastuse = jiffies;
221 counter->aging = true; 222 counter->aging = true;
222 223
223 spin_lock(&fc_stats->addlist_lock); 224 spin_lock(&fc_stats->addlist_lock);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index 1a05fb965c8d..5bcf93422ee0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -61,10 +61,15 @@ enum {
61enum { 61enum {
62 MLX5_NIC_IFC_FULL = 0, 62 MLX5_NIC_IFC_FULL = 0,
63 MLX5_NIC_IFC_DISABLED = 1, 63 MLX5_NIC_IFC_DISABLED = 1,
64 MLX5_NIC_IFC_NO_DRAM_NIC = 2 64 MLX5_NIC_IFC_NO_DRAM_NIC = 2,
65 MLX5_NIC_IFC_INVALID = 3
65}; 66};
66 67
67static u8 get_nic_interface(struct mlx5_core_dev *dev) 68enum {
69 MLX5_DROP_NEW_HEALTH_WORK,
70};
71
72static u8 get_nic_state(struct mlx5_core_dev *dev)
68{ 73{
69 return (ioread32be(&dev->iseg->cmdq_addr_l_sz) >> 8) & 3; 74 return (ioread32be(&dev->iseg->cmdq_addr_l_sz) >> 8) & 3;
70} 75}
@@ -97,7 +102,7 @@ static int in_fatal(struct mlx5_core_dev *dev)
97 struct mlx5_core_health *health = &dev->priv.health; 102 struct mlx5_core_health *health = &dev->priv.health;
98 struct health_buffer __iomem *h = health->health; 103 struct health_buffer __iomem *h = health->health;
99 104
100 if (get_nic_interface(dev) == MLX5_NIC_IFC_DISABLED) 105 if (get_nic_state(dev) == MLX5_NIC_IFC_DISABLED)
101 return 1; 106 return 1;
102 107
103 if (ioread32be(&h->fw_ver) == 0xffffffff) 108 if (ioread32be(&h->fw_ver) == 0xffffffff)
@@ -127,7 +132,7 @@ unlock:
127 132
128static void mlx5_handle_bad_state(struct mlx5_core_dev *dev) 133static void mlx5_handle_bad_state(struct mlx5_core_dev *dev)
129{ 134{
130 u8 nic_interface = get_nic_interface(dev); 135 u8 nic_interface = get_nic_state(dev);
131 136
132 switch (nic_interface) { 137 switch (nic_interface) {
133 case MLX5_NIC_IFC_FULL: 138 case MLX5_NIC_IFC_FULL:
@@ -149,8 +154,34 @@ static void mlx5_handle_bad_state(struct mlx5_core_dev *dev)
149 mlx5_disable_device(dev); 154 mlx5_disable_device(dev);
150} 155}
151 156
157static void health_recover(struct work_struct *work)
158{
159 struct mlx5_core_health *health;
160 struct delayed_work *dwork;
161 struct mlx5_core_dev *dev;
162 struct mlx5_priv *priv;
163 u8 nic_state;
164
165 dwork = container_of(work, struct delayed_work, work);
166 health = container_of(dwork, struct mlx5_core_health, recover_work);
167 priv = container_of(health, struct mlx5_priv, health);
168 dev = container_of(priv, struct mlx5_core_dev, priv);
169
170 nic_state = get_nic_state(dev);
171 if (nic_state == MLX5_NIC_IFC_INVALID) {
172 dev_err(&dev->pdev->dev, "health recovery flow aborted since the nic state is invalid\n");
173 return;
174 }
175
176 dev_err(&dev->pdev->dev, "starting health recovery flow\n");
177 mlx5_recover_device(dev);
178}
179
180/* How much time to wait until health resetting the driver (in msecs) */
181#define MLX5_RECOVERY_DELAY_MSECS 60000
152static void health_care(struct work_struct *work) 182static void health_care(struct work_struct *work)
153{ 183{
184 unsigned long recover_delay = msecs_to_jiffies(MLX5_RECOVERY_DELAY_MSECS);
154 struct mlx5_core_health *health; 185 struct mlx5_core_health *health;
155 struct mlx5_core_dev *dev; 186 struct mlx5_core_dev *dev;
156 struct mlx5_priv *priv; 187 struct mlx5_priv *priv;
@@ -160,6 +191,14 @@ static void health_care(struct work_struct *work)
160 dev = container_of(priv, struct mlx5_core_dev, priv); 191 dev = container_of(priv, struct mlx5_core_dev, priv);
161 mlx5_core_warn(dev, "handling bad device here\n"); 192 mlx5_core_warn(dev, "handling bad device here\n");
162 mlx5_handle_bad_state(dev); 193 mlx5_handle_bad_state(dev);
194
195 spin_lock(&health->wq_lock);
196 if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags))
197 schedule_delayed_work(&health->recover_work, recover_delay);
198 else
199 dev_err(&dev->pdev->dev,
200 "new health works are not permitted at this stage\n");
201 spin_unlock(&health->wq_lock);
163} 202}
164 203
165static const char *hsynd_str(u8 synd) 204static const char *hsynd_str(u8 synd)
@@ -272,7 +311,13 @@ static void poll_health(unsigned long data)
272 if (in_fatal(dev) && !health->sick) { 311 if (in_fatal(dev) && !health->sick) {
273 health->sick = true; 312 health->sick = true;
274 print_health_info(dev); 313 print_health_info(dev);
275 schedule_work(&health->work); 314 spin_lock(&health->wq_lock);
315 if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags))
316 queue_work(health->wq, &health->work);
317 else
318 dev_err(&dev->pdev->dev,
319 "new health works are not permitted at this stage\n");
320 spin_unlock(&health->wq_lock);
276 } 321 }
277} 322}
278 323
@@ -281,6 +326,8 @@ void mlx5_start_health_poll(struct mlx5_core_dev *dev)
281 struct mlx5_core_health *health = &dev->priv.health; 326 struct mlx5_core_health *health = &dev->priv.health;
282 327
283 init_timer(&health->timer); 328 init_timer(&health->timer);
329 health->sick = 0;
330 clear_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
284 health->health = &dev->iseg->health; 331 health->health = &dev->iseg->health;
285 health->health_counter = &dev->iseg->health_counter; 332 health->health_counter = &dev->iseg->health_counter;
286 333
@@ -297,11 +344,22 @@ void mlx5_stop_health_poll(struct mlx5_core_dev *dev)
297 del_timer_sync(&health->timer); 344 del_timer_sync(&health->timer);
298} 345}
299 346
347void mlx5_drain_health_wq(struct mlx5_core_dev *dev)
348{
349 struct mlx5_core_health *health = &dev->priv.health;
350
351 spin_lock(&health->wq_lock);
352 set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
353 spin_unlock(&health->wq_lock);
354 cancel_delayed_work_sync(&health->recover_work);
355 cancel_work_sync(&health->work);
356}
357
300void mlx5_health_cleanup(struct mlx5_core_dev *dev) 358void mlx5_health_cleanup(struct mlx5_core_dev *dev)
301{ 359{
302 struct mlx5_core_health *health = &dev->priv.health; 360 struct mlx5_core_health *health = &dev->priv.health;
303 361
304 flush_work(&health->work); 362 destroy_workqueue(health->wq);
305} 363}
306 364
307int mlx5_health_init(struct mlx5_core_dev *dev) 365int mlx5_health_init(struct mlx5_core_dev *dev)
@@ -316,9 +374,13 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
316 374
317 strcpy(name, "mlx5_health"); 375 strcpy(name, "mlx5_health");
318 strcat(name, dev_name(&dev->pdev->dev)); 376 strcat(name, dev_name(&dev->pdev->dev));
377 health->wq = create_singlethread_workqueue(name);
319 kfree(name); 378 kfree(name);
320 379 if (!health->wq)
380 return -ENOMEM;
381 spin_lock_init(&health->wq_lock);
321 INIT_WORK(&health->work, health_care); 382 INIT_WORK(&health->work, health_care);
383 INIT_DELAYED_WORK(&health->recover_work, health_recover);
322 384
323 return 0; 385 return 0;
324} 386}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index d9c3c70b29e4..d5433c49b2b0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -844,12 +844,6 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
844 struct pci_dev *pdev = dev->pdev; 844 struct pci_dev *pdev = dev->pdev;
845 int err; 845 int err;
846 846
847 err = mlx5_query_hca_caps(dev);
848 if (err) {
849 dev_err(&pdev->dev, "query hca failed\n");
850 goto out;
851 }
852
853 err = mlx5_query_board_id(dev); 847 err = mlx5_query_board_id(dev);
854 if (err) { 848 if (err) {
855 dev_err(&pdev->dev, "query board id failed\n"); 849 dev_err(&pdev->dev, "query board id failed\n");
@@ -1023,6 +1017,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
1023 1017
1024 mlx5_start_health_poll(dev); 1018 mlx5_start_health_poll(dev);
1025 1019
1020 err = mlx5_query_hca_caps(dev);
1021 if (err) {
1022 dev_err(&pdev->dev, "query hca failed\n");
1023 goto err_stop_poll;
1024 }
1025
1026 if (boot && mlx5_init_once(dev, priv)) { 1026 if (boot && mlx5_init_once(dev, priv)) {
1027 dev_err(&pdev->dev, "sw objs init failed\n"); 1027 dev_err(&pdev->dev, "sw objs init failed\n");
1028 goto err_stop_poll; 1028 goto err_stop_poll;
@@ -1313,10 +1313,16 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
1313 struct mlx5_priv *priv = &dev->priv; 1313 struct mlx5_priv *priv = &dev->priv;
1314 1314
1315 dev_info(&pdev->dev, "%s was called\n", __func__); 1315 dev_info(&pdev->dev, "%s was called\n", __func__);
1316
1316 mlx5_enter_error_state(dev); 1317 mlx5_enter_error_state(dev);
1317 mlx5_unload_one(dev, priv, false); 1318 mlx5_unload_one(dev, priv, false);
1318 pci_save_state(pdev); 1319 /* In case of kernel call save the pci state and drain health wq */
1319 mlx5_pci_disable_device(dev); 1320 if (state) {
1321 pci_save_state(pdev);
1322 mlx5_drain_health_wq(dev);
1323 mlx5_pci_disable_device(dev);
1324 }
1325
1320 return state == pci_channel_io_perm_failure ? 1326 return state == pci_channel_io_perm_failure ?
1321 PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; 1327 PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
1322} 1328}
@@ -1373,11 +1379,6 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
1373 return PCI_ERS_RESULT_RECOVERED; 1379 return PCI_ERS_RESULT_RECOVERED;
1374} 1380}
1375 1381
1376void mlx5_disable_device(struct mlx5_core_dev *dev)
1377{
1378 mlx5_pci_err_detected(dev->pdev, 0);
1379}
1380
1381static void mlx5_pci_resume(struct pci_dev *pdev) 1382static void mlx5_pci_resume(struct pci_dev *pdev)
1382{ 1383{
1383 struct mlx5_core_dev *dev = pci_get_drvdata(pdev); 1384 struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
@@ -1427,6 +1428,18 @@ static const struct pci_device_id mlx5_core_pci_table[] = {
1427 1428
1428MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table); 1429MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table);
1429 1430
1431void mlx5_disable_device(struct mlx5_core_dev *dev)
1432{
1433 mlx5_pci_err_detected(dev->pdev, 0);
1434}
1435
1436void mlx5_recover_device(struct mlx5_core_dev *dev)
1437{
1438 mlx5_pci_disable_device(dev);
1439 if (mlx5_pci_slot_reset(dev->pdev) == PCI_ERS_RESULT_RECOVERED)
1440 mlx5_pci_resume(dev->pdev);
1441}
1442
1430static struct pci_driver mlx5_core_driver = { 1443static struct pci_driver mlx5_core_driver = {
1431 .name = DRIVER_NAME, 1444 .name = DRIVER_NAME,
1432 .id_table = mlx5_core_pci_table, 1445 .id_table = mlx5_core_pci_table,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 3d0cfb9f18f9..187662c8ea96 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -83,6 +83,7 @@ void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
83 unsigned long param); 83 unsigned long param);
84void mlx5_enter_error_state(struct mlx5_core_dev *dev); 84void mlx5_enter_error_state(struct mlx5_core_dev *dev);
85void mlx5_disable_device(struct mlx5_core_dev *dev); 85void mlx5_disable_device(struct mlx5_core_dev *dev);
86void mlx5_recover_device(struct mlx5_core_dev *dev);
86int mlx5_sriov_init(struct mlx5_core_dev *dev); 87int mlx5_sriov_init(struct mlx5_core_dev *dev);
87void mlx5_sriov_cleanup(struct mlx5_core_dev *dev); 88void mlx5_sriov_cleanup(struct mlx5_core_dev *dev);
88int mlx5_sriov_attach(struct mlx5_core_dev *dev); 89int mlx5_sriov_attach(struct mlx5_core_dev *dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index cc4fd61914d3..a57d5a81eb05 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -209,6 +209,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr)
209static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id) 209static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
210{ 210{
211 struct page *page; 211 struct page *page;
212 u64 zero_addr = 1;
212 u64 addr; 213 u64 addr;
213 int err; 214 int err;
214 int nid = dev_to_node(&dev->pdev->dev); 215 int nid = dev_to_node(&dev->pdev->dev);
@@ -218,26 +219,35 @@ static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
218 mlx5_core_warn(dev, "failed to allocate page\n"); 219 mlx5_core_warn(dev, "failed to allocate page\n");
219 return -ENOMEM; 220 return -ENOMEM;
220 } 221 }
222map:
221 addr = dma_map_page(&dev->pdev->dev, page, 0, 223 addr = dma_map_page(&dev->pdev->dev, page, 0,
222 PAGE_SIZE, DMA_BIDIRECTIONAL); 224 PAGE_SIZE, DMA_BIDIRECTIONAL);
223 if (dma_mapping_error(&dev->pdev->dev, addr)) { 225 if (dma_mapping_error(&dev->pdev->dev, addr)) {
224 mlx5_core_warn(dev, "failed dma mapping page\n"); 226 mlx5_core_warn(dev, "failed dma mapping page\n");
225 err = -ENOMEM; 227 err = -ENOMEM;
226 goto out_alloc; 228 goto err_mapping;
227 } 229 }
230
231 /* Firmware doesn't support page with physical address 0 */
232 if (addr == 0) {
233 zero_addr = addr;
234 goto map;
235 }
236
228 err = insert_page(dev, addr, page, func_id); 237 err = insert_page(dev, addr, page, func_id);
229 if (err) { 238 if (err) {
230 mlx5_core_err(dev, "failed to track allocated page\n"); 239 mlx5_core_err(dev, "failed to track allocated page\n");
231 goto out_mapping; 240 dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE,
241 DMA_BIDIRECTIONAL);
232 } 242 }
233 243
234 return 0; 244err_mapping:
235 245 if (err)
236out_mapping: 246 __free_page(page);
237 dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
238 247
239out_alloc: 248 if (zero_addr == 0)
240 __free_page(page); 249 dma_unmap_page(&dev->pdev->dev, zero_addr, PAGE_SIZE,
250 DMA_BIDIRECTIONAL);
241 251
242 return err; 252 return err;
243} 253}
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 85c4786427e4..ecc451d89ccd 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -418,8 +418,12 @@ struct mlx5_core_health {
418 u32 prev; 418 u32 prev;
419 int miss_counter; 419 int miss_counter;
420 bool sick; 420 bool sick;
421 /* wq spinlock to synchronize draining */
422 spinlock_t wq_lock;
421 struct workqueue_struct *wq; 423 struct workqueue_struct *wq;
424 unsigned long flags;
422 struct work_struct work; 425 struct work_struct work;
426 struct delayed_work recover_work;
423}; 427};
424 428
425struct mlx5_cq_table { 429struct mlx5_cq_table {
@@ -626,10 +630,6 @@ struct mlx5_db {
626}; 630};
627 631
628enum { 632enum {
629 MLX5_DB_PER_PAGE = PAGE_SIZE / L1_CACHE_BYTES,
630};
631
632enum {
633 MLX5_COMP_EQ_SIZE = 1024, 633 MLX5_COMP_EQ_SIZE = 1024,
634}; 634};
635 635
@@ -638,13 +638,6 @@ enum {
638 MLX5_PTYS_EN = 1 << 2, 638 MLX5_PTYS_EN = 1 << 2,
639}; 639};
640 640
641struct mlx5_db_pgdir {
642 struct list_head list;
643 DECLARE_BITMAP(bitmap, MLX5_DB_PER_PAGE);
644 __be32 *db_page;
645 dma_addr_t db_dma;
646};
647
648typedef void (*mlx5_cmd_cbk_t)(int status, void *context); 641typedef void (*mlx5_cmd_cbk_t)(int status, void *context);
649 642
650struct mlx5_cmd_work_ent { 643struct mlx5_cmd_work_ent {
@@ -789,6 +782,7 @@ void mlx5_health_cleanup(struct mlx5_core_dev *dev);
789int mlx5_health_init(struct mlx5_core_dev *dev); 782int mlx5_health_init(struct mlx5_core_dev *dev);
790void mlx5_start_health_poll(struct mlx5_core_dev *dev); 783void mlx5_start_health_poll(struct mlx5_core_dev *dev);
791void mlx5_stop_health_poll(struct mlx5_core_dev *dev); 784void mlx5_stop_health_poll(struct mlx5_core_dev *dev);
785void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
792int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size, 786int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
793 struct mlx5_buf *buf, int node); 787 struct mlx5_buf *buf, int node);
794int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf); 788int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf);