net/mlx4_core: Add support for filtering multicast loopback

Update device capabilities regarding HW filtering multicast loopback support.

Add MLX4_UPDATE_QP_ETH_SRC_CHECK_MC_LB attribute to mlx4_update_qp to
enable changing QP context to support filtering incoming multicast
loopback traffic according the sender's counter index.

Set the corresponding bits in QP context to force the loopback source
checks if attribute is given and HW supports it.

Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Maor Gottlieb 2015-10-15 14:44:38 +03:00 committed by Doug Ledford
parent ddf9529be1
commit 9a89283597
5 changed files with 68 additions and 13 deletions

View File

@ -155,6 +155,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
[27] = "Port beacon support", [27] = "Port beacon support",
[28] = "RX-ALL support", [28] = "RX-ALL support",
[29] = "802.1ad offload support", [29] = "802.1ad offload support",
[31] = "Modifying loopback source checks using UPDATE_QP support",
[32] = "Loopback source checks support",
}; };
int i; int i;
@ -964,6 +966,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
if (field32 & (1 << 16)) if (field32 & (1 << 16))
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP;
if (field32 & (1 << 18))
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB;
if (field32 & (1 << 19))
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_LB_SRC_CHK;
if (field32 & (1 << 26)) if (field32 & (1 << 26))
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL; dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL;
if (field32 & (1 << 20)) if (field32 & (1 << 20))

View File

@ -436,6 +436,23 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
cmd->qp_context.pri_path.grh_mylmc = params->smac_index; cmd->qp_context.pri_path.grh_mylmc = params->smac_index;
} }
if (attr & MLX4_UPDATE_QP_ETH_SRC_CHECK_MC_LB) {
if (!(dev->caps.flags2
& MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB)) {
mlx4_warn(dev,
"Trying to set src check LB, but it isn't supported\n");
err = -ENOTSUPP;
goto out;
}
pri_addr_path_mask |=
1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB;
if (params->flags &
MLX4_UPDATE_QP_PARAMS_FLAGS_ETH_CHECK_MC_LB) {
cmd->qp_context.pri_path.fl |=
MLX4_FL_ETH_SRC_CHECK_MC_LB;
}
}
if (attr & MLX4_UPDATE_QP_VSD) { if (attr & MLX4_UPDATE_QP_VSD) {
qp_mask |= 1ULL << MLX4_UPD_QP_MASK_VSD; qp_mask |= 1ULL << MLX4_UPD_QP_MASK_VSD;
if (params->flags & MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE) if (params->flags & MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE)
@ -458,7 +475,7 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
err = mlx4_cmd(dev, mailbox->dma, qpn & 0xffffff, 0, err = mlx4_cmd(dev, mailbox->dma, qpn & 0xffffff, 0,
MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_NATIVE); MLX4_CMD_NATIVE);
out:
mlx4_free_cmd_mailbox(dev, mailbox); mlx4_free_cmd_mailbox(dev, mailbox);
return err; return err;
} }

View File

@ -770,9 +770,12 @@ static int update_vport_qp_param(struct mlx4_dev *dev,
} }
} }
/* preserve IF_COUNTER flag */
qpc->pri_path.vlan_control &=
MLX4_CTRL_ETH_SRC_CHECK_IF_COUNTER;
if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE && if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE &&
dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) { dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) {
qpc->pri_path.vlan_control = qpc->pri_path.vlan_control |=
MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED | MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED | MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED | MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
@ -780,12 +783,12 @@ static int update_vport_qp_param(struct mlx4_dev *dev,
MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED | MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED; MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
} else if (0 != vp_oper->state.default_vlan) { } else if (0 != vp_oper->state.default_vlan) {
qpc->pri_path.vlan_control = qpc->pri_path.vlan_control |=
MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED | MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED | MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED; MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
} else { /* priority tagged */ } else { /* priority tagged */
qpc->pri_path.vlan_control = qpc->pri_path.vlan_control |=
MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED | MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED; MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
} }
@ -3762,9 +3765,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
update_gid(dev, inbox, (u8)slave); update_gid(dev, inbox, (u8)slave);
adjust_proxy_tun_qkey(dev, vhcr, qpc); adjust_proxy_tun_qkey(dev, vhcr, qpc);
orig_sched_queue = qpc->pri_path.sched_queue; orig_sched_queue = qpc->pri_path.sched_queue;
err = update_vport_qp_param(dev, inbox, slave, qpn);
if (err)
return err;
err = get_res(dev, slave, qpn, RES_QP, &qp); err = get_res(dev, slave, qpn, RES_QP, &qp);
if (err) if (err)
@ -3774,6 +3774,10 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
goto out; goto out;
} }
err = update_vport_qp_param(dev, inbox, slave, qpn);
if (err)
goto out;
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
out: out:
/* if no error, save sched queue value passed in by VF. This is /* if no error, save sched queue value passed in by VF. This is
@ -4208,7 +4212,9 @@ static int add_eth_header(struct mlx4_dev *dev, int slave,
} }
#define MLX4_UPD_QP_PATH_MASK_SUPPORTED (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX) #define MLX4_UPD_QP_PATH_MASK_SUPPORTED ( \
1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX |\
1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB)
int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave, int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr, struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *inbox,
@ -4231,6 +4237,16 @@ int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
(pri_addr_path_mask & ~MLX4_UPD_QP_PATH_MASK_SUPPORTED)) (pri_addr_path_mask & ~MLX4_UPD_QP_PATH_MASK_SUPPORTED))
return -EPERM; return -EPERM;
if ((pri_addr_path_mask &
(1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB)) &&
!(dev->caps.flags2 &
MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB)) {
mlx4_warn(dev,
"Src check LB for slave %d isn't supported\n",
slave);
return -ENOTSUPP;
}
/* Just change the smac for the QP */ /* Just change the smac for the QP */
err = get_res(dev, slave, qpn, RES_QP, &rqp); err = get_res(dev, slave, qpn, RES_QP, &rqp);
if (err) { if (err) {

View File

@ -214,6 +214,8 @@ enum {
MLX4_DEV_CAP_FLAG2_IGNORE_FCS = 1LL << 28, MLX4_DEV_CAP_FLAG2_IGNORE_FCS = 1LL << 28,
MLX4_DEV_CAP_FLAG2_PHV_EN = 1LL << 29, MLX4_DEV_CAP_FLAG2_PHV_EN = 1LL << 29,
MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN = 1LL << 30, MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN = 1LL << 30,
MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB = 1ULL << 31,
MLX4_DEV_CAP_FLAG2_LB_SRC_CHK = 1ULL << 32,
}; };
enum { enum {

View File

@ -135,7 +135,10 @@ struct mlx4_rss_context {
struct mlx4_qp_path { struct mlx4_qp_path {
u8 fl; u8 fl;
u8 vlan_control; union {
u8 vlan_control;
u8 control;
};
u8 disable_pkey_check; u8 disable_pkey_check;
u8 pkey_index; u8 pkey_index;
u8 counter_index; u8 counter_index;
@ -156,9 +159,16 @@ struct mlx4_qp_path {
}; };
enum { /* fl */ enum { /* fl */
MLX4_FL_CV = 1 << 6, MLX4_FL_CV = 1 << 6,
MLX4_FL_ETH_HIDE_CQE_VLAN = 1 << 2 MLX4_FL_ETH_HIDE_CQE_VLAN = 1 << 2,
MLX4_FL_ETH_SRC_CHECK_MC_LB = 1 << 1,
MLX4_FL_ETH_SRC_CHECK_UC_LB = 1 << 0,
}; };
enum { /* control */
MLX4_CTRL_ETH_SRC_CHECK_IF_COUNTER = 1 << 7,
};
enum { /* vlan_control */ enum { /* vlan_control */
MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED = 1 << 6, MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED = 1 << 6,
MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED = 1 << 5, /* 802.1p priority tag */ MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED = 1 << 5, /* 802.1p priority tag */
@ -254,6 +264,8 @@ enum {
MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE = 14 + 32, MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE = 14 + 32,
MLX4_UPD_QP_PATH_MASK_IF_COUNTER_INDEX = 15 + 32, MLX4_UPD_QP_PATH_MASK_IF_COUNTER_INDEX = 15 + 32,
MLX4_UPD_QP_PATH_MASK_FVL_RX = 16 + 32, MLX4_UPD_QP_PATH_MASK_FVL_RX = 16 + 32,
MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_UC_LB = 18 + 32,
MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB = 19 + 32,
}; };
enum { /* param3 */ enum { /* param3 */
@ -436,11 +448,13 @@ enum mlx4_update_qp_attr {
MLX4_UPDATE_QP_VSD = 1 << 1, MLX4_UPDATE_QP_VSD = 1 << 1,
MLX4_UPDATE_QP_RATE_LIMIT = 1 << 2, MLX4_UPDATE_QP_RATE_LIMIT = 1 << 2,
MLX4_UPDATE_QP_QOS_VPORT = 1 << 3, MLX4_UPDATE_QP_QOS_VPORT = 1 << 3,
MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 4) - 1 MLX4_UPDATE_QP_ETH_SRC_CHECK_MC_LB = 1 << 4,
MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 5) - 1
}; };
enum mlx4_update_qp_params_flags { enum mlx4_update_qp_params_flags {
MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE = 1 << 0, MLX4_UPDATE_QP_PARAMS_FLAGS_ETH_CHECK_MC_LB = 1 << 0,
MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE = 1 << 1,
}; };
struct mlx4_update_qp_params { struct mlx4_update_qp_params {