提交 308a2805 编写于 作者: H Huazhong Tan 提交者: Xie XiuQi

net: hns3: add support for configuring VF MAC on the host

driver inclusion
category: Feature
bugzilla: NA
CVE: NA

This patch adds support of configuring VF MAC on the host
for the HNS3 driver.

BTW, the parameter init in the hns3_init_mac_addr is
unnecessary now, since the MAC address will not read from
NCL_CONFIG when doing reset, so it should be removed,
otherwise it will affect VF's MAC address initialization.

Also, removes some unnecessary operations related to
vport MAC in hclge_set_vf_uc_mac_addr

Fixes: 79ea611f5673 ("net: hns3: add the function of setting VF status independently")

Feature or Bugfix:Bugfix
Signed-off-by: NHuazhong Tan <tanhuazhong@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>
上级 d4e83a9a
......@@ -541,6 +541,7 @@ struct hnae3_ae_ops {
struct ifla_vf_info *ivf);
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);
};
struct hnae3_dcb_ops {
......
......@@ -1916,6 +1916,23 @@ static int hns3_nic_set_vf_link_state(struct net_device *ndev, int vf,
return h->ae_algo->ops->set_vf_link_state(h, vf, link_state);
}
static int hns3_nic_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
if (!h->ae_algo->ops->set_vf_mac)
return -EOPNOTSUPP;
if (is_broadcast_ether_addr(mac) ||
is_multicast_ether_addr(mac)) {
netdev_err(netdev,
"Set VF MAC error! invalid mac:%pM.\n", mac);
return -EINVAL;
}
return h->ae_algo->ops->set_vf_mac(h, vf_id, mac);
}
struct net_device_ops hns3_nic_netdev_ops = {
.ndo_open = hns3_nic_net_open,
.ndo_stop = hns3_nic_net_stop,
......@@ -1939,6 +1956,7 @@ struct net_device_ops hns3_nic_netdev_ops = {
#endif
.ndo_get_vf_config = hns3_nic_get_vf_config,
.ndo_set_vf_link_state = hns3_nic_set_vf_link_state,
.ndo_set_vf_mac = hns3_nic_set_vf_mac,
};
......@@ -3868,14 +3886,14 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
}
/* Set mac addr if it is configured. or leave it to the AE driver */
static int hns3_init_mac_addr(struct net_device *netdev, bool init)
static int hns3_init_mac_addr(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
u8 mac_addr_temp[ETH_ALEN];
int ret = 0;
if (h->ae_algo->ops->get_mac_addr && init) {
if (h->ae_algo->ops->get_mac_addr) {
h->ae_algo->ops->get_mac_addr(h, mac_addr_temp);
ether_addr_copy(netdev->dev_addr, mac_addr_temp);
}
......@@ -3988,7 +4006,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
handle->kinfo.netdev = netdev;
handle->priv = (void *)priv;
hns3_init_mac_addr(netdev, true);
hns3_init_mac_addr(netdev);
hns3_set_default_feature(netdev);
......@@ -4467,7 +4485,7 @@ static int hns3_reset_notify_restore_enet(struct hnae3_handle *handle)
bool vlan_filter_enable;
int ret = 0;
ret = hns3_init_mac_addr(netdev, false);
ret = hns3_init_mac_addr(netdev);
if (ret)
return ret;
......
......@@ -2843,8 +2843,12 @@ static struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf)
{
#define HCLGE_VF_VPORT_START_NUM 1
if (vf < 0 || vf >= pci_num_vf(hdev->pdev))
if (vf < 0 || vf >= pci_num_vf(hdev->pdev)) {
dev_err(&hdev->pdev->dev,
"Out-of-range(1 < vfid < %d) or Invalid VF(=%d) specified.\n",
pci_num_vf(hdev->pdev), vf);
return NULL;
}
/* vf start from 1 in vport */
vf += HCLGE_VF_VPORT_START_NUM;
......@@ -2884,6 +2888,31 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
return 0;
}
static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
u8 *mac_addr)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
vport = hclge_get_vf_vport(hdev, vf);
if (!vport)
return -EINVAL;
if (ether_addr_equal(mac_addr, vport->mac)) {
dev_info(&hdev->pdev->dev,
"Specified MAC(=%pM) is same as before, no change committed!\n",
vport->mac);
return 0;
}
ether_addr_copy(vport->mac, mac_addr);
dev_info(&hdev->pdev->dev,
"VF %d has been set to %pM. Please reload/reset VF\n",
vf, vport->mac);
return 0;
}
static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
{
u32 rst_src_reg;
......@@ -10368,6 +10397,7 @@ struct hnae3_ae_ops hclge_ops = {
.get_vf_config = hclge_get_vf_config,
.set_vf_link_state = hclge_set_vf_link_state,
.set_vf_spoofchk = hclge_set_vf_spoofchk,
.set_vf_mac = hclge_set_vf_mac,
};
struct hnae3_ae_algo ae_algo = {
......
......@@ -260,21 +260,18 @@ 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) {
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) {
hclge_rm_vport_mac_table(vport, mac_addr,
false, HCLGE_MAC_ADDR_UC);
eth_zero_addr(vport->mac);
}
} else {
dev_err(&hdev->pdev->dev,
......@@ -433,6 +430,13 @@ static int hclge_get_vf_queue_info(struct hclge_vport *vport,
HCLGE_TQPS_RSS_INFO_LEN);
}
static int hclge_get_vf_mac_addr(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
{
return hclge_gen_resp_to_vf(vport, mbx_req, 0, vport->mac,
ETH_ALEN);
}
static int hclge_get_vf_queue_depth(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *mbx_req,
bool gen_resp)
......@@ -789,6 +793,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
"PF fail(%d) to media type for VF\n",
ret);
break;
case HCLGE_MBX_GET_MAC_ADDR:
ret = hclge_get_vf_mac_addr(vport, req);
if (ret)
dev_err(&hdev->pdev->dev,
"PF failed(%d) to get MAC for VF\n",
ret);
break;
case HCLGE_MBX_NCSI_ERROR:
ae_dev->ops->set_default_reset_request(ae_dev,
HNAE3_GLOBAL_RESET);
......
......@@ -1175,11 +1175,37 @@ static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle)
}
}
static int hclgevf_get_host_mac_addr(struct hclgevf_dev *hdev, u8 *p)
{
u8 host_mac[ETH_ALEN];
int status;
status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MAC_ADDR, 0, NULL, 0,
true, host_mac, ETH_ALEN);
if (status) {
dev_err(&hdev->pdev->dev,
"fail to get VF MAC from host %d", status);
return status;
}
ether_addr_copy(p, host_mac);
return 0;
}
static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
u8 host_mac_addr[ETH_ALEN];
if (hclgevf_get_host_mac_addr(hdev, host_mac_addr))
return;
ether_addr_copy(p, hdev->hw.mac.mac_addr);
hdev->has_pf_mac = !is_zero_ether_addr(host_mac_addr);
if (hdev->has_pf_mac)
ether_addr_copy(p, host_mac_addr);
else
ether_addr_copy(p, hdev->hw.mac.mac_addr);
}
static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p,
......@@ -1188,10 +1214,22 @@ static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p,
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr;
u8 *new_mac_addr = (u8 *)p;
u8 host_mac_addr[ETH_ALEN];
u8 msg_data[ETH_ALEN * 2];
u16 subcode;
int status;
status = hclgevf_get_host_mac_addr(hdev, host_mac_addr);
if (status)
return status;
if (!is_first && hdev->has_pf_mac) {
dev_err(&hdev->pdev->dev,
"has host VF mac %pM, user MAC %pM not allow\n",
old_mac_addr, p);
return -EPERM;
}
ether_addr_copy(msg_data, new_mac_addr);
ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr);
......
......@@ -267,6 +267,7 @@ struct hclgevf_dev {
u16 num_tx_desc; /* desc num of per tx queue */
u16 num_rx_desc; /* desc num of per rx queue */
u8 hw_tc_map;
u8 has_pf_mac;
u16 num_msi;
u16 num_msi_left;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册