summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c21
6 files changed, 34 insertions, 26 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 55d7bd4e210a..9129ace02560 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -815,8 +815,9 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
int err;
int i;
- priv->eq_table.uar_map = kcalloc(sizeof *priv->eq_table.uar_map,
- mlx4_num_eq_uar(dev), GFP_KERNEL);
+ priv->eq_table.uar_map = kcalloc(mlx4_num_eq_uar(dev),
+ sizeof *priv->eq_table.uar_map,
+ GFP_KERNEL);
if (!priv->eq_table.uar_map) {
err = -ENOMEM;
goto err_out_free;
@@ -1035,7 +1036,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
struct mlx4_priv *priv = mlx4_priv(dev);
int vec = 0, err = 0, i;
- spin_lock(&priv->msix_ctl.pool_lock);
+ mutex_lock(&priv->msix_ctl.pool_lock);
for (i = 0; !vec && i < dev->caps.comp_pool; i++) {
if (~priv->msix_ctl.pool_bm & 1ULL << i) {
priv->msix_ctl.pool_bm |= 1ULL << i;
@@ -1057,7 +1058,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
eq_set_ci(&priv->eq_table.eq[vec], 1);
}
}
- spin_unlock(&priv->msix_ctl.pool_lock);
+ mutex_unlock(&priv->msix_ctl.pool_lock);
if (vec) {
*vector = vec;
@@ -1078,13 +1079,13 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec)
if (likely(i >= 0)) {
/*sanity check , making sure were not trying to free irq's
Belonging to a legacy EQ*/
- spin_lock(&priv->msix_ctl.pool_lock);
+ mutex_lock(&priv->msix_ctl.pool_lock);
if (priv->msix_ctl.pool_bm & 1ULL << i) {
free_irq(priv->eq_table.eq[vec].irq,
&priv->eq_table.eq[vec]);
priv->msix_ctl.pool_bm &= ~(1ULL << i);
}
- spin_unlock(&priv->msix_ctl.pool_lock);
+ mutex_unlock(&priv->msix_ctl.pool_lock);
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 8a21e10952ea..9ea7cabcaf3c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -685,7 +685,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
return err;
}
-static int mlx4_QUERY_PORT(struct mlx4_dev *dev, void *ptr, u8 port)
+int mlx4_QUERY_PORT(struct mlx4_dev *dev, void *ptr, u8 port)
{
struct mlx4_cmd_mailbox *outbox = ptr;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 678558b502fc..d498f049c74e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -531,15 +531,14 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
for (port = 0; port < dev->caps.num_ports; port++) {
/* Change the port type only if the new type is different
* from the current, and not set to Auto */
- if (port_types[port] != dev->caps.port_type[port + 1]) {
+ if (port_types[port] != dev->caps.port_type[port + 1])
change = 1;
- dev->caps.port_type[port + 1] = port_types[port];
- }
}
if (change) {
mlx4_unregister_device(dev);
for (port = 1; port <= dev->caps.num_ports; port++) {
mlx4_CLOSE_PORT(dev, port);
+ dev->caps.port_type[port] = port_types[port - 1];
err = mlx4_SET_PORT(dev, port);
if (err) {
mlx4_err(dev, "Failed to set port %d, "
@@ -986,6 +985,9 @@ static int map_bf_area(struct mlx4_dev *dev)
resource_size_t bf_len;
int err = 0;
+ if (!dev->caps.bf_reg_size)
+ return -ENXIO;
+
bf_start = pci_resource_start(dev->pdev, 2) +
(dev->caps.num_uars << PAGE_SHIFT);
bf_len = pci_resource_len(dev->pdev, 2) -
@@ -1825,7 +1827,7 @@ slave_start:
goto err_master_mfunc;
priv->msix_ctl.pool_bm = 0;
- spin_lock_init(&priv->msix_ctl.pool_lock);
+ mutex_init(&priv->msix_ctl.pool_lock);
mlx4_enable_msi_x(dev);
if ((mlx4_is_mfunc(dev)) &&
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index c92269f8c057..28f8251561f4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -697,7 +697,7 @@ struct mlx4_sense {
struct mlx4_msix_ctl {
u64 pool_bm;
- spinlock_t pool_lock;
+ struct mutex pool_lock;
};
struct mlx4_steer {
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 8deeef98280c..25a80d71fb2a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -304,7 +304,7 @@ static int mlx4_HW2SW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
}
-static int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
+int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
u32 *base_mridx)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -320,14 +320,14 @@ static int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
}
EXPORT_SYMBOL_GPL(mlx4_mr_reserve_range);
-static void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt)
+void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt)
{
struct mlx4_priv *priv = mlx4_priv(dev);
mlx4_bitmap_free_range(&priv->mr_table.mpt_bitmap, base_mridx, cnt);
}
EXPORT_SYMBOL_GPL(mlx4_mr_release_range);
-static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
+int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
u64 iova, u64 size, u32 access, int npages,
int page_shift, struct mlx4_mr *mr)
{
@@ -457,7 +457,7 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
}
EXPORT_SYMBOL_GPL(mlx4_mr_alloc);
-static void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
+void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
{
int err;
@@ -852,7 +852,7 @@ err_free:
}
EXPORT_SYMBOL_GPL(mlx4_fmr_alloc);
-static int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
+int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
u32 pd, u32 access, int max_pages,
int max_maps, u8 page_shift, struct mlx4_fmr *fmr)
{
@@ -954,7 +954,7 @@ int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
}
EXPORT_SYMBOL_GPL(mlx4_fmr_free);
-static int mlx4_fmr_free_reserved(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
+int mlx4_fmr_free_reserved(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
{
if (fmr->maps)
return -EBUSY;
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index dcd819bfb2f0..bfdb7af19e49 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -73,6 +73,7 @@ struct res_gid {
struct list_head list;
u8 gid[16];
enum mlx4_protocol prot;
+ enum mlx4_steer_type steer;
};
enum res_qp_states {
@@ -374,6 +375,7 @@ static struct res_common *alloc_qp_tr(int id)
ret->com.res_id = id;
ret->com.state = RES_QP_RESERVED;
+ ret->local_qpn = id;
INIT_LIST_HEAD(&ret->mcg_list);
spin_lock_init(&ret->mcg_spl);
@@ -2479,7 +2481,8 @@ static struct res_gid *find_gid(struct mlx4_dev *dev, int slave,
}
static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
- u8 *gid, enum mlx4_protocol prot)
+ u8 *gid, enum mlx4_protocol prot,
+ enum mlx4_steer_type steer)
{
struct res_gid *res;
int err;
@@ -2495,6 +2498,7 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
} else {
memcpy(res->gid, gid, 16);
res->prot = prot;
+ res->steer = steer;
list_add_tail(&res->list, &rqp->mcg_list);
err = 0;
}
@@ -2504,14 +2508,15 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
}
static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
- u8 *gid, enum mlx4_protocol prot)
+ u8 *gid, enum mlx4_protocol prot,
+ enum mlx4_steer_type steer)
{
struct res_gid *res;
int err;
spin_lock_irq(&rqp->mcg_spl);
res = find_gid(dev, slave, rqp, gid);
- if (!res || res->prot != prot)
+ if (!res || res->prot != prot || res->steer != steer)
err = -EINVAL;
else {
list_del(&res->list);
@@ -2538,7 +2543,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
int attach = vhcr->op_modifier;
int block_loopback = vhcr->in_modifier >> 31;
u8 steer_type_mask = 2;
- enum mlx4_steer_type type = gid[7] & steer_type_mask;
+ enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
qpn = vhcr->in_modifier & 0xffffff;
err = get_res(dev, slave, qpn, RES_QP, &rqp);
@@ -2547,7 +2552,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
qp.qpn = qpn;
if (attach) {
- err = add_mcg_res(dev, slave, rqp, gid, prot);
+ err = add_mcg_res(dev, slave, rqp, gid, prot, type);
if (err)
goto ex_put;
@@ -2556,7 +2561,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto ex_rem;
} else {
- err = rem_mcg_res(dev, slave, rqp, gid, prot);
+ err = rem_mcg_res(dev, slave, rqp, gid, prot, type);
if (err)
goto ex_put;
err = mlx4_qp_detach_common(dev, &qp, gid, prot, type);
@@ -2567,7 +2572,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
ex_rem:
/* ignore error return below, already in error */
- err1 = rem_mcg_res(dev, slave, rqp, gid, prot);
+ err1 = rem_mcg_res(dev, slave, rqp, gid, prot, type);
ex_put:
put_res(dev, slave, qpn, RES_QP);
@@ -2606,7 +2611,7 @@ static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
qp.qpn = rqp->local_qpn;
err = mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot,
- MLX4_MC_STEER);
+ rgid->steer);
list_del(&rgid->list);
kfree(rgid);
}