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