aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_resources.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/intf.c54
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c89
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c3
-rw-r--r--include/linux/mlx4/device.h1
-rw-r--r--include/linux/mlx4/driver.h19
8 files changed, 177 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
index f1a5500ff72d..34f2fdf4fe5d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_resources.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
@@ -50,10 +50,14 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
50 context->mtu_msgmax = 0xff; 50 context->mtu_msgmax = 0xff;
51 if (!is_tx && !rss) 51 if (!is_tx && !rss)
52 context->rq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4); 52 context->rq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4);
53 if (is_tx) 53 if (is_tx) {
54 context->sq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4); 54 context->sq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4);
55 else 55 if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_REMAP)
56 context->params2 |= MLX4_QP_BIT_FPP;
57
58 } else {
56 context->sq_size_stride = ilog2(TXBB_SIZE) - 4; 59 context->sq_size_stride = ilog2(TXBB_SIZE) - 4;
60 }
57 context->usr_page = cpu_to_be32(mdev->priv_uar.index); 61 context->usr_page = cpu_to_be32(mdev->priv_uar.index);
58 context->local_qpn = cpu_to_be32(qpn); 62 context->local_qpn = cpu_to_be32(qpn);
59 context->pri_path.ackto = 1 & 0x07; 63 context->pri_path.ackto = 1 & 0x07;
diff --git a/drivers/net/ethernet/mellanox/mlx4/intf.c b/drivers/net/ethernet/mellanox/mlx4/intf.c
index 68d2bad325d5..6fce58718837 100644
--- a/drivers/net/ethernet/mellanox/mlx4/intf.c
+++ b/drivers/net/ethernet/mellanox/mlx4/intf.c
@@ -33,11 +33,13 @@
33 33
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/export.h> 35#include <linux/export.h>
36#include <linux/errno.h>
36 37
37#include "mlx4.h" 38#include "mlx4.h"
38 39
39struct mlx4_device_context { 40struct mlx4_device_context {
40 struct list_head list; 41 struct list_head list;
42 struct list_head bond_list;
41 struct mlx4_interface *intf; 43 struct mlx4_interface *intf;
42 void *context; 44 void *context;
43}; 45};
@@ -115,6 +117,58 @@ void mlx4_unregister_interface(struct mlx4_interface *intf)
115} 117}
116EXPORT_SYMBOL_GPL(mlx4_unregister_interface); 118EXPORT_SYMBOL_GPL(mlx4_unregister_interface);
117 119
120int mlx4_do_bond(struct mlx4_dev *dev, bool enable)
121{
122 struct mlx4_priv *priv = mlx4_priv(dev);
123 struct mlx4_device_context *dev_ctx = NULL, *temp_dev_ctx;
124 unsigned long flags;
125 int ret;
126 LIST_HEAD(bond_list);
127
128 if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_REMAP))
129 return -ENOTSUPP;
130
131 ret = mlx4_disable_rx_port_check(dev, enable);
132 if (ret) {
133 mlx4_err(dev, "Fail to %s rx port check\n",
134 enable ? "enable" : "disable");
135 return ret;
136 }
137 if (enable) {
138 dev->flags |= MLX4_FLAG_BONDED;
139 } else {
140 ret = mlx4_virt2phy_port_map(dev, 1, 2);
141 if (ret) {
142 mlx4_err(dev, "Fail to reset port map\n");
143 return ret;
144 }
145 dev->flags &= ~MLX4_FLAG_BONDED;
146 }
147
148 spin_lock_irqsave(&priv->ctx_lock, flags);
149 list_for_each_entry_safe(dev_ctx, temp_dev_ctx, &priv->ctx_list, list) {
150 if (dev_ctx->intf->flags & MLX4_INTFF_BONDING) {
151 list_add_tail(&dev_ctx->bond_list, &bond_list);
152 list_del(&dev_ctx->list);
153 }
154 }
155 spin_unlock_irqrestore(&priv->ctx_lock, flags);
156
157 list_for_each_entry(dev_ctx, &bond_list, bond_list) {
158 dev_ctx->intf->remove(dev, dev_ctx->context);
159 dev_ctx->context = dev_ctx->intf->add(dev);
160
161 spin_lock_irqsave(&priv->ctx_lock, flags);
162 list_add_tail(&dev_ctx->list, &priv->ctx_list);
163 spin_unlock_irqrestore(&priv->ctx_lock, flags);
164
165 mlx4_dbg(dev, "Inrerface for protocol %d restarted with when bonded mode is %s\n",
166 dev_ctx->intf->protocol, enable ?
167 "enabled" : "disabled");
168 }
169 return 0;
170}
171
118void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, 172void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type,
119 unsigned long param) 173 unsigned long param)
120{ 174{
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index cc9f48439244..f3245fe0f442 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1160,6 +1160,91 @@ err_set_port:
1160 return err ? err : count; 1160 return err ? err : count;
1161} 1161}
1162 1162
1163int mlx4_bond(struct mlx4_dev *dev)
1164{
1165 int ret = 0;
1166 struct mlx4_priv *priv = mlx4_priv(dev);
1167
1168 mutex_lock(&priv->bond_mutex);
1169
1170 if (!mlx4_is_bonded(dev))
1171 ret = mlx4_do_bond(dev, true);
1172 else
1173 ret = 0;
1174
1175 mutex_unlock(&priv->bond_mutex);
1176 if (ret)
1177 mlx4_err(dev, "Failed to bond device: %d\n", ret);
1178 else
1179 mlx4_dbg(dev, "Device is bonded\n");
1180 return ret;
1181}
1182EXPORT_SYMBOL_GPL(mlx4_bond);
1183
1184int mlx4_unbond(struct mlx4_dev *dev)
1185{
1186 int ret = 0;
1187 struct mlx4_priv *priv = mlx4_priv(dev);
1188
1189 mutex_lock(&priv->bond_mutex);
1190
1191 if (mlx4_is_bonded(dev))
1192 ret = mlx4_do_bond(dev, false);
1193
1194 mutex_unlock(&priv->bond_mutex);
1195 if (ret)
1196 mlx4_err(dev, "Failed to unbond device: %d\n", ret);
1197 else
1198 mlx4_dbg(dev, "Device is unbonded\n");
1199 return ret;
1200}
1201EXPORT_SYMBOL_GPL(mlx4_unbond);
1202
1203
1204int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p)
1205{
1206 u8 port1 = v2p->port1;
1207 u8 port2 = v2p->port2;
1208 struct mlx4_priv *priv = mlx4_priv(dev);
1209 int err;
1210
1211 if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_REMAP))
1212 return -ENOTSUPP;
1213
1214 mutex_lock(&priv->bond_mutex);
1215
1216 /* zero means keep current mapping for this port */
1217 if (port1 == 0)
1218 port1 = priv->v2p.port1;
1219 if (port2 == 0)
1220 port2 = priv->v2p.port2;
1221
1222 if ((port1 < 1) || (port1 > MLX4_MAX_PORTS) ||
1223 (port2 < 1) || (port2 > MLX4_MAX_PORTS) ||
1224 (port1 == 2 && port2 == 1)) {
1225 /* besides boundary checks cross mapping makes
1226 * no sense and therefore not allowed */
1227 err = -EINVAL;
1228 } else if ((port1 == priv->v2p.port1) &&
1229 (port2 == priv->v2p.port2)) {
1230 err = 0;
1231 } else {
1232 err = mlx4_virt2phy_port_map(dev, port1, port2);
1233 if (!err) {
1234 mlx4_dbg(dev, "port map changed: [%d][%d]\n",
1235 port1, port2);
1236 priv->v2p.port1 = port1;
1237 priv->v2p.port2 = port2;
1238 } else {
1239 mlx4_err(dev, "Failed to change port mape: %d\n", err);
1240 }
1241 }
1242
1243 mutex_unlock(&priv->bond_mutex);
1244 return err;
1245}
1246EXPORT_SYMBOL_GPL(mlx4_port_map_set);
1247
1163static int mlx4_load_fw(struct mlx4_dev *dev) 1248static int mlx4_load_fw(struct mlx4_dev *dev)
1164{ 1249{
1165 struct mlx4_priv *priv = mlx4_priv(dev); 1250 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -2638,6 +2723,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
2638 spin_lock_init(&priv->ctx_lock); 2723 spin_lock_init(&priv->ctx_lock);
2639 2724
2640 mutex_init(&priv->port_mutex); 2725 mutex_init(&priv->port_mutex);
2726 mutex_init(&priv->bond_mutex);
2641 2727
2642 INIT_LIST_HEAD(&priv->pgdir_list); 2728 INIT_LIST_HEAD(&priv->pgdir_list);
2643 mutex_init(&priv->pgdir_mutex); 2729 mutex_init(&priv->pgdir_mutex);
@@ -2934,6 +3020,9 @@ slave_start:
2934 goto err_port; 3020 goto err_port;
2935 } 3021 }
2936 3022
3023 priv->v2p.port1 = 1;
3024 priv->v2p.port2 = 2;
3025
2937 err = mlx4_register_device(dev); 3026 err = mlx4_register_device(dev);
2938 if (err) 3027 if (err)
2939 goto err_port; 3028 goto err_port;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 148dc0945aab..803f17653da7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -885,6 +885,8 @@ struct mlx4_priv {
885 int reserved_mtts; 885 int reserved_mtts;
886 int fs_hash_mode; 886 int fs_hash_mode;
887 u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS]; 887 u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS];
888 struct mlx4_port_map v2p; /* cached port mapping configuration */
889 struct mutex bond_mutex; /* for bond mode */
888 __be64 slave_node_guids[MLX4_MFUNC_MAX]; 890 __be64 slave_node_guids[MLX4_MFUNC_MAX];
889 891
890 atomic_t opreq_count; 892 atomic_t opreq_count;
@@ -1364,6 +1366,7 @@ int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port);
1364/* Returns the VF index of slave */ 1366/* Returns the VF index of slave */
1365int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); 1367int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave);
1366int mlx4_config_mad_demux(struct mlx4_dev *dev); 1368int mlx4_config_mad_demux(struct mlx4_dev *dev);
1369int mlx4_do_bond(struct mlx4_dev *dev, bool enable);
1367 1370
1368enum mlx4_zone_flags { 1371enum mlx4_zone_flags {
1369 MLX4_ZONE_ALLOW_ALLOC_FROM_LOWER_PRIO = 1UL << 0, 1372 MLX4_ZONE_ALLOW_ALLOC_FROM_LOWER_PRIO = 1UL << 0,
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 1586ecce13c7..2bb8553bd905 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -882,6 +882,8 @@ int mlx4_qp_to_ready(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
882 for (i = 0; i < ARRAY_SIZE(states) - 1; i++) { 882 for (i = 0; i < ARRAY_SIZE(states) - 1; i++) {
883 context->flags &= cpu_to_be32(~(0xf << 28)); 883 context->flags &= cpu_to_be32(~(0xf << 28));
884 context->flags |= cpu_to_be32(states[i + 1] << 28); 884 context->flags |= cpu_to_be32(states[i + 1] << 28);
885 if (states[i + 1] != MLX4_QP_STATE_RTR)
886 context->params2 &= ~MLX4_QP_BIT_FPP;
885 err = mlx4_qp_modify(dev, mtt, states[i], states[i + 1], 887 err = mlx4_qp_modify(dev, mtt, states[i], states[i + 1],
886 context, 0, 0, qp); 888 context, 0, 0, qp);
887 if (err) { 889 if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 79feeb6b0d87..c5f3dfca226b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2944,6 +2944,9 @@ static int verify_qp_parameters(struct mlx4_dev *dev,
2944 qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; 2944 qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
2945 optpar = be32_to_cpu(*(__be32 *) inbox->buf); 2945 optpar = be32_to_cpu(*(__be32 *) inbox->buf);
2946 2946
2947 if (slave != mlx4_master_func_num(dev))
2948 qp_ctx->params2 &= ~MLX4_QP_BIT_FPP;
2949
2947 switch (qp_type) { 2950 switch (qp_type) {
2948 case MLX4_QP_ST_RC: 2951 case MLX4_QP_ST_RC:
2949 case MLX4_QP_ST_XRC: 2952 case MLX4_QP_ST_XRC:
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index d9afd99dde39..977b0b164431 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -70,6 +70,7 @@ enum {
70 MLX4_FLAG_SLAVE = 1 << 3, 70 MLX4_FLAG_SLAVE = 1 << 3,
71 MLX4_FLAG_SRIOV = 1 << 4, 71 MLX4_FLAG_SRIOV = 1 << 4,
72 MLX4_FLAG_OLD_REG_MAC = 1 << 6, 72 MLX4_FLAG_OLD_REG_MAC = 1 << 6,
73 MLX4_FLAG_BONDED = 1 << 7
73}; 74};
74 75
75enum { 76enum {
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h
index 022055c8fb26..9553a73d2049 100644
--- a/include/linux/mlx4/driver.h
+++ b/include/linux/mlx4/driver.h
@@ -49,6 +49,10 @@ enum mlx4_dev_event {
49 MLX4_DEV_EVENT_SLAVE_SHUTDOWN, 49 MLX4_DEV_EVENT_SLAVE_SHUTDOWN,
50}; 50};
51 51
52enum {
53 MLX4_INTFF_BONDING = 1 << 0
54};
55
52struct mlx4_interface { 56struct mlx4_interface {
53 void * (*add) (struct mlx4_dev *dev); 57 void * (*add) (struct mlx4_dev *dev);
54 void (*remove)(struct mlx4_dev *dev, void *context); 58 void (*remove)(struct mlx4_dev *dev, void *context);
@@ -57,11 +61,26 @@ struct mlx4_interface {
57 void * (*get_dev)(struct mlx4_dev *dev, void *context, u8 port); 61 void * (*get_dev)(struct mlx4_dev *dev, void *context, u8 port);
58 struct list_head list; 62 struct list_head list;
59 enum mlx4_protocol protocol; 63 enum mlx4_protocol protocol;
64 int flags;
60}; 65};
61 66
62int mlx4_register_interface(struct mlx4_interface *intf); 67int mlx4_register_interface(struct mlx4_interface *intf);
63void mlx4_unregister_interface(struct mlx4_interface *intf); 68void mlx4_unregister_interface(struct mlx4_interface *intf);
64 69
70int mlx4_bond(struct mlx4_dev *dev);
71int mlx4_unbond(struct mlx4_dev *dev);
72static inline int mlx4_is_bonded(struct mlx4_dev *dev)
73{
74 return !!(dev->flags & MLX4_FLAG_BONDED);
75}
76
77struct mlx4_port_map {
78 u8 port1;
79 u8 port2;
80};
81
82int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p);
83
65void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port); 84void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port);
66 85
67static inline u64 mlx4_mac_to_u64(u8 *addr) 86static inline u64 mlx4_mac_to_u64(u8 *addr)