diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index c99c7d227ebc8b7d877c4450d616b8e79956948b..88110835e8767a670091ac001ddbca4e172339c6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -410,6 +410,13 @@ struct hclge_mac_vlan_tbl_entry_cmd { u8 rsv2[6]; }; +struct hclge_check_mac_addr_cmd { + u8 response; + u8 mac_addr[ETH_ALEN]; + u8 vf_id; + u8 rsv[16]; +}; + #define HCLGE_UMV_SPC_ALC_B 0 struct hclge_umv_spc_alc_cmd { u8 allocate; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 55170897ba6a94fe275c6dfd2bd26b86315ad507..fb357c32cd446036f737020f745110c29b98fa82 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -9059,6 +9059,35 @@ static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev, return return_status; } +int hclge_check_mac_addr_valid(struct hclge_dev *hdev, u8 vf, + const u8 *mac_addr) +{ + char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN]; + struct hclge_check_mac_addr_cmd *req; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_ADDR_CHECK, false); + req = (struct hclge_check_mac_addr_cmd *)desc.data; + ether_addr_copy(req->mac_addr, mac_addr); + req->vf_id = vf; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "failed to check function %u mac addr valid, ret = %d\n", + vf, ret); + return ret; + } + + if (req->response) { + hnae3_format_mac_addr(format_mac_addr, mac_addr); + dev_err(&hdev->pdev->dev, "invalid function %u mac addr: %s\n", + vf, format_mac_addr); + return -EINVAL; + } + + return 0; +} + static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf, u8 *mac_addr) { @@ -9213,6 +9242,12 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p, return -EINVAL; } + if (hnae3_check_roh_mac_type(handle)) { + ret = hclge_check_mac_addr_valid(hdev, 0, new_addr); + if (ret) + return ret; + } + ret = hclge_pause_addr_cfg(hdev, new_addr); if (ret) { dev_err(&hdev->pdev->dev, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 568ad7c0c1dec1ef7bcf146224e2315e3863aa1f..f48ba1e7589c860348865663b24425b89057f44e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -1124,6 +1124,8 @@ void hclge_report_hw_error(struct hclge_dev *hdev, enum hnae3_hw_error_type type); void hclge_inform_vf_promisc_info(struct hclge_vport *vport); int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len); +int hclge_check_mac_addr_valid(struct hclge_dev *hdev, u8 vf, + const u8 *mac_addr); int hclge_push_vf_link_status(struct hclge_vport *vport); int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en); int hclge_mac_update_stats(struct hclge_dev *hdev);