aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2013-06-27 12:05:21 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-01 16:10:22 -0400
commitb01978cacfd7e3a4ca703b0e48f2e18de8865df5 (patch)
tree73beae91335dbcf4a4129b3970be68f1082aff0b /drivers/net/ethernet
parent4e144d3a807d6d2aa03d2cb234d88ef1a140e8c3 (diff)
net/mlx4_core: Dynamic VST to VST vlan/qos changes
Within VST mode, enable modifying the vlan and/or qos for a VF without requiring unbind/rebind. This requires firmware which supports the UPDATE_QP command. (If the command is not available, we fall back to requiring unbind/bind to activate these changes). To avoid race conditions with modify-qp on QPs that are affected by update-qp, this operation is performed on the comm_wq. If the update operation succeeds for all the necessary QPs, a vlan_unregister is performed for the abandoned vlan id. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c122
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h20
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c145
4 files changed, 282 insertions, 10 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index df04c8206ebe..7b927891dc35 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -112,6 +112,14 @@ enum {
112 GO_BIT_TIMEOUT_MSECS = 10000 112 GO_BIT_TIMEOUT_MSECS = 10000
113}; 113};
114 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
115struct mlx4_cmd_context { 123struct mlx4_cmd_context {
116 struct completion done; 124 struct completion done;
117 int result; 125 int result;
@@ -792,6 +800,15 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
792 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 800 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
793} 801}
794 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
795int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave, 812int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave,
796 struct mlx4_vhcr *vhcr, 813 struct mlx4_vhcr *vhcr,
797 struct mlx4_cmd_mailbox *inbox, 814 struct mlx4_cmd_mailbox *inbox,
@@ -1226,6 +1243,15 @@ static struct mlx4_cmd_info cmd_info[] = {
1226 .wrapper = mlx4_GEN_QP_wrapper 1243 .wrapper = mlx4_GEN_QP_wrapper
1227 }, 1244 },
1228 { 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 {
1229 .opcode = MLX4_CMD_CONF_SPECIAL_QP, 1255 .opcode = MLX4_CMD_CONF_SPECIAL_QP,
1230 .has_inbox = false, 1256 .has_inbox = false,
1231 .has_outbox = false, 1257 .has_outbox = false,
@@ -1495,6 +1521,72 @@ out:
1495 return ret; 1521 return ret;
1496} 1522}
1497 1523
1524
1525int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv,
1526 int slave, int port)
1527{
1528 struct mlx4_vport_oper_state *vp_oper;
1529 struct mlx4_vport_state *vp_admin;
1530 struct mlx4_vf_immed_vlan_work *work;
1531 int err;
1532 int admin_vlan_ix = NO_INDX;
1533
1534 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1535 vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
1536
1537 if (vp_oper->state.default_vlan == vp_admin->default_vlan &&
1538 vp_oper->state.default_qos == vp_admin->default_qos)
1539 return 0;
1540
1541 work = kzalloc(sizeof(*work), GFP_KERNEL);
1542 if (!work)
1543 return -ENOMEM;
1544
1545 if (vp_oper->state.default_vlan != vp_admin->default_vlan) {
1546 err = __mlx4_register_vlan(&priv->dev, port,
1547 vp_admin->default_vlan,
1548 &admin_vlan_ix);
1549 if (err) {
1550 mlx4_warn((&priv->dev),
1551 "No vlan resources slave %d, port %d\n",
1552 slave, port);
1553 return err;
1554 }
1555 work->flags |= MLX4_VF_IMMED_VLAN_FLAG_VLAN;
1556 mlx4_dbg((&(priv->dev)),
1557 "alloc vlan %d idx %d slave %d port %d\n",
1558 (int)(vp_admin->default_vlan),
1559 admin_vlan_ix, slave, port);
1560 }
1561
1562 /* save original vlan ix and vlan id */
1563 work->orig_vlan_id = vp_oper->state.default_vlan;
1564 work->orig_vlan_ix = vp_oper->vlan_idx;
1565
1566 /* handle new qos */
1567 if (vp_oper->state.default_qos != vp_admin->default_qos)
1568 work->flags |= MLX4_VF_IMMED_VLAN_FLAG_QOS;
1569
1570 if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN)
1571 vp_oper->vlan_idx = admin_vlan_ix;
1572
1573 vp_oper->state.default_vlan = vp_admin->default_vlan;
1574 vp_oper->state.default_qos = vp_admin->default_qos;
1575
1576 /* iterate over QPs owned by this slave, using UPDATE_QP */
1577 work->port = port;
1578 work->slave = slave;
1579 work->qos = vp_oper->state.default_qos;
1580 work->vlan_id = vp_oper->state.default_vlan;
1581 work->vlan_ix = vp_oper->vlan_idx;
1582 work->priv = priv;
1583 INIT_WORK(&work->work, mlx4_vf_immed_vlan_work_handler);
1584 queue_work(priv->mfunc.master.comm_wq, &work->work);
1585
1586 return 0;
1587}
1588
1589
1498static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave) 1590static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
1499{ 1591{
1500 int port, err; 1592 int port, err;
@@ -2109,11 +2201,18 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
2109} 2201}
2110EXPORT_SYMBOL_GPL(mlx4_set_vf_mac); 2202EXPORT_SYMBOL_GPL(mlx4_set_vf_mac);
2111 2203
2204static int calculate_transition(u16 oper_vlan, u16 admin_vlan)
2205{
2206 return (2 * (oper_vlan == MLX4_VGT) + (admin_vlan == MLX4_VGT));
2207}
2208
2112int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos) 2209int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2113{ 2210{
2114 struct mlx4_priv *priv = mlx4_priv(dev); 2211 struct mlx4_priv *priv = mlx4_priv(dev);
2115 struct mlx4_vport_state *s_info; 2212 struct mlx4_vport_oper_state *vf_oper;
2213 struct mlx4_vport_state *vf_admin;
2116 int slave; 2214 int slave;
2215 enum mlx4_vlan_transition vlan_trans;
2117 2216
2118 if ((!mlx4_is_master(dev)) || 2217 if ((!mlx4_is_master(dev)) ||
2119 !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VLAN_CONTROL)) 2218 !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VLAN_CONTROL))
@@ -2126,12 +2225,25 @@ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2126 if (slave < 0) 2225 if (slave < 0)
2127 return -EINVAL; 2226 return -EINVAL;
2128 2227
2129 s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; 2228 vf_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
2229 vf_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
2230
2130 if ((0 == vlan) && (0 == qos)) 2231 if ((0 == vlan) && (0 == qos))
2131 s_info->default_vlan = MLX4_VGT; 2232 vf_admin->default_vlan = MLX4_VGT;
2132 else 2233 else
2133 s_info->default_vlan = vlan; 2234 vf_admin->default_vlan = vlan;
2134 s_info->default_qos = qos; 2235 vf_admin->default_qos = qos;
2236
2237 vlan_trans = calculate_transition(vf_oper->state.default_vlan,
2238 vf_admin->default_vlan);
2239
2240 if (priv->mfunc.master.slave_state[slave].active &&
2241 dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP &&
2242 vlan_trans == MLX4_VLAN_TRANSITION_VST_VST) {
2243 mlx4_info(dev, "updating vf %d port %d config params immediately\n",
2244 vf, port);
2245 mlx4_master_immediate_activate_vlan_qos(priv, slave, port);
2246 }
2135 return 0; 2247 return 0;
2136} 2248}
2137EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan); 2249EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 569bbe3e7403..8873d6802c80 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -133,7 +133,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
133 [4] = "Automatic MAC reassignment support", 133 [4] = "Automatic MAC reassignment support",
134 [5] = "Time stamping support", 134 [5] = "Time stamping support",
135 [6] = "VST (control vlan insertion/stripping) support", 135 [6] = "VST (control vlan insertion/stripping) support",
136 [7] = "FSM (MAC anti-spoofing) support" 136 [7] = "FSM (MAC anti-spoofing) support",
137 [8] = "Dynamic QP updates support"
137 }; 138 };
138 int i; 139 int i;
139 140
@@ -659,6 +660,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
659 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); 660 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET);
660 661
661 MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 662 MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
663 if (field32 & (1 << 16))
664 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP;
662 if (field32 & (1 << 26)) 665 if (field32 & (1 << 26))
663 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL; 666 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL;
664 if (field32 & (1 << 20)) 667 if (field32 & (1 << 20))
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 75272935a3f7..5abcb6501e30 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -571,6 +571,24 @@ struct mlx4_cmd {
571 u8 comm_toggle; 571 u8 comm_toggle;
572}; 572};
573 573
574enum {
575 MLX4_VF_IMMED_VLAN_FLAG_VLAN = 1 << 0,
576 MLX4_VF_IMMED_VLAN_FLAG_QOS = 1 << 1,
577};
578struct mlx4_vf_immed_vlan_work {
579 struct work_struct work;
580 struct mlx4_priv *priv;
581 int flags;
582 int slave;
583 int vlan_ix;
584 int orig_vlan_ix;
585 u8 port;
586 u8 qos;
587 u16 vlan_id;
588 u16 orig_vlan_id;
589};
590
591
574struct mlx4_uar_table { 592struct mlx4_uar_table {
575 struct mlx4_bitmap bitmap; 593 struct mlx4_bitmap bitmap;
576}; 594};
@@ -1218,4 +1236,6 @@ static inline spinlock_t *mlx4_tlock(struct mlx4_dev *dev)
1218 1236
1219#define NOT_MASKED_PD_BITS 17 1237#define NOT_MASKED_PD_BITS 17
1220 1238
1239void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work);
1240
1221#endif /* MLX4_H */ 1241#endif /* MLX4_H */
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 1157f028a90f..46323a20060c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -101,6 +101,8 @@ struct res_qp {
101 spinlock_t mcg_spl; 101 spinlock_t mcg_spl;
102 int local_qpn; 102 int local_qpn;
103 atomic_t ref_count; 103 atomic_t ref_count;
104 u32 qpc_flags;
105 u8 sched_queue;
104}; 106};
105 107
106enum res_mtt_states { 108enum res_mtt_states {
@@ -355,7 +357,7 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
355 357
356static int update_vport_qp_param(struct mlx4_dev *dev, 358static int update_vport_qp_param(struct mlx4_dev *dev,
357 struct mlx4_cmd_mailbox *inbox, 359 struct mlx4_cmd_mailbox *inbox,
358 u8 slave) 360 u8 slave, u32 qpn)
359{ 361{
360 struct mlx4_qp_context *qpc = inbox->buf + 8; 362 struct mlx4_qp_context *qpc = inbox->buf + 8;
361 struct mlx4_vport_oper_state *vp_oper; 363 struct mlx4_vport_oper_state *vp_oper;
@@ -369,9 +371,17 @@ static int update_vport_qp_param(struct mlx4_dev *dev,
369 371
370 if (MLX4_VGT != vp_oper->state.default_vlan) { 372 if (MLX4_VGT != vp_oper->state.default_vlan) {
371 qp_type = (be32_to_cpu(qpc->flags) >> 16) & 0xff; 373 qp_type = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
372 if (MLX4_QP_ST_RC == qp_type) 374 if (MLX4_QP_ST_RC == qp_type ||
375 (MLX4_QP_ST_UD == qp_type &&
376 !mlx4_is_qp_reserved(dev, qpn)))
373 return -EINVAL; 377 return -EINVAL;
374 378
379 /* the reserved QPs (special, proxy, tunnel)
380 * do not operate over vlans
381 */
382 if (mlx4_is_qp_reserved(dev, qpn))
383 return 0;
384
375 /* force strip vlan by clear vsd */ 385 /* force strip vlan by clear vsd */
376 qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN); 386 qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN);
377 if (0 != vp_oper->state.default_vlan) { 387 if (0 != vp_oper->state.default_vlan) {
@@ -2114,6 +2124,8 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
2114 if (err) 2124 if (err)
2115 return err; 2125 return err;
2116 qp->local_qpn = local_qpn; 2126 qp->local_qpn = local_qpn;
2127 qp->sched_queue = 0;
2128 qp->qpc_flags = be32_to_cpu(qpc->flags);
2117 2129
2118 err = get_res(dev, slave, mtt_base, RES_MTT, &mtt); 2130 err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2119 if (err) 2131 if (err)
@@ -2836,6 +2848,9 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
2836{ 2848{
2837 int err; 2849 int err;
2838 struct mlx4_qp_context *qpc = inbox->buf + 8; 2850 struct mlx4_qp_context *qpc = inbox->buf + 8;
2851 int qpn = vhcr->in_modifier & 0x7fffff;
2852 struct res_qp *qp;
2853 u8 orig_sched_queue;
2839 2854
2840 err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave); 2855 err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave);
2841 if (err) 2856 if (err)
@@ -2844,11 +2859,30 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
2844 update_pkey_index(dev, slave, inbox); 2859 update_pkey_index(dev, slave, inbox);
2845 update_gid(dev, inbox, (u8)slave); 2860 update_gid(dev, inbox, (u8)slave);
2846 adjust_proxy_tun_qkey(dev, vhcr, qpc); 2861 adjust_proxy_tun_qkey(dev, vhcr, qpc);
2847 err = update_vport_qp_param(dev, inbox, slave); 2862 orig_sched_queue = qpc->pri_path.sched_queue;
2863 err = update_vport_qp_param(dev, inbox, slave, qpn);
2848 if (err) 2864 if (err)
2849 return err; 2865 return err;
2850 2866
2851 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd); 2867 err = get_res(dev, slave, qpn, RES_QP, &qp);
2868 if (err)
2869 return err;
2870 if (qp->com.from_state != RES_QP_HW) {
2871 err = -EBUSY;
2872 goto out;
2873 }
2874
2875 err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2876out:
2877 /* if no error, save sched queue value passed in by VF. This is
2878 * essentially the QOS value provided by the VF. This will be useful
2879 * if we allow dynamic changes from VST back to VGT
2880 */
2881 if (!err)
2882 qp->sched_queue = orig_sched_queue;
2883
2884 put_res(dev, slave, qpn, RES_QP);
2885 return err;
2852} 2886}
2853 2887
2854int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave, 2888int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
@@ -3932,3 +3966,106 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
3932 rem_slave_xrcdns(dev, slave); 3966 rem_slave_xrcdns(dev, slave);
3933 mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); 3967 mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
3934} 3968}
3969
3970void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
3971{
3972 struct mlx4_vf_immed_vlan_work *work =
3973 container_of(_work, struct mlx4_vf_immed_vlan_work, work);
3974 struct mlx4_cmd_mailbox *mailbox;
3975 struct mlx4_update_qp_context *upd_context;
3976 struct mlx4_dev *dev = &work->priv->dev;
3977 struct mlx4_resource_tracker *tracker =
3978 &work->priv->mfunc.master.res_tracker;
3979 struct list_head *qp_list =
3980 &tracker->slave_list[work->slave].res_list[RES_QP];
3981 struct res_qp *qp;
3982 struct res_qp *tmp;
3983 u64 qp_mask = ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED) |
3984 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P) |
3985 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED) |
3986 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED) |
3987 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P) |
3988 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED) |
3989 (1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX) |
3990 (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE));
3991
3992 int err;
3993 int port, errors = 0;
3994 u8 vlan_control;
3995
3996 if (mlx4_is_slave(dev)) {
3997 mlx4_warn(dev, "Trying to update-qp in slave %d\n",
3998 work->slave);
3999 goto out;
4000 }
4001
4002 mailbox = mlx4_alloc_cmd_mailbox(dev);
4003 if (IS_ERR(mailbox))
4004 goto out;
4005
4006 if (!work->vlan_id)
4007 vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
4008 MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
4009 else
4010 vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
4011 MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
4012 MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
4013
4014 upd_context = mailbox->buf;
4015 upd_context->primary_addr_path_mask = cpu_to_be64(qp_mask);
4016 upd_context->qp_context.pri_path.vlan_control = vlan_control;
4017 upd_context->qp_context.pri_path.vlan_index = work->vlan_ix;
4018
4019 spin_lock_irq(mlx4_tlock(dev));
4020 list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
4021 spin_unlock_irq(mlx4_tlock(dev));
4022 if (qp->com.owner == work->slave) {
4023 if (qp->com.from_state != RES_QP_HW ||
4024 !qp->sched_queue || /* no INIT2RTR trans yet */
4025 mlx4_is_qp_reserved(dev, qp->local_qpn) ||
4026 qp->qpc_flags & (1 << MLX4_RSS_QPC_FLAG_OFFSET)) {
4027 spin_lock_irq(mlx4_tlock(dev));
4028 continue;
4029 }
4030 port = (qp->sched_queue >> 6 & 1) + 1;
4031 if (port != work->port) {
4032 spin_lock_irq(mlx4_tlock(dev));
4033 continue;
4034 }
4035 upd_context->qp_context.pri_path.sched_queue =
4036 qp->sched_queue & 0xC7;
4037 upd_context->qp_context.pri_path.sched_queue |=
4038 ((work->qos & 0x7) << 3);
4039
4040 err = mlx4_cmd(dev, mailbox->dma,
4041 qp->local_qpn & 0xffffff,
4042 0, MLX4_CMD_UPDATE_QP,
4043 MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
4044 if (err) {
4045 mlx4_info(dev, "UPDATE_QP failed for slave %d, "
4046 "port %d, qpn %d (%d)\n",
4047 work->slave, port, qp->local_qpn,
4048 err);
4049 errors++;
4050 }
4051 }
4052 spin_lock_irq(mlx4_tlock(dev));
4053 }
4054 spin_unlock_irq(mlx4_tlock(dev));
4055 mlx4_free_cmd_mailbox(dev, mailbox);
4056
4057 if (errors)
4058 mlx4_err(dev, "%d UPDATE_QP failures for slave %d, port %d\n",
4059 errors, work->slave, work->port);
4060
4061 /* unregister previous vlan_id if needed and we had no errors
4062 * while updating the QPs
4063 */
4064 if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN && !errors &&
4065 NO_INDX != work->orig_vlan_ix)
4066 __mlx4_unregister_vlan(&work->priv->dev, work->port,
4067 work->orig_vlan_ix);
4068out:
4069 kfree(work);
4070 return;
4071}