diff options
author | Rony Efraim <ronye@mellanox.com> | 2013-11-07 05:19:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-07 19:22:47 -0500 |
commit | f0f829bf42cdeb027234a1d0e1e5f62d77380a4d (patch) | |
tree | a34783b75f12d3136073ab3a13dfdf734cfe8fba | |
parent | 571b8b92c7d4cddd899cf19f11f14fb149968898 (diff) |
net/mlx4_core: Add immediate activate for VGT->VST->VGT
Allow immediate activate of VGT->VST and VST->VGT transitions, without
the need of rebinding in mlx4_master_immediate_activate_vlan_qos().
Also in struct res_qp: add qp parameters (vlan_index,fvl,vlan_cntrol..)
to the saved set, in order to restore when move to VGT.
- Clear at mlx4_RST2INIT_QP_wrapper()
- Save at mlx4_INIT2RTR_QP_wrapper()
- Restore at mlx4_vf_immed_vlan_work_handler()
Update mlx4_vf_immed_vlan_work_handler() to support VGT.
Signed-off-by: Rony Efraim <ronye@mellanox.com>
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Reviewed-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 34 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 79 |
2 files changed, 81 insertions, 32 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 7207dcd05759..1e9970d2f0f3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1539,11 +1539,6 @@ out: | |||
1539 | return ret; | 1539 | return ret; |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | static int calculate_transition(u16 oper_vlan, u16 admin_vlan) | ||
1543 | { | ||
1544 | return (2 * (oper_vlan == MLX4_VGT) + (admin_vlan == MLX4_VGT)); | ||
1545 | } | ||
1546 | |||
1547 | static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv, | 1542 | static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv, |
1548 | int slave, int port) | 1543 | int slave, int port) |
1549 | { | 1544 | { |
@@ -1553,7 +1548,6 @@ static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv, | |||
1553 | struct mlx4_dev *dev = &(priv->dev); | 1548 | struct mlx4_dev *dev = &(priv->dev); |
1554 | int err; | 1549 | int err; |
1555 | int admin_vlan_ix = NO_INDX; | 1550 | int admin_vlan_ix = NO_INDX; |
1556 | enum mlx4_vlan_transition vlan_trans; | ||
1557 | 1551 | ||
1558 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; | 1552 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; |
1559 | vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; | 1553 | vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; |
@@ -1563,12 +1557,8 @@ static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv, | |||
1563 | vp_oper->state.link_state == vp_admin->link_state) | 1557 | vp_oper->state.link_state == vp_admin->link_state) |
1564 | return 0; | 1558 | return 0; |
1565 | 1559 | ||
1566 | vlan_trans = calculate_transition(vp_oper->state.default_vlan, | ||
1567 | vp_admin->default_vlan); | ||
1568 | |||
1569 | if (!(priv->mfunc.master.slave_state[slave].active && | 1560 | if (!(priv->mfunc.master.slave_state[slave].active && |
1570 | dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP && | 1561 | dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP)) { |
1571 | vlan_trans == MLX4_VLAN_TRANSITION_VST_VST)) { | ||
1572 | /* even if the UPDATE_QP command isn't supported, we still want | 1562 | /* even if the UPDATE_QP command isn't supported, we still want |
1573 | * to set this VF link according to the admin directive | 1563 | * to set this VF link according to the admin directive |
1574 | */ | 1564 | */ |
@@ -1586,15 +1576,19 @@ static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv, | |||
1586 | return -ENOMEM; | 1576 | return -ENOMEM; |
1587 | 1577 | ||
1588 | if (vp_oper->state.default_vlan != vp_admin->default_vlan) { | 1578 | if (vp_oper->state.default_vlan != vp_admin->default_vlan) { |
1589 | err = __mlx4_register_vlan(&priv->dev, port, | 1579 | if (MLX4_VGT != vp_admin->default_vlan) { |
1590 | vp_admin->default_vlan, | 1580 | err = __mlx4_register_vlan(&priv->dev, port, |
1591 | &admin_vlan_ix); | 1581 | vp_admin->default_vlan, |
1592 | if (err) { | 1582 | &admin_vlan_ix); |
1593 | kfree(work); | 1583 | if (err) { |
1594 | mlx4_warn((&priv->dev), | 1584 | kfree(work); |
1595 | "No vlan resources slave %d, port %d\n", | 1585 | mlx4_warn((&priv->dev), |
1596 | slave, port); | 1586 | "No vlan resources slave %d, port %d\n", |
1597 | return err; | 1587 | slave, port); |
1588 | return err; | ||
1589 | } | ||
1590 | } else { | ||
1591 | admin_vlan_ix = NO_INDX; | ||
1598 | } | 1592 | } |
1599 | work->flags |= MLX4_VF_IMMED_VLAN_FLAG_VLAN; | 1593 | work->flags |= MLX4_VF_IMMED_VLAN_FLAG_VLAN; |
1600 | mlx4_dbg((&(priv->dev)), | 1594 | mlx4_dbg((&(priv->dev)), |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b1603e2287a7..2f3f2bc7f283 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -110,7 +110,14 @@ struct res_qp { | |||
110 | int local_qpn; | 110 | int local_qpn; |
111 | atomic_t ref_count; | 111 | atomic_t ref_count; |
112 | u32 qpc_flags; | 112 | u32 qpc_flags; |
113 | /* saved qp params before VST enforcement in order to restore on VGT */ | ||
113 | u8 sched_queue; | 114 | u8 sched_queue; |
115 | __be32 param3; | ||
116 | u8 vlan_control; | ||
117 | u8 fvl_rx; | ||
118 | u8 pri_path_fl; | ||
119 | u8 vlan_index; | ||
120 | u8 feup; | ||
114 | }; | 121 | }; |
115 | 122 | ||
116 | enum res_mtt_states { | 123 | enum res_mtt_states { |
@@ -2568,6 +2575,12 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave, | |||
2568 | return err; | 2575 | return err; |
2569 | qp->local_qpn = local_qpn; | 2576 | qp->local_qpn = local_qpn; |
2570 | qp->sched_queue = 0; | 2577 | qp->sched_queue = 0; |
2578 | qp->param3 = 0; | ||
2579 | qp->vlan_control = 0; | ||
2580 | qp->fvl_rx = 0; | ||
2581 | qp->pri_path_fl = 0; | ||
2582 | qp->vlan_index = 0; | ||
2583 | qp->feup = 0; | ||
2571 | qp->qpc_flags = be32_to_cpu(qpc->flags); | 2584 | qp->qpc_flags = be32_to_cpu(qpc->flags); |
2572 | 2585 | ||
2573 | err = get_res(dev, slave, mtt_base, RES_MTT, &mtt); | 2586 | err = get_res(dev, slave, mtt_base, RES_MTT, &mtt); |
@@ -3294,6 +3307,12 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave, | |||
3294 | int qpn = vhcr->in_modifier & 0x7fffff; | 3307 | int qpn = vhcr->in_modifier & 0x7fffff; |
3295 | struct res_qp *qp; | 3308 | struct res_qp *qp; |
3296 | u8 orig_sched_queue; | 3309 | u8 orig_sched_queue; |
3310 | __be32 orig_param3 = qpc->param3; | ||
3311 | u8 orig_vlan_control = qpc->pri_path.vlan_control; | ||
3312 | u8 orig_fvl_rx = qpc->pri_path.fvl_rx; | ||
3313 | u8 orig_pri_path_fl = qpc->pri_path.fl; | ||
3314 | u8 orig_vlan_index = qpc->pri_path.vlan_index; | ||
3315 | u8 orig_feup = qpc->pri_path.feup; | ||
3297 | 3316 | ||
3298 | err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave); | 3317 | err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave); |
3299 | if (err) | 3318 | if (err) |
@@ -3321,9 +3340,15 @@ out: | |||
3321 | * essentially the QOS value provided by the VF. This will be useful | 3340 | * essentially the QOS value provided by the VF. This will be useful |
3322 | * if we allow dynamic changes from VST back to VGT | 3341 | * if we allow dynamic changes from VST back to VGT |
3323 | */ | 3342 | */ |
3324 | if (!err) | 3343 | if (!err) { |
3325 | qp->sched_queue = orig_sched_queue; | 3344 | qp->sched_queue = orig_sched_queue; |
3326 | 3345 | qp->param3 = orig_param3; | |
3346 | qp->vlan_control = orig_vlan_control; | ||
3347 | qp->fvl_rx = orig_fvl_rx; | ||
3348 | qp->pri_path_fl = orig_pri_path_fl; | ||
3349 | qp->vlan_index = orig_vlan_index; | ||
3350 | qp->feup = orig_feup; | ||
3351 | } | ||
3327 | put_res(dev, slave, qpn, RES_QP); | 3352 | put_res(dev, slave, qpn, RES_QP); |
3328 | return err; | 3353 | return err; |
3329 | } | 3354 | } |
@@ -4437,13 +4462,20 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) | |||
4437 | &tracker->slave_list[work->slave].res_list[RES_QP]; | 4462 | &tracker->slave_list[work->slave].res_list[RES_QP]; |
4438 | struct res_qp *qp; | 4463 | struct res_qp *qp; |
4439 | struct res_qp *tmp; | 4464 | struct res_qp *tmp; |
4440 | u64 qp_mask = ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED) | | 4465 | u64 qp_path_mask_vlan_ctrl = |
4466 | ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED) | | ||
4441 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P) | | 4467 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P) | |
4442 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED) | | 4468 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED) | |
4443 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED) | | 4469 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED) | |
4444 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P) | | 4470 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P) | |
4445 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED) | | 4471 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED)); |
4446 | (1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX) | | 4472 | |
4473 | u64 qp_path_mask = ((1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX) | | ||
4474 | (1ULL << MLX4_UPD_QP_PATH_MASK_FVL) | | ||
4475 | (1ULL << MLX4_UPD_QP_PATH_MASK_CV) | | ||
4476 | (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_HIDE_CQE_VLAN) | | ||
4477 | (1ULL << MLX4_UPD_QP_PATH_MASK_FEUP) | | ||
4478 | (1ULL << MLX4_UPD_QP_PATH_MASK_FVL_RX) | | ||
4447 | (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE)); | 4479 | (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE)); |
4448 | 4480 | ||
4449 | int err; | 4481 | int err; |
@@ -4475,9 +4507,7 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) | |||
4475 | MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED; | 4507 | MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED; |
4476 | 4508 | ||
4477 | upd_context = mailbox->buf; | 4509 | upd_context = mailbox->buf; |
4478 | upd_context->primary_addr_path_mask = cpu_to_be64(qp_mask); | 4510 | upd_context->qp_mask = cpu_to_be64(MLX4_UPD_QP_MASK_VSD); |
4479 | upd_context->qp_context.pri_path.vlan_control = vlan_control; | ||
4480 | upd_context->qp_context.pri_path.vlan_index = work->vlan_ix; | ||
4481 | 4511 | ||
4482 | spin_lock_irq(mlx4_tlock(dev)); | 4512 | spin_lock_irq(mlx4_tlock(dev)); |
4483 | list_for_each_entry_safe(qp, tmp, qp_list, com.list) { | 4513 | list_for_each_entry_safe(qp, tmp, qp_list, com.list) { |
@@ -4495,10 +4525,35 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) | |||
4495 | spin_lock_irq(mlx4_tlock(dev)); | 4525 | spin_lock_irq(mlx4_tlock(dev)); |
4496 | continue; | 4526 | continue; |
4497 | } | 4527 | } |
4498 | upd_context->qp_context.pri_path.sched_queue = | 4528 | if (MLX4_QP_ST_RC == ((qp->qpc_flags >> 16) & 0xff)) |
4499 | qp->sched_queue & 0xC7; | 4529 | upd_context->primary_addr_path_mask = cpu_to_be64(qp_path_mask); |
4500 | upd_context->qp_context.pri_path.sched_queue |= | 4530 | else |
4501 | ((work->qos & 0x7) << 3); | 4531 | upd_context->primary_addr_path_mask = |
4532 | cpu_to_be64(qp_path_mask | qp_path_mask_vlan_ctrl); | ||
4533 | if (work->vlan_id == MLX4_VGT) { | ||
4534 | upd_context->qp_context.param3 = qp->param3; | ||
4535 | upd_context->qp_context.pri_path.vlan_control = qp->vlan_control; | ||
4536 | upd_context->qp_context.pri_path.fvl_rx = qp->fvl_rx; | ||
4537 | upd_context->qp_context.pri_path.vlan_index = qp->vlan_index; | ||
4538 | upd_context->qp_context.pri_path.fl = qp->pri_path_fl; | ||
4539 | upd_context->qp_context.pri_path.feup = qp->feup; | ||
4540 | upd_context->qp_context.pri_path.sched_queue = | ||
4541 | qp->sched_queue; | ||
4542 | } else { | ||
4543 | upd_context->qp_context.param3 = qp->param3 & ~cpu_to_be32(MLX4_STRIP_VLAN); | ||
4544 | upd_context->qp_context.pri_path.vlan_control = vlan_control; | ||
4545 | upd_context->qp_context.pri_path.vlan_index = work->vlan_ix; | ||
4546 | upd_context->qp_context.pri_path.fvl_rx = | ||
4547 | qp->fvl_rx | MLX4_FVL_RX_FORCE_ETH_VLAN; | ||
4548 | upd_context->qp_context.pri_path.fl = | ||
4549 | qp->pri_path_fl | MLX4_FL_CV | MLX4_FL_ETH_HIDE_CQE_VLAN; | ||
4550 | upd_context->qp_context.pri_path.feup = | ||
4551 | qp->feup | MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN; | ||
4552 | upd_context->qp_context.pri_path.sched_queue = | ||
4553 | qp->sched_queue & 0xC7; | ||
4554 | upd_context->qp_context.pri_path.sched_queue |= | ||
4555 | ((work->qos & 0x7) << 3); | ||
4556 | } | ||
4502 | 4557 | ||
4503 | err = mlx4_cmd(dev, mailbox->dma, | 4558 | err = mlx4_cmd(dev, mailbox->dma, |
4504 | qp->local_qpn & 0xffffff, | 4559 | qp->local_qpn & 0xffffff, |