提交 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 { ...@@ -541,6 +541,7 @@ struct hnae3_ae_ops {
struct ifla_vf_info *ivf); struct ifla_vf_info *ivf);
int (*set_vf_link_state)(struct hnae3_handle *handle, int vf, int (*set_vf_link_state)(struct hnae3_handle *handle, int vf,
int link_state); int link_state);
int (*set_vf_mac)(struct hnae3_handle *handle, int vf, u8 *p);
}; };
struct hnae3_dcb_ops { struct hnae3_dcb_ops {
......
...@@ -1916,6 +1916,23 @@ static int hns3_nic_set_vf_link_state(struct net_device *ndev, int vf, ...@@ -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); 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 = { struct net_device_ops hns3_nic_netdev_ops = {
.ndo_open = hns3_nic_net_open, .ndo_open = hns3_nic_net_open,
.ndo_stop = hns3_nic_net_stop, .ndo_stop = hns3_nic_net_stop,
...@@ -1939,6 +1956,7 @@ struct net_device_ops hns3_nic_netdev_ops = { ...@@ -1939,6 +1956,7 @@ struct net_device_ops hns3_nic_netdev_ops = {
#endif #endif
.ndo_get_vf_config = hns3_nic_get_vf_config, .ndo_get_vf_config = hns3_nic_get_vf_config,
.ndo_set_vf_link_state = hns3_nic_set_vf_link_state, .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) ...@@ -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 */ /* 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 hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle; struct hnae3_handle *h = priv->ae_handle;
u8 mac_addr_temp[ETH_ALEN]; u8 mac_addr_temp[ETH_ALEN];
int ret = 0; 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); h->ae_algo->ops->get_mac_addr(h, mac_addr_temp);
ether_addr_copy(netdev->dev_addr, 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) ...@@ -3988,7 +4006,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
handle->kinfo.netdev = netdev; handle->kinfo.netdev = netdev;
handle->priv = (void *)priv; handle->priv = (void *)priv;
hns3_init_mac_addr(netdev, true); hns3_init_mac_addr(netdev);
hns3_set_default_feature(netdev); hns3_set_default_feature(netdev);
...@@ -4467,7 +4485,7 @@ static int hns3_reset_notify_restore_enet(struct hnae3_handle *handle) ...@@ -4467,7 +4485,7 @@ static int hns3_reset_notify_restore_enet(struct hnae3_handle *handle)
bool vlan_filter_enable; bool vlan_filter_enable;
int ret = 0; int ret = 0;
ret = hns3_init_mac_addr(netdev, false); ret = hns3_init_mac_addr(netdev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -2843,8 +2843,12 @@ static struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf) ...@@ -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 #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; return NULL;
}
/* vf start from 1 in vport */ /* vf start from 1 in vport */
vf += HCLGE_VF_VPORT_START_NUM; vf += HCLGE_VF_VPORT_START_NUM;
...@@ -2884,6 +2888,31 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, ...@@ -2884,6 +2888,31 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
return 0; 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) static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
{ {
u32 rst_src_reg; u32 rst_src_reg;
...@@ -10368,6 +10397,7 @@ struct hnae3_ae_ops hclge_ops = { ...@@ -10368,6 +10397,7 @@ struct hnae3_ae_ops hclge_ops = {
.get_vf_config = hclge_get_vf_config, .get_vf_config = hclge_get_vf_config,
.set_vf_link_state = hclge_set_vf_link_state, .set_vf_link_state = hclge_set_vf_link_state,
.set_vf_spoofchk = hclge_set_vf_spoofchk, .set_vf_spoofchk = hclge_set_vf_spoofchk,
.set_vf_mac = hclge_set_vf_mac,
}; };
struct hnae3_ae_algo ae_algo = { struct hnae3_ae_algo ae_algo = {
......
...@@ -260,21 +260,18 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, ...@@ -260,21 +260,18 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
false, HCLGE_MAC_ADDR_UC); false, HCLGE_MAC_ADDR_UC);
hclge_add_vport_mac_table(vport, mac_addr, hclge_add_vport_mac_table(vport, mac_addr,
HCLGE_MAC_ADDR_UC); HCLGE_MAC_ADDR_UC);
ether_addr_copy(vport->mac, mac_addr);
} }
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) { } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) {
status = hclge_add_uc_addr_common(vport, mac_addr); status = hclge_add_uc_addr_common(vport, mac_addr);
if (!status) { if (!status) {
hclge_add_vport_mac_table(vport, mac_addr, hclge_add_vport_mac_table(vport, mac_addr,
HCLGE_MAC_ADDR_UC); HCLGE_MAC_ADDR_UC);
ether_addr_copy(vport->mac, mac_addr);
} }
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) {
status = hclge_rm_uc_addr_common(vport, mac_addr); status = hclge_rm_uc_addr_common(vport, mac_addr);
if (!status) { if (!status) {
hclge_rm_vport_mac_table(vport, mac_addr, hclge_rm_vport_mac_table(vport, mac_addr,
false, HCLGE_MAC_ADDR_UC); false, HCLGE_MAC_ADDR_UC);
eth_zero_addr(vport->mac);
} }
} else { } else {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
...@@ -433,6 +430,13 @@ static int hclge_get_vf_queue_info(struct hclge_vport *vport, ...@@ -433,6 +430,13 @@ static int hclge_get_vf_queue_info(struct hclge_vport *vport,
HCLGE_TQPS_RSS_INFO_LEN); 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, static int hclge_get_vf_queue_depth(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *mbx_req, struct hclge_mbx_vf_to_pf_cmd *mbx_req,
bool gen_resp) bool gen_resp)
...@@ -789,6 +793,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev) ...@@ -789,6 +793,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
"PF fail(%d) to media type for VF\n", "PF fail(%d) to media type for VF\n",
ret); ret);
break; 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: case HCLGE_MBX_NCSI_ERROR:
ae_dev->ops->set_default_reset_request(ae_dev, ae_dev->ops->set_default_reset_request(ae_dev,
HNAE3_GLOBAL_RESET); HNAE3_GLOBAL_RESET);
......
...@@ -1175,10 +1175,36 @@ static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) ...@@ -1175,10 +1175,36 @@ 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) static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p)
{ {
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 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;
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); ether_addr_copy(p, hdev->hw.mac.mac_addr);
} }
...@@ -1188,10 +1214,22 @@ 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); struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr;
u8 *new_mac_addr = (u8 *)p; u8 *new_mac_addr = (u8 *)p;
u8 host_mac_addr[ETH_ALEN];
u8 msg_data[ETH_ALEN * 2]; u8 msg_data[ETH_ALEN * 2];
u16 subcode; u16 subcode;
int status; 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, new_mac_addr);
ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr);
......
...@@ -267,6 +267,7 @@ struct hclgevf_dev { ...@@ -267,6 +267,7 @@ struct hclgevf_dev {
u16 num_tx_desc; /* desc num of per tx queue */ u16 num_tx_desc; /* desc num of per tx queue */
u16 num_rx_desc; /* desc num of per rx queue */ u16 num_rx_desc; /* desc num of per rx queue */
u8 hw_tc_map; u8 hw_tc_map;
u8 has_pf_mac;
u16 num_msi; u16 num_msi;
u16 num_msi_left; u16 num_msi_left;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册