提交 a714d679 编写于 作者: Y Yufeng Mo 提交者: Xie XiuQi

net: hns3: add the function of setting VF status independently

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

This patch adds the function of setting VF status independently. The
options are auto, enable, and disable. Even if the PF is down, the
communication between VFs will be normal if the VFs are set to enable.
The commands are as follows:

'ip link set <pf> vf <vf_id> state <auto|enable|disable>'
set the vf status

'ip link show'
view the setting status

Feature or Bugfix:Bugfix
Signed-off-by: NYufeng Mo <moyufeng@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>
上级 64d129ca
......@@ -533,6 +533,10 @@ struct hnae3_ae_ops {
int (*priv_ops)(struct hnae3_handle *handle, int opcode,
void *data, int length);
#endif
int (*get_vf_config)(struct hnae3_handle *handle, int vf,
struct ifla_vf_info *ivf);
int (*set_vf_link_state)(struct hnae3_handle *handle, int vf,
int link_state);
};
struct hnae3_dcb_ops {
......
......@@ -1881,6 +1881,28 @@ static int hns3_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
}
#endif
static int hns3_nic_get_vf_config(struct net_device *ndev, int vf,
struct ifla_vf_info *ivf)
{
struct hnae3_handle *h = hns3_get_handle(ndev);
if (!h->ae_algo->ops->get_vf_config)
return -EOPNOTSUPP;
return h->ae_algo->ops->get_vf_config(h, vf, ivf);
}
static int hns3_nic_set_vf_link_state(struct net_device *ndev, int vf,
int link_state)
{
struct hnae3_handle *h = hns3_get_handle(ndev);
if (!h->ae_algo->ops->set_vf_link_state)
return -EOPNOTSUPP;
return h->ae_algo->ops->set_vf_link_state(h, vf, link_state);
}
struct net_device_ops hns3_nic_netdev_ops = {
.ndo_open = hns3_nic_net_open,
.ndo_stop = hns3_nic_net_stop,
......@@ -1901,6 +1923,8 @@ struct net_device_ops hns3_nic_netdev_ops = {
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = hns3_rx_flow_steer,
#endif
.ndo_get_vf_config = hns3_nic_get_vf_config,
.ndo_set_vf_link_state = hns3_nic_set_vf_link_state,
};
......
......@@ -1612,6 +1612,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
for (i = 0; i < num_vport; i++) {
vport->back = hdev;
vport->vport_id = i;
vport->link_state = IFLA_VF_LINK_STATE_AUTO;
vport->mps = HCLGE_MAC_DEFAULT_FRAME;
vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
vport->rxvlan_cfg.rx_vlan_offload_en = true;
......@@ -2830,6 +2831,39 @@ static int hclge_get_status(struct hnae3_handle *handle)
return hdev->hw.mac.link;
}
static int hclge_get_vf_config(struct hnae3_handle *handle, int vf,
struct ifla_vf_info *ivf)
{
#define HCLGE_VF_VPORT_START_NUM 1
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
if (vf < 0 || vf >= hdev->num_alloc_vport - HCLGE_VF_VPORT_START_NUM)
return -EINVAL;
/* vf start from 1 in vport */
vf += HCLGE_VF_VPORT_START_NUM;
ivf->vf = vf;
ivf->linkstate = hdev->vport[vf].link_state;
ether_addr_copy(ivf->mac, hdev->vport[vf].mac);
return 0;
}
static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
int link_state)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
if (vf <= 0 || vf >= hdev->num_alloc_vport)
return -EINVAL;
hdev->vport[vf].link_state = link_state;
return 0;
}
static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
{
u32 rst_src_reg;
......@@ -10185,6 +10219,8 @@ struct hnae3_ae_ops hclge_ops = {
.restore_vlan_table = hclge_restore_vlan_table,
.reset_done = hclge_reset_done,
.handle_imp_error = hclge_handle_imp_error,
.get_vf_config = hclge_get_vf_config,
.set_vf_link_state = hclge_set_vf_link_state,
};
struct hnae3_ae_algo ae_algo = {
......
......@@ -969,6 +969,8 @@ struct hclge_vport {
unsigned long state;
unsigned long last_active_jiffies;
int link_state;
u8 mac[ETH_ALEN];
int mps; /* Max packet size */
struct list_head uc_mac_list; /* Store VF unicast table */
......
......@@ -260,17 +260,22 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
false, HCLGE_MAC_ADDR_UC);
hclge_add_vport_mac_table(vport, mac_addr,
HCLGE_MAC_ADDR_UC);
ether_addr_copy(vport->mac, mac_addr);
}
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) {
status = hclge_add_uc_addr_common(vport, mac_addr);
if (!status)
if (!status) {
hclge_add_vport_mac_table(vport, mac_addr,
HCLGE_MAC_ADDR_UC);
ether_addr_copy(vport->mac, mac_addr);
}
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) {
status = hclge_rm_uc_addr_common(vport, mac_addr);
if (!status)
if (!status) {
hclge_rm_vport_mac_table(vport, mac_addr,
false, HCLGE_MAC_ADDR_UC);
eth_zero_addr(vport->mac);
}
} else {
dev_err(&hdev->pdev->dev,
"failed to set unicast mac addr, unknown subcode %d\n",
......@@ -455,6 +460,8 @@ static int hclge_get_vf_media_type(struct hclge_vport *vport,
static int hclge_get_link_info(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
{
#define HCLGE_VF_LINK_STATE_UP 1U
#define HCLGE_VF_LINK_STATE_DOWN 0U
struct hclge_dev *hdev = vport->back;
u16 link_status;
u8 msg_data[8];
......@@ -462,7 +469,19 @@ static int hclge_get_link_info(struct hclge_vport *vport,
u16 duplex;
/* mac.link can only be 0 or 1 */
link_status = (u16)hdev->hw.mac.link;
switch (vport->link_state) {
case IFLA_VF_LINK_STATE_ENABLE:
link_status = HCLGE_VF_LINK_STATE_UP;
break;
case IFLA_VF_LINK_STATE_DISABLE:
link_status = HCLGE_VF_LINK_STATE_DOWN;
break;
case IFLA_VF_LINK_STATE_AUTO:
default:
link_status = (u16)hdev->hw.mac.link;
break;
}
duplex = hdev->hw.mac.duplex;
memcpy(&msg_data[0], &link_status, sizeof(u16));
memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册