Commit c43abe1a authored by Guojia Liao's avatar Guojia Liao Committed by Jakub Kicinski

net: hns3: add support for extended promiscuous command

For DEVICE_VERSION_V2, the hardware supports enable tx and rx
promiscuous separately. But tx or rx promiscuous is active for
unicast, multicast and broadcast promiscuous simultaneously.
To support traffics between functions belong to the same port,
we always enable tx promiscuous for broadcast promiscuous, so
tx promiscuous for unicast and multicast promiscuous is also
enabled.

For DEVICE_VERSION_V3, the hardware decouples the above
relationship. Tx unicast promiscuous, rx unicast promiscuous,
tx multicast promiscuous, rx multicast promiscuous, tx broadcast
promiscuous and rx broadcast promiscuous can be enabled separately.

So add support for the new promiscuous command.
Signed-off-by: default avatarGuojia Liao <liaoguojia@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bdc40a3f
......@@ -583,23 +583,26 @@ struct hclge_link_status_cmd {
u8 rsv[23];
};
struct hclge_promisc_param {
u8 vf_id;
u8 enable;
};
/* for DEVICE_VERSION_V1/2, reference to promisc cmd byte8 */
#define HCLGE_PROMISC_EN_UC 1
#define HCLGE_PROMISC_EN_MC 2
#define HCLGE_PROMISC_EN_BC 3
#define HCLGE_PROMISC_TX_EN 4
#define HCLGE_PROMISC_RX_EN 5
/* for DEVICE_VERSION_V3, reference to promisc cmd byte10 */
#define HCLGE_PROMISC_UC_RX_EN 2
#define HCLGE_PROMISC_MC_RX_EN 3
#define HCLGE_PROMISC_BC_RX_EN 4
#define HCLGE_PROMISC_UC_TX_EN 5
#define HCLGE_PROMISC_MC_TX_EN 6
#define HCLGE_PROMISC_BC_TX_EN 7
#define HCLGE_PROMISC_TX_EN_B BIT(4)
#define HCLGE_PROMISC_RX_EN_B BIT(5)
#define HCLGE_PROMISC_EN_B 1
#define HCLGE_PROMISC_EN_ALL 0x7
#define HCLGE_PROMISC_EN_UC 0x1
#define HCLGE_PROMISC_EN_MC 0x2
#define HCLGE_PROMISC_EN_BC 0x4
struct hclge_promisc_cfg_cmd {
u8 flag;
u8 promisc;
u8 vf_id;
__le16 rsv0;
u8 rsv1[20];
u8 extend_promisc;
u8 rsv0[21];
};
enum hclge_promisc_type {
......
......@@ -4826,61 +4826,50 @@ static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle, int vector,
return ret;
}
static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
struct hclge_promisc_param *param)
static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, u8 vf_id,
bool en_uc, bool en_mc, bool en_bc)
{
struct hclge_promisc_cfg_cmd *req;
struct hclge_desc desc;
u8 promisc_cfg = 0;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PROMISC_MODE, false);
req = (struct hclge_promisc_cfg_cmd *)desc.data;
req->vf_id = param->vf_id;
req->vf_id = vf_id;
/* HCLGE_PROMISC_TX_EN_B and HCLGE_PROMISC_RX_EN_B are not supported on
* pdev revision(0x20), new revision support them. The
* value of this two fields will not return error when driver
* send command to fireware in revision(0x20).
*/
req->flag = (param->enable << HCLGE_PROMISC_EN_B) |
HCLGE_PROMISC_TX_EN_B | HCLGE_PROMISC_RX_EN_B;
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_RX_EN, en_uc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_RX_EN, en_mc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_RX_EN, en_bc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_TX_EN, en_uc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_TX_EN, en_mc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_TX_EN, en_bc ? 1 : 0);
req->extend_promisc = promisc_cfg;
/* to be compatible with DEVICE_VERSION_V1/2 */
promisc_cfg = 0;
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_UC, en_uc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_MC, en_mc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_BC, en_bc ? 1 : 0);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_TX_EN, 1);
hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_RX_EN, 1);
req->promisc = promisc_cfg;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"failed to set vport %d promisc mode, ret = %d.\n",
param->vf_id, ret);
"failed to set vport %u promisc mode, ret = %d.\n",
vf_id, ret);
return ret;
}
static void hclge_promisc_param_init(struct hclge_promisc_param *param,
bool en_uc, bool en_mc, bool en_bc,
int vport_id)
{
if (!param)
return;
memset(param, 0, sizeof(struct hclge_promisc_param));
if (en_uc)
param->enable = HCLGE_PROMISC_EN_UC;
if (en_mc)
param->enable |= HCLGE_PROMISC_EN_MC;
if (en_bc)
param->enable |= HCLGE_PROMISC_EN_BC;
param->vf_id = vport_id;
}
int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc,
bool en_mc_pmc, bool en_bc_pmc)
{
struct hclge_dev *hdev = vport->back;
struct hclge_promisc_param param;
hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, en_bc_pmc,
vport->vport_id);
return hclge_cmd_set_promisc_mode(hdev, &param);
return hclge_cmd_set_promisc_mode(vport->back, vport->vport_id,
en_uc_pmc, en_mc_pmc, en_bc_pmc);
}
static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment