brintos

brintos / linux-shallow public Read only

0
0
Text · 20.0 KiB · 4ad4e8a Raw
686 lines · c
1// SPDX-License-Identifier: GPL-2.0+2// Copyright (c) 2021-2021 Hisilicon Limited.3 4#include "hnae3.h"5#include "hclge_comm_cmd.h"6 7static void hclge_comm_cmd_config_regs(struct hclge_comm_hw *hw,8				       struct hclge_comm_cmq_ring *ring)9{10	dma_addr_t dma = ring->desc_dma_addr;11	u32 reg_val;12 13	if (ring->ring_type == HCLGE_COMM_TYPE_CSQ) {14		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,15				     lower_32_bits(dma));16		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,17				     upper_32_bits(dma));18		reg_val = hclge_comm_read_dev(hw, HCLGE_COMM_NIC_CSQ_DEPTH_REG);19		reg_val &= HCLGE_COMM_NIC_SW_RST_RDY;20		reg_val |= ring->desc_num >> HCLGE_COMM_NIC_CMQ_DESC_NUM_S;21		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_DEPTH_REG, reg_val);22		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_HEAD_REG, 0);23		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_TAIL_REG, 0);24	} else {25		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,26				     lower_32_bits(dma));27		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,28				     upper_32_bits(dma));29		reg_val = ring->desc_num >> HCLGE_COMM_NIC_CMQ_DESC_NUM_S;30		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_DEPTH_REG, reg_val);31		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_HEAD_REG, 0);32		hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_TAIL_REG, 0);33	}34}35 36void hclge_comm_cmd_init_regs(struct hclge_comm_hw *hw)37{38	hclge_comm_cmd_config_regs(hw, &hw->cmq.csq);39	hclge_comm_cmd_config_regs(hw, &hw->cmq.crq);40}41 42void hclge_comm_cmd_reuse_desc(struct hclge_desc *desc, bool is_read)43{44	desc->flag = cpu_to_le16(HCLGE_COMM_CMD_FLAG_NO_INTR |45				 HCLGE_COMM_CMD_FLAG_IN);46	if (is_read)47		desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_WR);48	else49		desc->flag &= cpu_to_le16(~HCLGE_COMM_CMD_FLAG_WR);50}51EXPORT_SYMBOL_GPL(hclge_comm_cmd_reuse_desc);52 53static void hclge_comm_set_default_capability(struct hnae3_ae_dev *ae_dev,54					      bool is_pf)55{56	set_bit(HNAE3_DEV_SUPPORT_GRO_B, ae_dev->caps);57	if (is_pf) {58		set_bit(HNAE3_DEV_SUPPORT_FD_B, ae_dev->caps);59		set_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps);60		set_bit(HNAE3_DEV_SUPPORT_PAUSE_B, ae_dev->caps);61	}62}63 64void hclge_comm_cmd_setup_basic_desc(struct hclge_desc *desc,65				     enum hclge_opcode_type opcode,66				     bool is_read)67{68	memset((void *)desc, 0, sizeof(struct hclge_desc));69	desc->opcode = cpu_to_le16(opcode);70	desc->flag = cpu_to_le16(HCLGE_COMM_CMD_FLAG_NO_INTR |71				 HCLGE_COMM_CMD_FLAG_IN);72 73	if (is_read)74		desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_WR);75}76EXPORT_SYMBOL_GPL(hclge_comm_cmd_setup_basic_desc);77 78int hclge_comm_firmware_compat_config(struct hnae3_ae_dev *ae_dev,79				      struct hclge_comm_hw *hw, bool en)80{81	struct hclge_comm_firmware_compat_cmd *req;82	struct hclge_desc desc;83	u32 compat = 0;84 85	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_IMP_COMPAT_CFG, false);86 87	if (en) {88		req = (struct hclge_comm_firmware_compat_cmd *)desc.data;89 90		hnae3_set_bit(compat, HCLGE_COMM_LINK_EVENT_REPORT_EN_B, 1);91		hnae3_set_bit(compat, HCLGE_COMM_NCSI_ERROR_REPORT_EN_B, 1);92		if (hclge_comm_dev_phy_imp_supported(ae_dev))93			hnae3_set_bit(compat, HCLGE_COMM_PHY_IMP_EN_B, 1);94		hnae3_set_bit(compat, HCLGE_COMM_MAC_STATS_EXT_EN_B, 1);95		hnae3_set_bit(compat, HCLGE_COMM_SYNC_RX_RING_HEAD_EN_B, 1);96		hnae3_set_bit(compat, HCLGE_COMM_LLRS_FEC_EN_B, 1);97 98		req->compat = cpu_to_le32(compat);99	}100 101	return hclge_comm_cmd_send(hw, &desc, 1);102}103 104void hclge_comm_free_cmd_desc(struct hclge_comm_cmq_ring *ring)105{106	int size  = ring->desc_num * sizeof(struct hclge_desc);107 108	if (!ring->desc)109		return;110 111	dma_free_coherent(&ring->pdev->dev, size,112			  ring->desc, ring->desc_dma_addr);113	ring->desc = NULL;114}115 116static int hclge_comm_alloc_cmd_desc(struct hclge_comm_cmq_ring *ring)117{118	int size  = ring->desc_num * sizeof(struct hclge_desc);119 120	ring->desc = dma_alloc_coherent(&ring->pdev->dev,121					size, &ring->desc_dma_addr, GFP_KERNEL);122	if (!ring->desc)123		return -ENOMEM;124 125	return 0;126}127 128static __le32 hclge_comm_build_api_caps(void)129{130	u32 api_caps = 0;131 132	hnae3_set_bit(api_caps, HCLGE_COMM_API_CAP_FLEX_RSS_TBL_B, 1);133 134	return cpu_to_le32(api_caps);135}136 137static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = {138	{HCLGE_COMM_CAP_UDP_GSO_B, HNAE3_DEV_SUPPORT_UDP_GSO_B},139	{HCLGE_COMM_CAP_PTP_B, HNAE3_DEV_SUPPORT_PTP_B},140	{HCLGE_COMM_CAP_INT_QL_B, HNAE3_DEV_SUPPORT_INT_QL_B},141	{HCLGE_COMM_CAP_TQP_TXRX_INDEP_B, HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B},142	{HCLGE_COMM_CAP_HW_TX_CSUM_B, HNAE3_DEV_SUPPORT_HW_TX_CSUM_B},143	{HCLGE_COMM_CAP_UDP_TUNNEL_CSUM_B, HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B},144	{HCLGE_COMM_CAP_FD_FORWARD_TC_B, HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B},145	{HCLGE_COMM_CAP_FEC_B, HNAE3_DEV_SUPPORT_FEC_B},146	{HCLGE_COMM_CAP_PAUSE_B, HNAE3_DEV_SUPPORT_PAUSE_B},147	{HCLGE_COMM_CAP_PHY_IMP_B, HNAE3_DEV_SUPPORT_PHY_IMP_B},148	{HCLGE_COMM_CAP_QB_B, HNAE3_DEV_SUPPORT_QB_B},149	{HCLGE_COMM_CAP_TX_PUSH_B, HNAE3_DEV_SUPPORT_TX_PUSH_B},150	{HCLGE_COMM_CAP_RAS_IMP_B, HNAE3_DEV_SUPPORT_RAS_IMP_B},151	{HCLGE_COMM_CAP_RXD_ADV_LAYOUT_B, HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B},152	{HCLGE_COMM_CAP_PORT_VLAN_BYPASS_B,153	 HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B},154	{HCLGE_COMM_CAP_PORT_VLAN_BYPASS_B, HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B},155	{HCLGE_COMM_CAP_CQ_B, HNAE3_DEV_SUPPORT_CQ_B},156	{HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B},157	{HCLGE_COMM_CAP_FD_B, HNAE3_DEV_SUPPORT_FD_B},158	{HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B},159	{HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B},160	{HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B},161	{HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B},162	{HCLGE_COMM_CAP_VF_FAULT_B, HNAE3_DEV_SUPPORT_VF_FAULT_B},163	{HCLGE_COMM_CAP_ERR_MOD_GEN_REG_B, HNAE3_DEV_SUPPORT_ERR_MOD_GEN_REG_B},164};165 166static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = {167	{HCLGE_COMM_CAP_UDP_GSO_B, HNAE3_DEV_SUPPORT_UDP_GSO_B},168	{HCLGE_COMM_CAP_INT_QL_B, HNAE3_DEV_SUPPORT_INT_QL_B},169	{HCLGE_COMM_CAP_TQP_TXRX_INDEP_B, HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B},170	{HCLGE_COMM_CAP_HW_TX_CSUM_B, HNAE3_DEV_SUPPORT_HW_TX_CSUM_B},171	{HCLGE_COMM_CAP_UDP_TUNNEL_CSUM_B, HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B},172	{HCLGE_COMM_CAP_QB_B, HNAE3_DEV_SUPPORT_QB_B},173	{HCLGE_COMM_CAP_TX_PUSH_B, HNAE3_DEV_SUPPORT_TX_PUSH_B},174	{HCLGE_COMM_CAP_RXD_ADV_LAYOUT_B, HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B},175	{HCLGE_COMM_CAP_CQ_B, HNAE3_DEV_SUPPORT_CQ_B},176	{HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B},177};178 179static void180hclge_comm_capability_to_bitmap(unsigned long *bitmap, __le32 *caps)181{182	const unsigned int words = HCLGE_COMM_QUERY_CAP_LENGTH;183	u32 val[HCLGE_COMM_QUERY_CAP_LENGTH];184	unsigned int i;185 186	for (i = 0; i < words; i++)187		val[i] = __le32_to_cpu(caps[i]);188 189	bitmap_from_arr32(bitmap, val,190			  HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32));191}192 193static void194hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf,195			    struct hclge_comm_query_version_cmd *cmd)196{197	const struct hclge_comm_caps_bit_map *caps_map =198				is_pf ? hclge_pf_cmd_caps : hclge_vf_cmd_caps;199	u32 size = is_pf ? ARRAY_SIZE(hclge_pf_cmd_caps) :200				ARRAY_SIZE(hclge_vf_cmd_caps);201	DECLARE_BITMAP(caps, HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32));202	u32 i;203 204	hclge_comm_capability_to_bitmap(caps, cmd->caps);205	for (i = 0; i < size; i++)206		if (test_bit(caps_map[i].imp_bit, caps))207			set_bit(caps_map[i].local_bit, ae_dev->caps);208}209 210int hclge_comm_alloc_cmd_queue(struct hclge_comm_hw *hw, int ring_type)211{212	struct hclge_comm_cmq_ring *ring =213		(ring_type == HCLGE_COMM_TYPE_CSQ) ? &hw->cmq.csq :214						     &hw->cmq.crq;215	int ret;216 217	ring->ring_type = ring_type;218 219	ret = hclge_comm_alloc_cmd_desc(ring);220	if (ret)221		dev_err(&ring->pdev->dev, "descriptor %s alloc error %d\n",222			(ring_type == HCLGE_COMM_TYPE_CSQ) ? "CSQ" : "CRQ",223			ret);224 225	return ret;226}227 228int hclge_comm_cmd_query_version_and_capability(struct hnae3_ae_dev *ae_dev,229						struct hclge_comm_hw *hw,230						u32 *fw_version, bool is_pf)231{232	struct hclge_comm_query_version_cmd *resp;233	struct hclge_desc desc;234	int ret;235 236	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_FW_VER, 1);237	resp = (struct hclge_comm_query_version_cmd *)desc.data;238	resp->api_caps = hclge_comm_build_api_caps();239 240	ret = hclge_comm_cmd_send(hw, &desc, 1);241	if (ret)242		return ret;243 244	*fw_version = le32_to_cpu(resp->firmware);245 246	ae_dev->dev_version = le32_to_cpu(resp->hardware) <<247					 HNAE3_PCI_REVISION_BIT_SIZE;248	ae_dev->dev_version |= ae_dev->pdev->revision;249 250	if (ae_dev->dev_version == HNAE3_DEVICE_VERSION_V2) {251		hclge_comm_set_default_capability(ae_dev, is_pf);252		return 0;253	}254 255	hclge_comm_parse_capability(ae_dev, is_pf, resp);256 257	return ret;258}259 260static const u16 spec_opcode[] = { HCLGE_OPC_STATS_64_BIT,261				   HCLGE_OPC_STATS_32_BIT,262				   HCLGE_OPC_STATS_MAC,263				   HCLGE_OPC_STATS_MAC_ALL,264				   HCLGE_OPC_QUERY_32_BIT_REG,265				   HCLGE_OPC_QUERY_64_BIT_REG,266				   HCLGE_QUERY_CLEAR_MPF_RAS_INT,267				   HCLGE_QUERY_CLEAR_PF_RAS_INT,268				   HCLGE_QUERY_CLEAR_ALL_MPF_MSIX_INT,269				   HCLGE_QUERY_CLEAR_ALL_PF_MSIX_INT,270				   HCLGE_QUERY_ALL_ERR_INFO };271 272static bool hclge_comm_is_special_opcode(u16 opcode)273{274	/* these commands have several descriptors,275	 * and use the first one to save opcode and return value276	 */277	u32 i;278 279	for (i = 0; i < ARRAY_SIZE(spec_opcode); i++)280		if (spec_opcode[i] == opcode)281			return true;282 283	return false;284}285 286static int hclge_comm_ring_space(struct hclge_comm_cmq_ring *ring)287{288	int ntc = ring->next_to_clean;289	int ntu = ring->next_to_use;290	int used = (ntu - ntc + ring->desc_num) % ring->desc_num;291 292	return ring->desc_num - used - 1;293}294 295static void hclge_comm_cmd_copy_desc(struct hclge_comm_hw *hw,296				     struct hclge_desc *desc, int num)297{298	struct hclge_desc *desc_to_use;299	int handle = 0;300 301	while (handle < num) {302		desc_to_use = &hw->cmq.csq.desc[hw->cmq.csq.next_to_use];303		*desc_to_use = desc[handle];304		(hw->cmq.csq.next_to_use)++;305		if (hw->cmq.csq.next_to_use >= hw->cmq.csq.desc_num)306			hw->cmq.csq.next_to_use = 0;307		handle++;308	}309}310 311static int hclge_comm_is_valid_csq_clean_head(struct hclge_comm_cmq_ring *ring,312					      int head)313{314	int ntc = ring->next_to_clean;315	int ntu = ring->next_to_use;316 317	if (ntu > ntc)318		return head >= ntc && head <= ntu;319 320	return head >= ntc || head <= ntu;321}322 323static int hclge_comm_cmd_csq_clean(struct hclge_comm_hw *hw)324{325	struct hclge_comm_cmq_ring *csq = &hw->cmq.csq;326	int clean;327	u32 head;328 329	head = hclge_comm_read_dev(hw, HCLGE_COMM_NIC_CSQ_HEAD_REG);330	rmb(); /* Make sure head is ready before touch any data */331 332	if (!hclge_comm_is_valid_csq_clean_head(csq, head)) {333		dev_warn(&hw->cmq.csq.pdev->dev, "wrong cmd head (%u, %d-%d)\n",334			 head, csq->next_to_use, csq->next_to_clean);335		dev_warn(&hw->cmq.csq.pdev->dev,336			 "Disabling any further commands to IMP firmware\n");337		set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state);338		dev_warn(&hw->cmq.csq.pdev->dev,339			 "IMP firmware watchdog reset soon expected!\n");340		return -EIO;341	}342 343	clean = (head - csq->next_to_clean + csq->desc_num) % csq->desc_num;344	csq->next_to_clean = head;345	return clean;346}347 348static int hclge_comm_cmd_csq_done(struct hclge_comm_hw *hw)349{350	u32 head = hclge_comm_read_dev(hw, HCLGE_COMM_NIC_CSQ_HEAD_REG);351	return head == hw->cmq.csq.next_to_use;352}353 354static u32 hclge_get_cmdq_tx_timeout(u16 opcode, u32 tx_timeout)355{356	static const struct hclge_cmdq_tx_timeout_map cmdq_tx_timeout_map[] = {357		{HCLGE_OPC_CFG_RST_TRIGGER, HCLGE_COMM_CMDQ_CFG_RST_TIMEOUT},358	};359	u32 i;360 361	for (i = 0; i < ARRAY_SIZE(cmdq_tx_timeout_map); i++)362		if (cmdq_tx_timeout_map[i].opcode == opcode)363			return cmdq_tx_timeout_map[i].tx_timeout;364 365	return tx_timeout;366}367 368static void hclge_comm_wait_for_resp(struct hclge_comm_hw *hw, u16 opcode,369				     bool *is_completed)370{371	u32 cmdq_tx_timeout = hclge_get_cmdq_tx_timeout(opcode,372							hw->cmq.tx_timeout);373	u32 timeout = 0;374 375	do {376		if (hclge_comm_cmd_csq_done(hw)) {377			*is_completed = true;378			break;379		}380		udelay(1);381		timeout++;382	} while (timeout < cmdq_tx_timeout);383}384 385static int hclge_comm_cmd_convert_err_code(u16 desc_ret)386{387	struct hclge_comm_errcode hclge_comm_cmd_errcode[] = {388		{ HCLGE_COMM_CMD_EXEC_SUCCESS, 0 },389		{ HCLGE_COMM_CMD_NO_AUTH, -EPERM },390		{ HCLGE_COMM_CMD_NOT_SUPPORTED, -EOPNOTSUPP },391		{ HCLGE_COMM_CMD_QUEUE_FULL, -EXFULL },392		{ HCLGE_COMM_CMD_NEXT_ERR, -ENOSR },393		{ HCLGE_COMM_CMD_UNEXE_ERR, -ENOTBLK },394		{ HCLGE_COMM_CMD_PARA_ERR, -EINVAL },395		{ HCLGE_COMM_CMD_RESULT_ERR, -ERANGE },396		{ HCLGE_COMM_CMD_TIMEOUT, -ETIME },397		{ HCLGE_COMM_CMD_HILINK_ERR, -ENOLINK },398		{ HCLGE_COMM_CMD_QUEUE_ILLEGAL, -ENXIO },399		{ HCLGE_COMM_CMD_INVALID, -EBADR },400	};401	u32 errcode_count = ARRAY_SIZE(hclge_comm_cmd_errcode);402	u32 i;403 404	for (i = 0; i < errcode_count; i++)405		if (hclge_comm_cmd_errcode[i].imp_errcode == desc_ret)406			return hclge_comm_cmd_errcode[i].common_errno;407 408	return -EIO;409}410 411static int hclge_comm_cmd_check_retval(struct hclge_comm_hw *hw,412				       struct hclge_desc *desc, int num,413				       int ntc)414{415	u16 opcode, desc_ret;416	int handle;417 418	opcode = le16_to_cpu(desc[0].opcode);419	for (handle = 0; handle < num; handle++) {420		desc[handle] = hw->cmq.csq.desc[ntc];421		ntc++;422		if (ntc >= hw->cmq.csq.desc_num)423			ntc = 0;424	}425	if (likely(!hclge_comm_is_special_opcode(opcode)))426		desc_ret = le16_to_cpu(desc[num - 1].retval);427	else428		desc_ret = le16_to_cpu(desc[0].retval);429 430	hw->cmq.last_status = desc_ret;431 432	return hclge_comm_cmd_convert_err_code(desc_ret);433}434 435static int hclge_comm_cmd_check_result(struct hclge_comm_hw *hw,436				       struct hclge_desc *desc,437				       int num, int ntc)438{439	bool is_completed = false;440	int handle, ret;441 442	/* If the command is sync, wait for the firmware to write back,443	 * if multi descriptors to be sent, use the first one to check444	 */445	if (HCLGE_COMM_SEND_SYNC(le16_to_cpu(desc->flag)))446		hclge_comm_wait_for_resp(hw, le16_to_cpu(desc->opcode),447					 &is_completed);448 449	if (!is_completed)450		ret = -EBADE;451	else452		ret = hclge_comm_cmd_check_retval(hw, desc, num, ntc);453 454	/* Clean the command send queue */455	handle = hclge_comm_cmd_csq_clean(hw);456	if (handle < 0)457		ret = handle;458	else if (handle != num)459		dev_warn(&hw->cmq.csq.pdev->dev,460			 "cleaned %d, need to clean %d\n", handle, num);461	return ret;462}463 464/**465 * hclge_comm_cmd_send - send command to command queue466 * @hw: pointer to the hw struct467 * @desc: prefilled descriptor for describing the command468 * @num : the number of descriptors to be sent469 *470 * This is the main send command for command queue, it471 * sends the queue, cleans the queue, etc472 **/473int hclge_comm_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc,474			int num)475{476	bool is_special = hclge_comm_is_special_opcode(le16_to_cpu(desc->opcode));477	struct hclge_comm_cmq_ring *csq = &hw->cmq.csq;478	int ret;479	int ntc;480 481	if (hw->cmq.ops.trace_cmd_send)482		hw->cmq.ops.trace_cmd_send(hw, desc, num, is_special);483 484	spin_lock_bh(&hw->cmq.csq.lock);485 486	if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state)) {487		spin_unlock_bh(&hw->cmq.csq.lock);488		return -EBUSY;489	}490 491	if (num > hclge_comm_ring_space(&hw->cmq.csq)) {492		/* If CMDQ ring is full, SW HEAD and HW HEAD may be different,493		 * need update the SW HEAD pointer csq->next_to_clean494		 */495		csq->next_to_clean =496			hclge_comm_read_dev(hw, HCLGE_COMM_NIC_CSQ_HEAD_REG);497		spin_unlock_bh(&hw->cmq.csq.lock);498		return -EBUSY;499	}500 501	/**502	 * Record the location of desc in the ring for this time503	 * which will be use for hardware to write back504	 */505	ntc = hw->cmq.csq.next_to_use;506 507	hclge_comm_cmd_copy_desc(hw, desc, num);508 509	/* Write to hardware */510	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_TAIL_REG,511			     hw->cmq.csq.next_to_use);512 513	ret = hclge_comm_cmd_check_result(hw, desc, num, ntc);514 515	spin_unlock_bh(&hw->cmq.csq.lock);516 517	if (hw->cmq.ops.trace_cmd_get)518		hw->cmq.ops.trace_cmd_get(hw, desc, num, is_special);519 520	return ret;521}522EXPORT_SYMBOL_GPL(hclge_comm_cmd_send);523 524static void hclge_comm_cmd_uninit_regs(struct hclge_comm_hw *hw)525{526	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG, 0);527	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG, 0);528	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_DEPTH_REG, 0);529	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_HEAD_REG, 0);530	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CSQ_TAIL_REG, 0);531	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG, 0);532	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG, 0);533	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_DEPTH_REG, 0);534	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_HEAD_REG, 0);535	hclge_comm_write_dev(hw, HCLGE_COMM_NIC_CRQ_TAIL_REG, 0);536}537 538void hclge_comm_cmd_uninit(struct hnae3_ae_dev *ae_dev,539			   struct hclge_comm_hw *hw)540{541	struct hclge_comm_cmq *cmdq = &hw->cmq;542 543	hclge_comm_firmware_compat_config(ae_dev, hw, false);544	set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state);545 546	/* wait to ensure that the firmware completes the possible left547	 * over commands.548	 */549	msleep(HCLGE_COMM_CMDQ_CLEAR_WAIT_TIME);550	spin_lock_bh(&cmdq->csq.lock);551	spin_lock(&cmdq->crq.lock);552	hclge_comm_cmd_uninit_regs(hw);553	spin_unlock(&cmdq->crq.lock);554	spin_unlock_bh(&cmdq->csq.lock);555 556	hclge_comm_free_cmd_desc(&cmdq->csq);557	hclge_comm_free_cmd_desc(&cmdq->crq);558}559EXPORT_SYMBOL_GPL(hclge_comm_cmd_uninit);560 561int hclge_comm_cmd_queue_init(struct pci_dev *pdev, struct hclge_comm_hw *hw)562{563	struct hclge_comm_cmq *cmdq = &hw->cmq;564	int ret;565 566	/* Setup the lock for command queue */567	spin_lock_init(&cmdq->csq.lock);568	spin_lock_init(&cmdq->crq.lock);569 570	cmdq->csq.pdev = pdev;571	cmdq->crq.pdev = pdev;572 573	/* Setup the queue entries for use cmd queue */574	cmdq->csq.desc_num = HCLGE_COMM_NIC_CMQ_DESC_NUM;575	cmdq->crq.desc_num = HCLGE_COMM_NIC_CMQ_DESC_NUM;576 577	/* Setup Tx write back timeout */578	cmdq->tx_timeout = HCLGE_COMM_CMDQ_TX_TIMEOUT_DEFAULT;579 580	/* Setup queue rings */581	ret = hclge_comm_alloc_cmd_queue(hw, HCLGE_COMM_TYPE_CSQ);582	if (ret) {583		dev_err(&pdev->dev, "CSQ ring setup error %d\n", ret);584		return ret;585	}586 587	ret = hclge_comm_alloc_cmd_queue(hw, HCLGE_COMM_TYPE_CRQ);588	if (ret) {589		dev_err(&pdev->dev, "CRQ ring setup error %d\n", ret);590		goto err_csq;591	}592 593	return 0;594err_csq:595	hclge_comm_free_cmd_desc(&hw->cmq.csq);596	return ret;597}598EXPORT_SYMBOL_GPL(hclge_comm_cmd_queue_init);599 600void hclge_comm_cmd_init_ops(struct hclge_comm_hw *hw,601			     const struct hclge_comm_cmq_ops *ops)602{603	struct hclge_comm_cmq *cmdq = &hw->cmq;604 605	if (ops) {606		cmdq->ops.trace_cmd_send = ops->trace_cmd_send;607		cmdq->ops.trace_cmd_get = ops->trace_cmd_get;608	}609}610EXPORT_SYMBOL_GPL(hclge_comm_cmd_init_ops);611 612int hclge_comm_cmd_init(struct hnae3_ae_dev *ae_dev, struct hclge_comm_hw *hw,613			u32 *fw_version, bool is_pf,614			unsigned long reset_pending)615{616	struct hclge_comm_cmq *cmdq = &hw->cmq;617	int ret;618 619	spin_lock_bh(&cmdq->csq.lock);620	spin_lock(&cmdq->crq.lock);621 622	cmdq->csq.next_to_clean = 0;623	cmdq->csq.next_to_use = 0;624	cmdq->crq.next_to_clean = 0;625	cmdq->crq.next_to_use = 0;626 627	hclge_comm_cmd_init_regs(hw);628 629	spin_unlock(&cmdq->crq.lock);630	spin_unlock_bh(&cmdq->csq.lock);631 632	clear_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state);633 634	/* Check if there is new reset pending, because the higher level635	 * reset may happen when lower level reset is being processed.636	 */637	if (reset_pending) {638		ret = -EBUSY;639		goto err_cmd_init;640	}641 642	/* get version and device capabilities */643	ret = hclge_comm_cmd_query_version_and_capability(ae_dev, hw,644							  fw_version, is_pf);645	if (ret) {646		dev_err(&ae_dev->pdev->dev,647			"failed to query version and capabilities, ret = %d\n",648			ret);649		goto err_cmd_init;650	}651 652	dev_info(&ae_dev->pdev->dev,653		 "The firmware version is %lu.%lu.%lu.%lu\n",654		 hnae3_get_field(*fw_version, HNAE3_FW_VERSION_BYTE3_MASK,655				 HNAE3_FW_VERSION_BYTE3_SHIFT),656		 hnae3_get_field(*fw_version, HNAE3_FW_VERSION_BYTE2_MASK,657				 HNAE3_FW_VERSION_BYTE2_SHIFT),658		 hnae3_get_field(*fw_version, HNAE3_FW_VERSION_BYTE1_MASK,659				 HNAE3_FW_VERSION_BYTE1_SHIFT),660		 hnae3_get_field(*fw_version, HNAE3_FW_VERSION_BYTE0_MASK,661				 HNAE3_FW_VERSION_BYTE0_SHIFT));662 663	if (!is_pf && ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3)664		return 0;665 666	/* ask the firmware to enable some features, driver can work without667	 * it.668	 */669	ret = hclge_comm_firmware_compat_config(ae_dev, hw, true);670	if (ret)671		dev_warn(&ae_dev->pdev->dev,672			 "Firmware compatible features not enabled(%d).\n",673			 ret);674	return 0;675 676err_cmd_init:677	set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state);678 679	return ret;680}681EXPORT_SYMBOL_GPL(hclge_comm_cmd_init);682 683MODULE_LICENSE("GPL");684MODULE_DESCRIPTION("HNS3: Hisilicon Ethernet PF/VF Common Library");685MODULE_AUTHOR("Huawei Tech. Co., Ltd.");686