aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/cmd.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c196
1 files changed, 191 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 0e572a527154..299d0184f983 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -39,6 +39,7 @@
39#include <linux/errno.h> 39#include <linux/errno.h>
40 40
41#include <linux/mlx4/cmd.h> 41#include <linux/mlx4/cmd.h>
42#include <linux/mlx4/device.h>
42#include <linux/semaphore.h> 43#include <linux/semaphore.h>
43#include <rdma/ib_smi.h> 44#include <rdma/ib_smi.h>
44 45
@@ -111,6 +112,14 @@ enum {
111 GO_BIT_TIMEOUT_MSECS = 10000 112 GO_BIT_TIMEOUT_MSECS = 10000
112}; 113};
113 114
115enum mlx4_vlan_transition {
116 MLX4_VLAN_TRANSITION_VST_VST = 0,
117 MLX4_VLAN_TRANSITION_VST_VGT = 1,
118 MLX4_VLAN_TRANSITION_VGT_VST = 2,
119 MLX4_VLAN_TRANSITION_VGT_VGT = 3,
120};
121
122
114struct mlx4_cmd_context { 123struct mlx4_cmd_context {
115 struct completion done; 124 struct completion done;
116 int result; 125 int result;
@@ -256,6 +265,8 @@ static int mlx4_comm_cmd_wait(struct mlx4_dev *dev, u8 op,
256 265
257 if (!wait_for_completion_timeout(&context->done, 266 if (!wait_for_completion_timeout(&context->done,
258 msecs_to_jiffies(timeout))) { 267 msecs_to_jiffies(timeout))) {
268 mlx4_warn(dev, "communication channel command 0x%x timed out\n",
269 op);
259 err = -EBUSY; 270 err = -EBUSY;
260 goto out; 271 goto out;
261 } 272 }
@@ -485,6 +496,8 @@ static int mlx4_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
485 } 496 }
486 497
487 if (cmd_pending(dev)) { 498 if (cmd_pending(dev)) {
499 mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n",
500 op);
488 err = -ETIMEDOUT; 501 err = -ETIMEDOUT;
489 goto out; 502 goto out;
490 } 503 }
@@ -548,6 +561,8 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
548 561
549 if (!wait_for_completion_timeout(&context->done, 562 if (!wait_for_completion_timeout(&context->done,
550 msecs_to_jiffies(timeout))) { 563 msecs_to_jiffies(timeout))) {
564 mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n",
565 op);
551 err = -EBUSY; 566 err = -EBUSY;
552 goto out; 567 goto out;
553 } 568 }
@@ -785,6 +800,15 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
785 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 800 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
786} 801}
787 802
803int MLX4_CMD_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
804 struct mlx4_vhcr *vhcr,
805 struct mlx4_cmd_mailbox *inbox,
806 struct mlx4_cmd_mailbox *outbox,
807 struct mlx4_cmd_info *cmd)
808{
809 return -EPERM;
810}
811
788int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave, 812int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave,
789 struct mlx4_vhcr *vhcr, 813 struct mlx4_vhcr *vhcr,
790 struct mlx4_cmd_mailbox *inbox, 814 struct mlx4_cmd_mailbox *inbox,
@@ -1219,6 +1243,15 @@ static struct mlx4_cmd_info cmd_info[] = {
1219 .wrapper = mlx4_GEN_QP_wrapper 1243 .wrapper = mlx4_GEN_QP_wrapper
1220 }, 1244 },
1221 { 1245 {
1246 .opcode = MLX4_CMD_UPDATE_QP,
1247 .has_inbox = false,
1248 .has_outbox = false,
1249 .out_is_imm = false,
1250 .encode_slave_id = false,
1251 .verify = NULL,
1252 .wrapper = MLX4_CMD_UPDATE_QP_wrapper
1253 },
1254 {
1222 .opcode = MLX4_CMD_CONF_SPECIAL_QP, 1255 .opcode = MLX4_CMD_CONF_SPECIAL_QP,
1223 .has_inbox = false, 1256 .has_inbox = false,
1224 .has_outbox = false, 1257 .has_outbox = false,
@@ -1488,6 +1521,102 @@ out:
1488 return ret; 1521 return ret;
1489} 1522}
1490 1523
1524static int calculate_transition(u16 oper_vlan, u16 admin_vlan)
1525{
1526 return (2 * (oper_vlan == MLX4_VGT) + (admin_vlan == MLX4_VGT));
1527}
1528
1529int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv,
1530 int slave, int port)
1531{
1532 struct mlx4_vport_oper_state *vp_oper;
1533 struct mlx4_vport_state *vp_admin;
1534 struct mlx4_vf_immed_vlan_work *work;
1535 struct mlx4_dev *dev = &(priv->dev);
1536 int err;
1537 int admin_vlan_ix = NO_INDX;
1538 enum mlx4_vlan_transition vlan_trans;
1539
1540 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1541 vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
1542
1543 if (vp_oper->state.default_vlan == vp_admin->default_vlan &&
1544 vp_oper->state.default_qos == vp_admin->default_qos &&
1545 vp_oper->state.link_state == vp_admin->link_state)
1546 return 0;
1547
1548 vlan_trans = calculate_transition(vp_oper->state.default_vlan,
1549 vp_admin->default_vlan);
1550
1551 if (!(priv->mfunc.master.slave_state[slave].active &&
1552 dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP &&
1553 vlan_trans == MLX4_VLAN_TRANSITION_VST_VST)) {
1554 /* even if the UPDATE_QP command isn't supported, we still want
1555 * to set this VF link according to the admin directive
1556 */
1557 vp_oper->state.link_state = vp_admin->link_state;
1558 return -1;
1559 }
1560
1561 mlx4_dbg(dev, "updating immediately admin params slave %d port %d\n",
1562 slave, port);
1563 mlx4_dbg(dev, "vlan %d QoS %d link down %d\n", vp_admin->default_vlan,
1564 vp_admin->default_qos, vp_admin->link_state);
1565
1566 work = kzalloc(sizeof(*work), GFP_KERNEL);
1567 if (!work)
1568 return -ENOMEM;
1569
1570 if (vp_oper->state.default_vlan != vp_admin->default_vlan) {
1571 err = __mlx4_register_vlan(&priv->dev, port,
1572 vp_admin->default_vlan,
1573 &admin_vlan_ix);
1574 if (err) {
1575 kfree(work);
1576 mlx4_warn((&priv->dev),
1577 "No vlan resources slave %d, port %d\n",
1578 slave, port);
1579 return err;
1580 }
1581 work->flags |= MLX4_VF_IMMED_VLAN_FLAG_VLAN;
1582 mlx4_dbg((&(priv->dev)),
1583 "alloc vlan %d idx %d slave %d port %d\n",
1584 (int)(vp_admin->default_vlan),
1585 admin_vlan_ix, slave, port);
1586 }
1587
1588 /* save original vlan ix and vlan id */
1589 work->orig_vlan_id = vp_oper->state.default_vlan;
1590 work->orig_vlan_ix = vp_oper->vlan_idx;
1591
1592 /* handle new qos */
1593 if (vp_oper->state.default_qos != vp_admin->default_qos)
1594 work->flags |= MLX4_VF_IMMED_VLAN_FLAG_QOS;
1595
1596 if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN)
1597 vp_oper->vlan_idx = admin_vlan_ix;
1598
1599 vp_oper->state.default_vlan = vp_admin->default_vlan;
1600 vp_oper->state.default_qos = vp_admin->default_qos;
1601 vp_oper->state.link_state = vp_admin->link_state;
1602
1603 if (vp_admin->link_state == IFLA_VF_LINK_STATE_DISABLE)
1604 work->flags |= MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE;
1605
1606 /* iterate over QPs owned by this slave, using UPDATE_QP */
1607 work->port = port;
1608 work->slave = slave;
1609 work->qos = vp_oper->state.default_qos;
1610 work->vlan_id = vp_oper->state.default_vlan;
1611 work->vlan_ix = vp_oper->vlan_idx;
1612 work->priv = priv;
1613 INIT_WORK(&work->work, mlx4_vf_immed_vlan_work_handler);
1614 queue_work(priv->mfunc.master.comm_wq, &work->work);
1615
1616 return 0;
1617}
1618
1619
1491static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave) 1620static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
1492{ 1621{
1493 int port, err; 1622 int port, err;
@@ -2102,10 +2231,12 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
2102} 2231}
2103EXPORT_SYMBOL_GPL(mlx4_set_vf_mac); 2232EXPORT_SYMBOL_GPL(mlx4_set_vf_mac);
2104 2233
2234
2105int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos) 2235int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2106{ 2236{
2107 struct mlx4_priv *priv = mlx4_priv(dev); 2237 struct mlx4_priv *priv = mlx4_priv(dev);
2108 struct mlx4_vport_state *s_info; 2238 struct mlx4_vport_oper_state *vf_oper;
2239 struct mlx4_vport_state *vf_admin;
2109 int slave; 2240 int slave;
2110 2241
2111 if ((!mlx4_is_master(dev)) || 2242 if ((!mlx4_is_master(dev)) ||
@@ -2119,12 +2250,19 @@ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2119 if (slave < 0) 2250 if (slave < 0)
2120 return -EINVAL; 2251 return -EINVAL;
2121 2252
2122 s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; 2253 vf_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
2254 vf_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
2255
2123 if ((0 == vlan) && (0 == qos)) 2256 if ((0 == vlan) && (0 == qos))
2124 s_info->default_vlan = MLX4_VGT; 2257 vf_admin->default_vlan = MLX4_VGT;
2125 else 2258 else
2126 s_info->default_vlan = vlan; 2259 vf_admin->default_vlan = vlan;
2127 s_info->default_qos = qos; 2260 vf_admin->default_qos = qos;
2261
2262 if (mlx4_master_immediate_activate_vlan_qos(priv, slave, port))
2263 mlx4_info(dev,
2264 "updating vf %d port %d config will take effect on next VF restart\n",
2265 vf, port);
2128 return 0; 2266 return 0;
2129} 2267}
2130EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan); 2268EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
@@ -2178,7 +2316,55 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
2178 ivf->qos = s_info->default_qos; 2316 ivf->qos = s_info->default_qos;
2179 ivf->tx_rate = s_info->tx_rate; 2317 ivf->tx_rate = s_info->tx_rate;
2180 ivf->spoofchk = s_info->spoofchk; 2318 ivf->spoofchk = s_info->spoofchk;
2319 ivf->linkstate = s_info->link_state;
2181 2320
2182 return 0; 2321 return 0;
2183} 2322}
2184EXPORT_SYMBOL_GPL(mlx4_get_vf_config); 2323EXPORT_SYMBOL_GPL(mlx4_get_vf_config);
2324
2325int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state)
2326{
2327 struct mlx4_priv *priv = mlx4_priv(dev);
2328 struct mlx4_vport_state *s_info;
2329 int slave;
2330 u8 link_stat_event;
2331
2332 slave = mlx4_get_slave_indx(dev, vf);
2333 if (slave < 0)
2334 return -EINVAL;
2335
2336 switch (link_state) {
2337 case IFLA_VF_LINK_STATE_AUTO:
2338 /* get current link state */
2339 if (!priv->sense.do_sense_port[port])
2340 link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE;
2341 else
2342 link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN;
2343 break;
2344
2345 case IFLA_VF_LINK_STATE_ENABLE:
2346 link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE;
2347 break;
2348
2349 case IFLA_VF_LINK_STATE_DISABLE:
2350 link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN;
2351 break;
2352
2353 default:
2354 mlx4_warn(dev, "unknown value for link_state %02x on slave %d port %d\n",
2355 link_state, slave, port);
2356 return -EINVAL;
2357 };
2358 s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
2359 s_info->link_state = link_state;
2360
2361 /* send event */
2362 mlx4_gen_port_state_change_eqe(dev, slave, port, link_stat_event);
2363
2364 if (mlx4_master_immediate_activate_vlan_qos(priv, slave, port))
2365 mlx4_dbg(dev,
2366 "updating vf %d port %d no link state HW enforcment\n",
2367 vf, port);
2368 return 0;
2369}
2370EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);