Skip to content

Commit

Permalink
net: hns3: configure promisc mode for VF asynchronously
Browse files Browse the repository at this point in the history
Currently, when host set VF untrusted, the driver will disable
the promisc mode of VF. It may be conflicted when the VF requests
the host to set promisc mode. So refactor it by changing promisc
mode for VF asynchronously. With this change, the promisc mode of
VF can be restored when the VF being trusted again.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jian Shen authored and David S. Miller committed May 24, 2021
1 parent 62f148d commit 1e6e761
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 46 deletions.
43 changes: 29 additions & 14 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -11500,10 +11500,7 @@ static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
u32 new_trusted = enable ? 1 : 0;
bool en_bc_pmc;
int ret;

vport = hclge_get_vf_vport(hdev, vf);
if (!vport)
Expand All @@ -11512,18 +11509,9 @@ static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable)
if (vport->vf_info.trusted == new_trusted)
return 0;

/* Disable promisc mode for VF if it is not trusted any more. */
if (!enable && vport->vf_info.promisc_enable) {
en_bc_pmc = ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2;
ret = hclge_set_vport_promisc_mode(vport, false, false,
en_bc_pmc);
if (ret)
return ret;
vport->vf_info.promisc_enable = 0;
hclge_inform_vf_promisc_info(vport);
}

vport->vf_info.trusted = new_trusted;
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
hclge_task_schedule(hdev, 0);

return 0;
}
Expand Down Expand Up @@ -12417,6 +12405,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
struct hnae3_handle *handle = &vport->nic;
u8 tmp_flags;
int ret;
u16 i;

if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
set_bit(HCLGE_STATE_PROMISC_CHANGED, &hdev->state);
Expand All @@ -12433,6 +12422,32 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
tmp_flags & HNAE3_VLAN_FLTR);
}
}

for (i = 1; i < hdev->num_alloc_vport; i++) {
bool uc_en = false;
bool mc_en = false;
bool bc_en;

vport = &hdev->vport[i];

if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
&vport->state))
continue;

if (vport->vf_info.trusted) {
uc_en = vport->vf_info.request_uc_en > 0;
mc_en = vport->vf_info.request_mc_en > 0;
}
bc_en = vport->vf_info.request_bc_en > 0;

ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
mc_en, bc_en);
if (ret) {
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
&vport->state);
return;
}
}
}

static bool hclge_module_existed(struct hclge_dev *hdev)
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ struct hclge_rss_tuple_cfg {
enum HCLGE_VPORT_STATE {
HCLGE_VPORT_STATE_ALIVE,
HCLGE_VPORT_STATE_MAC_TBL_CHANGE,
HCLGE_VPORT_STATE_PROMISC_CHANGE,
HCLGE_VPORT_STATE_MAX
};

Expand All @@ -972,7 +973,9 @@ struct hclge_vf_info {
u32 spoofchk;
u32 max_tx_rate;
u32 trusted;
u16 promisc_enable;
u8 request_uc_en;
u8 request_mc_en;
u8 request_bc_en;
};

struct hclge_vport {
Expand Down
40 changes: 9 additions & 31 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,42 +231,24 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en,
return ret;
}

static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *req)
static void hclge_set_vf_promisc_mode(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *req)
{
bool en_bc = req->msg.en_bc ? true : false;
bool en_uc = req->msg.en_uc ? true : false;
bool en_mc = req->msg.en_mc ? true : false;
struct hnae3_handle *handle = &vport->nic;
int ret;
struct hclge_dev *hdev = vport->back;

if (!vport->vf_info.trusted) {
en_uc = false;
en_mc = false;
}
vport->vf_info.request_uc_en = req->msg.en_uc;
vport->vf_info.request_mc_en = req->msg.en_mc;
vport->vf_info.request_bc_en = req->msg.en_bc;

if (req->msg.en_limit_promisc)
set_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->priv_flags);
else
clear_bit(HNAE3_PFLAG_LIMIT_PROMISC,
&handle->priv_flags);

ret = hclge_set_vport_promisc_mode(vport, en_uc, en_mc, en_bc);

vport->vf_info.promisc_enable = (en_uc || en_mc) ? 1 : 0;

return ret;
}

void hclge_inform_vf_promisc_info(struct hclge_vport *vport)
{
u8 dest_vfid = (u8)vport->vport_id;
u8 msg_data[2];

memcpy(&msg_data[0], &vport->vf_info.promisc_enable, sizeof(u16));

hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
HCLGE_MBX_PUSH_PROMISC_INFO, dest_vfid);
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
hclge_task_schedule(hdev, 0);
}

static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
Expand Down Expand Up @@ -748,11 +730,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
req);
break;
case HCLGE_MBX_SET_PROMISC_MODE:
ret = hclge_set_vf_promisc_mode(vport, req);
if (ret)
dev_err(&hdev->pdev->dev,
"PF fail(%d) to set VF promisc mode\n",
ret);
hclge_set_vf_promisc_mode(vport, req);
break;
case HCLGE_MBX_SET_UNICAST:
ret = hclge_set_vf_uc_mac_addr(vport, req);
Expand Down

0 comments on commit 1e6e761

Please sign in to comment.