Commit 48423dd7 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'hns3-next' into net-next

Huazhong Tan says:

====================
This patch-set includes some new features for the HNS3 ethernet
controller driver.

[patch 01/06] adds support for configuring VF link status on the host.

[patch 02/06] adds support for configuring VF spoof check.

[patch 03/06] adds support for configuring VF trust.

[patch 04/06] adds support for configuring VF bandwidth on the host.

[patch 05/06] adds support for configuring VF MAC on the host.

[patch 06/06] adds support for tx-scatter-gather-fraglist.
====================
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
parents 11fc7d5a 8ae10cfb
...@@ -45,6 +45,7 @@ enum HCLGE_MBX_OPCODE { ...@@ -45,6 +45,7 @@ enum HCLGE_MBX_OPCODE {
HCLGE_MBX_GET_LINK_MODE, /* (VF -> PF) get the link mode of pf */ HCLGE_MBX_GET_LINK_MODE, /* (VF -> PF) get the link mode of pf */
HCLGE_MBX_PUSH_VLAN_INFO, /* (PF -> VF) push port base vlan */ HCLGE_MBX_PUSH_VLAN_INFO, /* (PF -> VF) push port base vlan */
HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */ 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 reset status */ HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */
HCLGE_MBX_PUSH_LINK_STATUS, /* (M7 -> PF) get port link status */ HCLGE_MBX_PUSH_LINK_STATUS, /* (M7 -> PF) get port link status */
......
...@@ -364,6 +364,19 @@ struct hnae3_ae_dev { ...@@ -364,6 +364,19 @@ struct hnae3_ae_dev {
* Enable/disable HW GRO * Enable/disable HW GRO
* add_arfs_entry * add_arfs_entry
* Check the 5-tuples of flow, and create flow director rule * Check the 5-tuples of flow, and create flow director rule
* get_vf_config
* Get the VF configuration setting by the host
* set_vf_link_state
* Set VF link status
* 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
* set_vf_rate
* Set the max tx rate of specified vf.
* set_vf_mac
* Configure the default MAC for specified VF
*/ */
struct hnae3_ae_ops { struct hnae3_ae_ops {
int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev); int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
...@@ -529,6 +542,16 @@ struct hnae3_ae_ops { ...@@ -529,6 +542,16 @@ struct hnae3_ae_ops {
int (*mac_connect_phy)(struct hnae3_handle *handle); int (*mac_connect_phy)(struct hnae3_handle *handle);
void (*mac_disconnect_phy)(struct hnae3_handle *handle); void (*mac_disconnect_phy)(struct hnae3_handle *handle);
void (*restore_vlan_table)(struct hnae3_handle *handle); void (*restore_vlan_table)(struct hnae3_handle *handle);
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);
int (*set_vf_spoofchk)(struct hnae3_handle *handle, int vf,
bool enable);
int (*set_vf_trust)(struct hnae3_handle *handle, int vf, bool enable);
int (*set_vf_rate)(struct hnae3_handle *handle, int vf,
int min_tx_rate, int max_tx_rate, bool force);
int (*set_vf_mac)(struct hnae3_handle *handle, int vf, u8 *p);
}; };
struct hnae3_dcb_ops { struct hnae3_dcb_ops {
......
...@@ -76,7 +76,7 @@ enum hns3_nic_state { ...@@ -76,7 +76,7 @@ enum hns3_nic_state {
#define HNS3_RING_NAME_LEN 16 #define HNS3_RING_NAME_LEN 16
#define HNS3_BUFFER_SIZE_2048 2048 #define HNS3_BUFFER_SIZE_2048 2048
#define HNS3_RING_MAX_PENDING 32760 #define HNS3_RING_MAX_PENDING 32760
#define HNS3_RING_MIN_PENDING 24 #define HNS3_RING_MIN_PENDING 72
#define HNS3_RING_BD_MULTIPLE 8 #define HNS3_RING_BD_MULTIPLE 8
/* max frame size of mac */ /* max frame size of mac */
#define HNS3_MAC_MAX_FRAME 9728 #define HNS3_MAC_MAX_FRAME 9728
...@@ -195,9 +195,13 @@ enum hns3_nic_state { ...@@ -195,9 +195,13 @@ enum hns3_nic_state {
#define HNS3_VECTOR_INITED 1 #define HNS3_VECTOR_INITED 1
#define HNS3_MAX_BD_SIZE 65535 #define HNS3_MAX_BD_SIZE 65535
#define HNS3_MAX_BD_NUM_NORMAL 8 #define HNS3_MAX_NON_TSO_BD_NUM 8U
#define HNS3_MAX_BD_NUM_TSO 63 #define HNS3_MAX_TSO_BD_NUM 63U
#define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS #define HNS3_MAX_TSO_SIZE \
(HNS3_MAX_BD_SIZE * HNS3_MAX_TSO_BD_NUM)
#define HNS3_MAX_NON_TSO_SIZE \
(HNS3_MAX_BD_SIZE * HNS3_MAX_NON_TSO_BD_NUM)
#define HNS3_VECTOR_GL0_OFFSET 0x100 #define HNS3_VECTOR_GL0_OFFSET 0x100
#define HNS3_VECTOR_GL1_OFFSET 0x200 #define HNS3_VECTOR_GL1_OFFSET 0x200
......
...@@ -244,7 +244,7 @@ enum hclge_opcode_type { ...@@ -244,7 +244,7 @@ enum hclge_opcode_type {
/* QCN commands */ /* QCN commands */
HCLGE_OPC_QCN_MOD_CFG = 0x1A01, HCLGE_OPC_QCN_MOD_CFG = 0x1A01,
HCLGE_OPC_QCN_GRP_TMPLT_CFG = 0x1A02, HCLGE_OPC_QCN_GRP_TMPLT_CFG = 0x1A02,
HCLGE_OPC_QCN_SHAPPING_IR_CFG = 0x1A03, HCLGE_OPC_QCN_SHAPPING_CFG = 0x1A03,
HCLGE_OPC_QCN_SHAPPING_BS_CFG = 0x1A04, HCLGE_OPC_QCN_SHAPPING_BS_CFG = 0x1A04,
HCLGE_OPC_QCN_QSET_LINK_CFG = 0x1A05, HCLGE_OPC_QCN_QSET_LINK_CFG = 0x1A05,
HCLGE_OPC_QCN_RP_STATUS_GET = 0x1A06, HCLGE_OPC_QCN_RP_STATUS_GET = 0x1A06,
...@@ -1090,9 +1090,6 @@ void hclge_cmd_setup_basic_desc(struct hclge_desc *desc, ...@@ -1090,9 +1090,6 @@ void hclge_cmd_setup_basic_desc(struct hclge_desc *desc,
enum hclge_opcode_type opcode, bool is_read); enum hclge_opcode_type opcode, bool is_read);
void hclge_cmd_reuse_desc(struct hclge_desc *desc, 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, enum hclge_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw,
struct hclge_desc *desc); struct hclge_desc *desc);
enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw *hw, enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw *hw,
......
...@@ -1110,6 +1110,82 @@ static void hclge_dbg_dump_mac_tnl_status(struct hclge_dev *hdev) ...@@ -1110,6 +1110,82 @@ static void hclge_dbg_dump_mac_tnl_status(struct hclge_dev *hdev)
} }
} }
static void hclge_dbg_dump_qs_shaper_single(struct hclge_dev *hdev, u16 qsid)
{
struct hclge_qs_shapping_cmd *shap_cfg_cmd;
u8 ir_u, ir_b, ir_s, bs_b, bs_s;
struct hclge_desc desc;
u32 shapping_para;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, true);
shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data;
shap_cfg_cmd->qs_id = cpu_to_le16(qsid);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"qs%u failed to get tx_rate, ret=%d\n",
qsid, ret);
return;
}
shapping_para = le32_to_cpu(shap_cfg_cmd->qs_shapping_para);
ir_b = hclge_tm_get_field(shapping_para, IR_B);
ir_u = hclge_tm_get_field(shapping_para, IR_U);
ir_s = hclge_tm_get_field(shapping_para, IR_S);
bs_b = hclge_tm_get_field(shapping_para, BS_B);
bs_s = hclge_tm_get_field(shapping_para, BS_S);
dev_info(&hdev->pdev->dev,
"qs%u ir_b:%u, ir_u:%u, ir_s:%u, bs_b:%u, bs_s:%u\n",
qsid, ir_b, ir_u, ir_s, bs_b, bs_s);
}
static void hclge_dbg_dump_qs_shaper_all(struct hclge_dev *hdev)
{
struct hnae3_knic_private_info *kinfo;
struct hclge_vport *vport;
int vport_id, i;
for (vport_id = 0; vport_id <= pci_num_vf(hdev->pdev); vport_id++) {
vport = &hdev->vport[vport_id];
kinfo = &vport->nic.kinfo;
dev_info(&hdev->pdev->dev, "qs cfg of vport%d:\n", vport_id);
for (i = 0; i < kinfo->num_tc; i++) {
u16 qsid = vport->qs_offset + i;
hclge_dbg_dump_qs_shaper_single(hdev, qsid);
}
}
}
static void hclge_dbg_dump_qs_shaper(struct hclge_dev *hdev,
const char *cmd_buf)
{
#define HCLGE_MAX_QSET_NUM 1024
u16 qsid;
int ret;
ret = kstrtou16(cmd_buf, 0, &qsid);
if (ret) {
hclge_dbg_dump_qs_shaper_all(hdev);
return;
}
if (qsid >= HCLGE_MAX_QSET_NUM) {
dev_err(&hdev->pdev->dev, "qsid(%u) out of range[0-1023]\n",
qsid);
return;
}
hclge_dbg_dump_qs_shaper_single(hdev, qsid);
}
int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf)
{ {
#define DUMP_REG "dump reg" #define DUMP_REG "dump reg"
...@@ -1145,6 +1221,9 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) ...@@ -1145,6 +1221,9 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf)
&cmd_buf[sizeof("dump ncl_config")]); &cmd_buf[sizeof("dump ncl_config")]);
} else if (strncmp(cmd_buf, "dump mac tnl status", 19) == 0) { } else if (strncmp(cmd_buf, "dump mac tnl status", 19) == 0) {
hclge_dbg_dump_mac_tnl_status(hdev); hclge_dbg_dump_mac_tnl_status(hdev);
} else if (strncmp(cmd_buf, "dump qs shaper", 14) == 0) {
hclge_dbg_dump_qs_shaper(hdev,
&cmd_buf[sizeof("dump qs shaper")]);
} else { } else {
dev_info(&hdev->pdev->dev, "unknown command\n"); dev_info(&hdev->pdev->dev, "unknown command\n");
return -EINVAL; return -EINVAL;
......
...@@ -258,6 +258,7 @@ struct hclge_mac { ...@@ -258,6 +258,7 @@ struct hclge_mac {
u8 support_autoneg; u8 support_autoneg;
u8 speed_type; /* 0: sfp speed, 1: active speed */ u8 speed_type; /* 0: sfp speed, 1: active speed */
u32 speed; u32 speed;
u32 max_speed;
u32 speed_ability; /* speed ability supported by current media */ u32 speed_ability; /* speed ability supported by current media */
u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */ u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */
u32 fec_mode; /* active fec mode */ u32 fec_mode; /* active fec mode */
...@@ -885,6 +886,15 @@ struct hclge_port_base_vlan_config { ...@@ -885,6 +886,15 @@ struct hclge_port_base_vlan_config {
struct hclge_vlan_info vlan_info; struct hclge_vlan_info vlan_info;
}; };
struct hclge_vf_info {
int link_state;
u8 mac[ETH_ALEN];
u32 spoofchk;
u32 max_tx_rate;
u32 trusted;
u16 promisc_enable;
};
struct hclge_vport { struct hclge_vport {
u16 alloc_tqps; /* Allocated Tx/Rx queues */ u16 alloc_tqps; /* Allocated Tx/Rx queues */
...@@ -916,15 +926,15 @@ struct hclge_vport { ...@@ -916,15 +926,15 @@ struct hclge_vport {
unsigned long state; unsigned long state;
unsigned long last_active_jiffies; unsigned long last_active_jiffies;
u32 mps; /* Max packet size */ u32 mps; /* Max packet size */
struct hclge_vf_info vf_info;
struct list_head uc_mac_list; /* Store VF unicast table */ struct list_head uc_mac_list; /* Store VF unicast table */
struct list_head mc_mac_list; /* Store VF multicast table */ struct list_head mc_mac_list; /* Store VF multicast table */
struct list_head vlan_list; /* Store VF vlan table */ struct list_head vlan_list; /* Store VF vlan table */
}; };
void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc, int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc,
bool en_mc, bool en_bc, int vport_id); bool en_mc_pmc, bool en_bc_pmc);
int hclge_add_uc_addr_common(struct hclge_vport *vport, int hclge_add_uc_addr_common(struct hclge_vport *vport,
const unsigned char *addr); const unsigned char *addr);
int hclge_rm_uc_addr_common(struct hclge_vport *vport, int hclge_rm_uc_addr_common(struct hclge_vport *vport,
...@@ -993,4 +1003,5 @@ int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, ...@@ -993,4 +1003,5 @@ int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
struct hclge_desc *desc); struct hclge_desc *desc);
void hclge_report_hw_error(struct hclge_dev *hdev, void hclge_report_hw_error(struct hclge_dev *hdev,
enum hnae3_hw_error_type type); enum hnae3_hw_error_type type);
void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
#endif #endif
...@@ -205,12 +205,38 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en, ...@@ -205,12 +205,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, static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *req) struct hclge_mbx_vf_to_pf_cmd *req)
{ {
bool en_bc = req->msg[1] ? true : false; #define HCLGE_MBX_BC_INDEX 1
struct hclge_promisc_param param; #define HCLGE_MBX_UC_INDEX 2
#define HCLGE_MBX_MC_INDEX 3
/* vf is not allowed to enable unicast/multicast broadcast */ bool en_bc = req->msg[HCLGE_MBX_BC_INDEX] ? true : false;
hclge_promisc_param_init(&param, false, false, en_bc, vport->vport_id); bool en_uc = req->msg[HCLGE_MBX_UC_INDEX] ? true : false;
return hclge_cmd_set_promisc_mode(vport->back, &param); bool en_mc = req->msg[HCLGE_MBX_MC_INDEX] ? true : false;
int ret;
if (!vport->vf_info.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->vf_info.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->vf_info.promisc_enable, sizeof(u16));
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, static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
...@@ -223,6 +249,20 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, ...@@ -223,6 +249,20 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_MODIFY) {
const u8 *old_addr = (const u8 *)(&mbx_req->msg[8]); const u8 *old_addr = (const u8 *)(&mbx_req->msg[8]);
/* If VF MAC has been configured by the host then it
* cannot be overridden by the MAC specified by the VM.
*/
if (!is_zero_ether_addr(vport->vf_info.mac) &&
!ether_addr_equal(mac_addr, vport->vf_info.mac)) {
status = -EPERM;
goto out;
}
if (!is_valid_ether_addr(mac_addr)) {
status = -EINVAL;
goto out;
}
hclge_rm_uc_addr_common(vport, old_addr); hclge_rm_uc_addr_common(vport, old_addr);
status = hclge_add_uc_addr_common(vport, mac_addr); status = hclge_add_uc_addr_common(vport, mac_addr);
if (status) { if (status) {
...@@ -250,6 +290,7 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, ...@@ -250,6 +290,7 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
return -EIO; return -EIO;
} }
out:
if (mbx_req->mbx_need_resp & HCLGE_MBX_NEED_RESP_BIT) if (mbx_req->mbx_need_resp & HCLGE_MBX_NEED_RESP_BIT)
hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0);
...@@ -324,6 +365,9 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, ...@@ -324,6 +365,9 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport,
proto = msg_cmd->proto; proto = msg_cmd->proto;
status = hclge_set_vlan_filter(handle, cpu_to_be16(proto), status = hclge_set_vlan_filter(handle, cpu_to_be16(proto),
vlan, is_kill); vlan, is_kill);
if (mbx_req->mbx_need_resp)
return hclge_gen_resp_to_vf(vport, mbx_req, status,
NULL, 0);
} else if (msg_cmd->subcode == HCLGE_MBX_VLAN_RX_OFF_CFG) { } else if (msg_cmd->subcode == HCLGE_MBX_VLAN_RX_OFF_CFG) {
struct hnae3_handle *handle = &vport->nic; struct hnae3_handle *handle = &vport->nic;
bool en = msg_cmd->is_kill ? true : false; bool en = msg_cmd->is_kill ? true : false;
...@@ -398,6 +442,13 @@ static int hclge_get_vf_queue_info(struct hclge_vport *vport, ...@@ -398,6 +442,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->vf_info.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)
...@@ -428,6 +479,9 @@ static int hclge_get_vf_media_type(struct hclge_vport *vport, ...@@ -428,6 +479,9 @@ static int hclge_get_vf_media_type(struct hclge_vport *vport,
static int hclge_get_link_info(struct hclge_vport *vport, static int hclge_get_link_info(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *mbx_req) 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; struct hclge_dev *hdev = vport->back;
u16 link_status; u16 link_status;
u8 msg_data[8]; u8 msg_data[8];
...@@ -435,7 +489,19 @@ static int hclge_get_link_info(struct hclge_vport *vport, ...@@ -435,7 +489,19 @@ static int hclge_get_link_info(struct hclge_vport *vport,
u16 duplex; u16 duplex;
/* mac.link can only be 0 or 1 */ /* mac.link can only be 0 or 1 */
link_status = (u16)hdev->hw.mac.link; switch (vport->vf_info.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; duplex = hdev->hw.mac.duplex;
memcpy(&msg_data[0], &link_status, sizeof(u16)); memcpy(&msg_data[0], &link_status, sizeof(u16));
memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32)); memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
...@@ -749,6 +815,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev) ...@@ -749,6 +815,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
case HCLGE_MBX_PUSH_LINK_STATUS: case HCLGE_MBX_PUSH_LINK_STATUS:
hclge_handle_link_change_event(hdev, req); hclge_handle_link_change_event(hdev, req);
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:
hclge_handle_ncsi_error(hdev); hclge_handle_ncsi_error(hdev);
break; break;
......
...@@ -511,6 +511,49 @@ static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id, ...@@ -511,6 +511,49 @@ static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id,
return hclge_cmd_send(&hdev->hw, &desc, 1); return hclge_cmd_send(&hdev->hw, &desc, 1);
} }
int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate)
{
struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
struct hclge_qs_shapping_cmd *shap_cfg_cmd;
struct hclge_dev *hdev = vport->back;
struct hclge_desc desc;
u8 ir_b, ir_u, ir_s;
u32 shaper_para;
int ret, i;
if (!max_tx_rate)
max_tx_rate = HCLGE_ETHER_MAX_RATE;
ret = hclge_shaper_para_calc(max_tx_rate, HCLGE_SHAPER_LVL_QSET,
&ir_b, &ir_u, &ir_s);
if (ret)
return ret;
shaper_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s,
HCLGE_SHAPER_BS_U_DEF,
HCLGE_SHAPER_BS_S_DEF);
for (i = 0; i < kinfo->num_tc; i++) {
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG,
false);
shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data;
shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i);
shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"vf%d, qs%u failed to set tx_rate:%d, ret=%d\n",
vport->vport_id, shap_cfg_cmd->qs_id,
max_tx_rate, ret);
return ret;
}
}
return 0;
}
static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
{ {
struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
......
...@@ -96,6 +96,12 @@ struct hclge_pg_shapping_cmd { ...@@ -96,6 +96,12 @@ struct hclge_pg_shapping_cmd {
__le32 pg_shapping_para; __le32 pg_shapping_para;
}; };
struct hclge_qs_shapping_cmd {
__le16 qs_id;
u8 rsvd[2];
__le32 qs_shapping_para;
};
#define HCLGE_BP_GRP_NUM 32 #define HCLGE_BP_GRP_NUM 32
#define HCLGE_BP_SUB_GRP_ID_S 0 #define HCLGE_BP_SUB_GRP_ID_S 0
#define HCLGE_BP_SUB_GRP_ID_M GENMASK(4, 0) #define HCLGE_BP_SUB_GRP_ID_M GENMASK(4, 0)
...@@ -154,4 +160,6 @@ int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); ...@@ -154,4 +160,6 @@ int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate);
#endif #endif
...@@ -1105,6 +1105,7 @@ static int hclgevf_put_vector(struct hnae3_handle *handle, int vector) ...@@ -1105,6 +1105,7 @@ static int hclgevf_put_vector(struct hnae3_handle *handle, int vector)
} }
static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
bool en_uc_pmc, bool en_mc_pmc,
bool en_bc_pmc) bool en_bc_pmc)
{ {
struct hclge_mbx_vf_to_pf_cmd *req; struct hclge_mbx_vf_to_pf_cmd *req;
...@@ -1112,10 +1113,11 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, ...@@ -1112,10 +1113,11 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
int ret; int ret;
req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE;
req->msg[1] = en_bc_pmc ? 1 : 0; 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); ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (ret) if (ret)
...@@ -1125,9 +1127,17 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, ...@@ -1125,9 +1127,17 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
return ret; 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;
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, static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, unsigned int tqp_id,
...@@ -1166,11 +1176,37 @@ static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) ...@@ -1166,11 +1176,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) 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];
ether_addr_copy(p, hdev->hw.mac.mac_addr); 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);
} }
static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p, static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p,
...@@ -1267,7 +1303,7 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, ...@@ -1267,7 +1303,7 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle,
memcpy(&msg_data[3], &proto, sizeof(proto)); memcpy(&msg_data[3], &proto, sizeof(proto));
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
HCLGE_MBX_VLAN_FILTER, msg_data, HCLGE_MBX_VLAN_FILTER, msg_data,
HCLGEVF_VLAN_MBX_MSG_LEN, false, NULL, 0); HCLGEVF_VLAN_MBX_MSG_LEN, true, NULL, 0);
/* when remove hw vlan filter failed, record the vlan id, /* when remove hw vlan filter failed, record the vlan id,
* and try to remove it from hw later, to be consistence * and try to remove it from hw later, to be consistence
...@@ -2626,12 +2662,6 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) ...@@ -2626,12 +2662,6 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
return ret; return ret;
} }
if (pdev->revision >= 0x21) {
ret = hclgevf_set_promisc_mode(hdev, true);
if (ret)
return ret;
}
dev_info(&hdev->pdev->dev, "Reset done\n"); dev_info(&hdev->pdev->dev, "Reset done\n");
return 0; return 0;
...@@ -2706,17 +2736,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) ...@@ -2706,17 +2736,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
if (ret) if (ret)
goto err_config; 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.
*/
if (pdev->revision >= 0x21) {
ret = hclgevf_set_promisc_mode(hdev, true);
if (ret)
goto err_config;
}
/* Initialize RSS for this VF */ /* Initialize RSS for this VF */
ret = hclgevf_rss_init_hw(hdev); ret = hclgevf_rss_init_hw(hdev);
if (ret) { if (ret) {
...@@ -3130,6 +3149,7 @@ static const struct hnae3_ae_ops hclgevf_ops = { ...@@ -3130,6 +3149,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.get_global_queue_id = hclgevf_get_qid_global, .get_global_queue_id = hclgevf_get_qid_global,
.set_timer_task = hclgevf_set_timer_task, .set_timer_task = hclgevf_set_timer_task,
.get_link_mode = hclgevf_get_link_mode, .get_link_mode = hclgevf_get_link_mode,
.set_promisc_mode = hclgevf_set_promisc_mode,
}; };
static struct hnae3_ae_algo ae_algovf = { static struct hnae3_ae_algo ae_algovf = {
......
...@@ -266,6 +266,7 @@ struct hclgevf_dev { ...@@ -266,6 +266,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;
......
...@@ -205,6 +205,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) ...@@ -205,6 +205,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
case HCLGE_MBX_ASSERTING_RESET: case HCLGE_MBX_ASSERTING_RESET:
case HCLGE_MBX_LINK_STAT_MODE: case HCLGE_MBX_LINK_STAT_MODE:
case HCLGE_MBX_PUSH_VLAN_INFO: case HCLGE_MBX_PUSH_VLAN_INFO:
case HCLGE_MBX_PUSH_PROMISC_INFO:
/* set this mbx event as pending. This is required as we /* set this mbx event as pending. This is required as we
* might loose interrupt event when mbx task is busy * might loose interrupt event when mbx task is busy
* handling. This shall be cleared when mbx task just * handling. This shall be cleared when mbx task just
...@@ -248,6 +249,14 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) ...@@ -248,6 +249,14 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
crq->next_to_use); 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) void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
{ {
enum hnae3_reset_type reset_type; enum hnae3_reset_type reset_type;
...@@ -313,6 +322,9 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) ...@@ -313,6 +322,9 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
hclgevf_update_port_base_vlan_info(hdev, state, hclgevf_update_port_base_vlan_info(hdev, state,
(u8 *)vlan_info, 8); (u8 *)vlan_info, 8);
break; break;
case HCLGE_MBX_PUSH_PROMISC_INFO:
hclgevf_parse_promisc_info(hdev, msg_q[1]);
break;
default: default:
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"fetched unsupported(%d) message from arq\n", "fetched unsupported(%d) message from arq\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment