提交 b6485e22 编写于 作者: J Jian Shen 提交者: Xie XiuQi

net: hns3: add support for setting VF trust

driver inclusion
category: feature
bugzilla: NA
CVE: NA

This patch adds supports for setting VF trust by host. If specified
VF is trusted, then it can enable promisc(include allmulti mode).
If a trusted VF enabled promisc, and being untrusted, host will
disable promisc mode for this VF.

For VF will update its promisc mode from set_rx_mode now, so it's
unnecessary to set broadcst promisc mode when initialization or
reset.

Feature or Bugfix:Feature
Signed-off-by: NJian Shen <shenjian15@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NYunsheng Lin <linyunsheng@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 425481d9
......@@ -45,6 +45,7 @@ enum HCLGE_MBX_OPCODE {
HCLGE_MBX_GET_LINK_MODE, /* (VF -> PF) get the link mode of pf */
HLCGE_MBX_PUSH_VLAN_INFO, /* (PF -> VF) push port base vlan */
HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */
HCLGE_MBX_PUSH_PROMISC_INFO, /* (PF -> VF) push vf promisc info */
HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf flr status */
HCLGE_MBX_PUSH_LINK_STATUS, /* (M7 -> PF) get port link status */
......
......@@ -360,6 +360,9 @@ struct hnae3_ae_dev {
* Check the 5-tuples of flow, and create flow director rule
* set_vf_spoofchk
* Enable/disable spoof check for specified vf
* set_vf_trust
* Enable/disable trust for specified vf, if the vf being trusted, then
* it can enable promisc mode
*/
struct hnae3_ae_ops {
int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
......@@ -542,6 +545,7 @@ struct hnae3_ae_ops {
int (*set_vf_link_state)(struct hnae3_handle *handle, int vf,
int link_state);
int (*set_vf_mac)(struct hnae3_handle *handle, int vf, u8 *p);
int (*set_vf_trust)(struct hnae3_handle *handle, int vf, bool enable);
};
struct hnae3_dcb_ops {
......
......@@ -174,8 +174,7 @@ bool hclge_reset_done_it(struct hnae3_handle *handle, bool done)
#define HCLGE_NAME_IT "hclge"
EXPORT_SYMBOL(hclge_get_vport);
EXPORT_SYMBOL(hclge_cmd_set_promisc_mode);
EXPORT_SYMBOL(hclge_promisc_param_init);
EXPORT_SYMBOL(hclge_set_vport_promisc_mode);
int hclge_init_it(void)
{
......
......@@ -47,7 +47,6 @@ int hns3_set_promisc_mode_cfg(struct hns3_nic_priv *nic_dev,
{
struct promisc_mode_param *mode_param;
struct hclge_promisc_cfg_cmd *req;
struct hclge_promisc_param param;
enum hclge_cmd_status status;
struct hclge_vport *vport;
struct hclge_dev *hdev;
......@@ -108,9 +107,7 @@ int hns3_set_promisc_mode_cfg(struct hns3_nic_priv *nic_dev,
return -1;
}
hclge_promisc_param_init(&param, en_uc, en_mc, en_bc, vport->vport_id);
return hclge_cmd_set_promisc_mode(hdev, &param);
return hclge_set_vport_promisc_mode(vport, en_uc, en_mc, en_bc);
}
int hns3_promisc_mode_cfg(struct hns3_nic_priv *nic_dev,
......
......@@ -1728,6 +1728,16 @@ static int hns3_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable)
return handle->ae_algo->ops->set_vf_spoofchk(handle, vf, enable);
}
static int hns3_set_vf_trust(struct net_device *netdev, int vf, bool enable)
{
struct hnae3_handle *handle = hns3_get_handle(netdev);
if (!handle->ae_algo->ops->set_vf_trust)
return -EOPNOTSUPP;
return handle->ae_algo->ops->set_vf_trust(handle, vf, enable);
}
static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
......@@ -1951,6 +1961,7 @@ struct net_device_ops hns3_nic_netdev_ops = {
.ndo_vlan_rx_kill_vid = hns3_vlan_rx_kill_vid,
.ndo_set_vf_vlan = hns3_ndo_set_vf_vlan,
.ndo_set_vf_spoofchk = hns3_set_vf_spoofchk,
.ndo_set_vf_trust = hns3_set_vf_trust,
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = hns3_rx_flow_steer,
#endif
......
......@@ -1121,9 +1121,6 @@ void hclge_cmd_setup_basic_desc(struct hclge_desc *desc,
enum hclge_opcode_type opcode, bool is_read);
void hclge_cmd_reuse_desc(struct hclge_desc *desc, bool is_read);
int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
struct hclge_promisc_param *param);
enum hclge_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw,
struct hclge_desc *desc);
enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw *hw,
......
......@@ -2867,6 +2867,7 @@ static int hclge_get_vf_config(struct hnae3_handle *handle, int vf,
ivf->vf = vf;
ivf->linkstate = vport->link_state;
ivf->spoofchk = vport->spoofchk;
ivf->trusted = vport->trusted;
ether_addr_copy(ivf->mac, vport->mac);
return 0;
......@@ -4663,8 +4664,8 @@ static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle, int vector,
return ret;
}
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,
struct hclge_promisc_param *param)
{
struct hclge_promisc_cfg_cmd *req;
struct hclge_desc desc;
......@@ -4691,8 +4692,9 @@ int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
return ret;
}
void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
bool en_mc, bool en_bc, int vport_id)
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;
......@@ -4707,12 +4709,21 @@ void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
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);
}
static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
bool en_mc_pmc)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
struct hclge_promisc_param param;
bool en_bc_pmc = true;
/* For revision 0x20, if broadcast promisc enabled, vlan filter is
......@@ -4722,9 +4733,8 @@ static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
if (handle->pdev->revision == 0x20)
en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false;
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_set_vport_promisc_mode(vport, en_uc_pmc, en_mc_pmc,
en_bc_pmc);
}
static int hclge_get_fd_mode(struct hclge_dev *hdev, u8 *fd_mode)
......@@ -9579,6 +9589,36 @@ static int hclge_reset_vport_spoofchk(struct hclge_dev *hdev)
return 0;
}
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;
u32 new_trusted = enable ? 1 : 0;
bool en_bc_pmc;
int ret;
vport = hclge_get_vf_vport(hdev, vf);
if (!vport)
return -EINVAL;
if (vport->trusted == new_trusted)
return 0;
/* Disable promisc mode for VF if it is not trusted any more. */
if (!enable && vport->promisc_enable) {
en_bc_pmc = hdev->pdev->revision == 0x20 ? false : true;
ret = hclge_set_vport_promisc_mode(vport, false, false,
en_bc_pmc);
if (ret)
return ret;
vport->promisc_enable = 0;
hclge_inform_vf_promisc_info(vport);
}
vport->trusted = new_trusted;
return 0;
}
static void hclge_reset_vport_state(struct hclge_dev *hdev)
{
struct hclge_vport *vport = hdev->vport;
......@@ -10426,6 +10466,7 @@ struct hnae3_ae_ops hclge_ops = {
.set_vf_link_state = hclge_set_vf_link_state,
.set_vf_spoofchk = hclge_set_vf_spoofchk,
.set_vf_mac = hclge_set_vf_mac,
.set_vf_trust = hclge_set_vf_trust,
};
struct hnae3_ae_algo ae_algo = {
......
......@@ -977,14 +977,15 @@ struct hclge_vport {
int mps; /* Max packet size */
u32 spoofchk;
u32 trusted;
u16 promisc_enable;
struct list_head uc_mac_list; /* Store VF unicast table */
struct list_head mc_mac_list; /* Store VF multicast table */
};
void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
bool en_mc, bool en_bc, int vport_id);
int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc,
bool en_mc_pmc, bool en_bc_pmc);
int hclge_add_uc_addr_common(struct hclge_vport *vport,
const unsigned char *addr);
int hclge_rm_uc_addr_common(struct hclge_vport *vport,
......@@ -1051,4 +1052,5 @@ enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev,
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
struct hclge_desc *desc);
void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
#endif
......@@ -233,12 +233,38 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en,
static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *req)
{
bool en_bc = req->msg[1] ? true : false;
struct hclge_promisc_param param;
#define HCLGE_MBX_BC_INDEX 1
#define HCLGE_MBX_UC_INDEX 2
#define HCLGE_MBX_MC_INDEX 3
/* vf is not allowed to enable unicast/multicast broadcast */
hclge_promisc_param_init(&param, false, false, en_bc, vport->vport_id);
return hclge_cmd_set_promisc_mode(vport->back, &param);
bool en_bc = req->msg[HCLGE_MBX_BC_INDEX] ? true : false;
bool en_uc = req->msg[HCLGE_MBX_UC_INDEX] ? true : false;
bool en_mc = req->msg[HCLGE_MBX_MC_INDEX] ? true : false;
int ret;
if (!vport->trusted) {
en_uc = false;
en_mc = false;
}
ret = hclge_set_vport_promisc_mode(vport, en_uc, en_mc, en_bc);
if (req->mbx_need_resp)
hclge_gen_resp_to_vf(vport, req, ret, NULL, 0);
vport->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->promisc_enable, sizeof(u16));
(void)hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
HCLGE_MBX_PUSH_PROMISC_INFO, dest_vfid);
}
static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
......
......@@ -1114,6 +1114,7 @@ static int hclgevf_put_vector(struct hnae3_handle *handle, int vector)
}
static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
bool en_uc_pmc, bool en_mc_pmc,
bool en_bc_pmc)
{
struct hclge_mbx_vf_to_pf_cmd *req;
......@@ -1121,10 +1122,11 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
int ret;
req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE;
req->msg[1] = en_bc_pmc ? 1 : 0;
req->msg[2] = en_uc_pmc ? 1 : 0;
req->msg[3] = en_mc_pmc ? 1 : 0;
ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (ret)
......@@ -1134,9 +1136,17 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
return ret;
}
static int hclgevf_set_promisc_mode(struct hclgevf_dev *hdev, bool en_bc_pmc)
static int hclgevf_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
bool en_mc_pmc)
{
return hclgevf_cmd_set_promisc_mode(hdev, en_bc_pmc);
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct pci_dev *pdev = hdev->pdev;
bool en_bc_pmc;
en_bc_pmc = pdev->revision == 0x20 ? false : true;
return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc,
en_bc_pmc);
}
static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, unsigned int tqp_id,
......@@ -2675,13 +2685,6 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
dev_err(&pdev->dev, "Enable tso fail, ret =%d\n", ret);
return ret;
}
ret = hclgevf_set_promisc_mode(hdev, true);
if (ret) {
dev_err(&pdev->dev,
"Enable promisc mode fail, ret =%d\n", ret);
return ret;
}
}
/* Initialize RSS for this VF */
......@@ -2775,15 +2778,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
dev_err(&pdev->dev, "Enable gro fail, ret=%d\n", ret);
goto err_config;
}
/* vf is not allowed to enable unicast/multicast promisc mode.
* For revision 0x20, default to disable broadcast promisc mode,
* firmware makes sure broadcast packets can be accepted.
* For revision 0x21, default to enable broadcast promisc mode.
*/
ret = hclgevf_set_promisc_mode(hdev, true);
if (ret)
goto err_config;
}
/* Initialize RSS for this VF */
......@@ -3201,6 +3195,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.set_mtu = hclgevf_set_mtu,
.get_global_queue_id = hclgevf_get_qid_global,
.get_link_mode = hclgevf_get_link_mode,
.set_promisc_mode = hclgevf_set_promisc_mode,
};
static struct hnae3_ae_algo ae_algovf = {
......
......@@ -232,6 +232,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
case HCLGE_MBX_ASSERTING_RESET:
case HCLGE_MBX_LINK_STAT_MODE:
case HLCGE_MBX_PUSH_VLAN_INFO:
case HCLGE_MBX_PUSH_PROMISC_INFO:
/* set this mbx event as pending. This is required as we
* might loose interrupt event when mbx task is busy
* handling. This shall be cleared when mbx task just
......@@ -275,6 +276,14 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
crq->next_to_use);
}
static void hclgevf_parse_promisc_info(struct hclgevf_dev *hdev,
u16 promisc_info)
{
if (!promisc_info)
dev_info(&hdev->pdev->dev,
"Promisc mode is closed by host for being untrusted.\n");
}
void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
{
enum hnae3_reset_type reset_type;
......@@ -343,6 +352,9 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
(u8 *)vlan_info,
8);
break;
case HCLGE_MBX_PUSH_PROMISC_INFO:
hclgevf_parse_promisc_info(hdev, msg_q[1]);
break;
default:
dev_err(&hdev->pdev->dev,
"fetched unsupported(%d) message from arq\n",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册