Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018-2021 HiSilicon Limited.
3 : : */
4 : :
5 : : #include <ethdev_pci.h>
6 : : #include <rte_io.h>
7 : :
8 : : #include "hns3_common.h"
9 : : #include "hns3_regs.h"
10 : : #include "hns3_intr.h"
11 : : #include "hns3_logs.h"
12 : :
13 : : static int
14 : : hns3_ring_space(struct hns3_cmq_ring *ring)
15 : : {
16 : 0 : int ntu = ring->next_to_use;
17 : 0 : int ntc = ring->next_to_clean;
18 : 0 : int used = (ntu - ntc + ring->desc_num) % ring->desc_num;
19 : :
20 : 0 : return ring->desc_num - used - 1;
21 : : }
22 : :
23 : : static bool
24 : : is_valid_csq_clean_head(struct hns3_cmq_ring *ring, int head)
25 : : {
26 : 0 : int ntu = ring->next_to_use;
27 : 0 : int ntc = ring->next_to_clean;
28 : :
29 : 0 : if (ntu > ntc)
30 : 0 : return head >= ntc && head <= ntu;
31 : :
32 : 0 : return head >= ntc || head <= ntu;
33 : : }
34 : :
35 : : /*
36 : : * hns3_allocate_dma_mem - Specific memory alloc for command function.
37 : : * Malloc a memzone, which is a contiguous portion of physical memory identified
38 : : * by a name.
39 : : * @ring: pointer to the ring structure
40 : : * @size: size of memory requested
41 : : * @alignment: what to align the allocation to
42 : : */
43 : : static int
44 : 0 : hns3_allocate_dma_mem(struct hns3_hw *hw, struct hns3_cmq_ring *ring,
45 : : uint64_t size, uint32_t alignment)
46 : : {
47 : : static RTE_ATOMIC(uint64_t) hns3_dma_memzone_id;
48 : : const struct rte_memzone *mz = NULL;
49 : : char z_name[RTE_MEMZONE_NAMESIZE];
50 : :
51 : 0 : snprintf(z_name, sizeof(z_name), "hns3_dma_%" PRIu64,
52 : : rte_atomic_fetch_add_explicit(&hns3_dma_memzone_id, 1, rte_memory_order_relaxed));
53 : 0 : mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY,
54 : : RTE_MEMZONE_IOVA_CONTIG, alignment,
55 : : RTE_PGSIZE_2M);
56 [ # # ]: 0 : if (mz == NULL)
57 : : return -ENOMEM;
58 : :
59 : 0 : ring->buf_size = size;
60 : 0 : ring->desc = mz->addr;
61 : 0 : ring->desc_dma_addr = mz->iova;
62 : 0 : ring->zone = (const void *)mz;
63 : 0 : hns3_dbg(hw, "cmd ring memzone name: %s", mz->name);
64 : :
65 : 0 : return 0;
66 : : }
67 : :
68 : : static void
69 : : hns3_free_dma_mem(struct hns3_cmq_ring *ring)
70 : : {
71 : 0 : rte_memzone_free((const struct rte_memzone *)ring->zone);
72 : 0 : ring->buf_size = 0;
73 : 0 : ring->desc = NULL;
74 : 0 : ring->desc_dma_addr = 0;
75 : 0 : ring->zone = NULL;
76 : 0 : }
77 : :
78 : : static int
79 : 0 : hns3_alloc_cmd_desc(struct hns3_hw *hw, struct hns3_cmq_ring *ring)
80 : : {
81 : 0 : int size = ring->desc_num * sizeof(struct hns3_cmd_desc);
82 : :
83 [ # # ]: 0 : if (hns3_allocate_dma_mem(hw, ring, size, HNS3_CMD_DESC_ALIGNMENT)) {
84 : 0 : hns3_err(hw, "allocate dma mem failed");
85 : 0 : return -ENOMEM;
86 : : }
87 : :
88 : : return 0;
89 : : }
90 : :
91 : : static void
92 : : hns3_free_cmd_desc(__rte_unused struct hns3_hw *hw, struct hns3_cmq_ring *ring)
93 : : {
94 [ # # ]: 0 : if (ring->desc)
95 : : hns3_free_dma_mem(ring);
96 : : }
97 : :
98 : : static int
99 : 0 : hns3_alloc_cmd_queue(struct hns3_hw *hw, int ring_type)
100 : : {
101 : : struct hns3_cmq_ring *ring =
102 [ # # ]: 0 : (ring_type == HNS3_TYPE_CSQ) ? &hw->cmq.csq : &hw->cmq.crq;
103 : : int ret;
104 : :
105 : 0 : ring->ring_type = ring_type;
106 : 0 : ring->hw = hw;
107 : :
108 : 0 : ret = hns3_alloc_cmd_desc(hw, ring);
109 [ # # ]: 0 : if (ret)
110 [ # # ]: 0 : hns3_err(hw, "descriptor %s alloc error %d",
111 : : (ring_type == HNS3_TYPE_CSQ) ? "CSQ" : "CRQ", ret);
112 : :
113 : 0 : return ret;
114 : : }
115 : :
116 : : void
117 : 0 : hns3_cmd_reuse_desc(struct hns3_cmd_desc *desc, bool is_read)
118 : : {
119 : 0 : desc->flag = rte_cpu_to_le_16(HNS3_CMD_FLAG_NO_INTR | HNS3_CMD_FLAG_IN);
120 [ # # ]: 0 : if (is_read)
121 : 0 : desc->flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_WR);
122 : : else
123 : : desc->flag &= rte_cpu_to_le_16(~HNS3_CMD_FLAG_WR);
124 : 0 : }
125 : :
126 : : void
127 [ # # ]: 0 : hns3_cmd_setup_basic_desc(struct hns3_cmd_desc *desc,
128 : : enum hns3_opcode_type opcode, bool is_read)
129 : : {
130 : : memset((void *)desc, 0, sizeof(struct hns3_cmd_desc));
131 : 0 : desc->opcode = rte_cpu_to_le_16(opcode);
132 : 0 : desc->flag = rte_cpu_to_le_16(HNS3_CMD_FLAG_NO_INTR | HNS3_CMD_FLAG_IN);
133 : :
134 [ # # ]: 0 : if (is_read)
135 : 0 : desc->flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_WR);
136 : 0 : }
137 : :
138 : : static void
139 : 0 : hns3_cmd_clear_regs(struct hns3_hw *hw)
140 : : {
141 : 0 : hns3_write_dev(hw, HNS3_CMDQ_TX_ADDR_L_REG, 0);
142 : 0 : hns3_write_dev(hw, HNS3_CMDQ_TX_ADDR_H_REG, 0);
143 : 0 : hns3_write_dev(hw, HNS3_CMDQ_TX_DEPTH_REG, 0);
144 : 0 : hns3_write_dev(hw, HNS3_CMDQ_TX_HEAD_REG, 0);
145 : 0 : hns3_write_dev(hw, HNS3_CMDQ_TX_TAIL_REG, 0);
146 : 0 : hns3_write_dev(hw, HNS3_CMDQ_RX_ADDR_L_REG, 0);
147 : 0 : hns3_write_dev(hw, HNS3_CMDQ_RX_ADDR_H_REG, 0);
148 : 0 : hns3_write_dev(hw, HNS3_CMDQ_RX_DEPTH_REG, 0);
149 : 0 : hns3_write_dev(hw, HNS3_CMDQ_RX_HEAD_REG, 0);
150 : 0 : hns3_write_dev(hw, HNS3_CMDQ_RX_TAIL_REG, 0);
151 : 0 : }
152 : :
153 : : static void
154 : 0 : hns3_cmd_config_regs(struct hns3_cmq_ring *ring)
155 : : {
156 : 0 : uint64_t dma = ring->desc_dma_addr;
157 : :
158 [ # # ]: 0 : if (ring->ring_type == HNS3_TYPE_CSQ) {
159 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_TX_ADDR_L_REG,
160 : : lower_32_bits(dma));
161 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_TX_ADDR_H_REG,
162 : : upper_32_bits(dma));
163 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_TX_DEPTH_REG,
164 : : ring->desc_num >> HNS3_NIC_CMQ_DESC_NUM_S |
165 : : HNS3_NIC_SW_RST_RDY);
166 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_TX_HEAD_REG, 0);
167 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_TX_TAIL_REG, 0);
168 : : } else {
169 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_RX_ADDR_L_REG,
170 : : lower_32_bits(dma));
171 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_RX_ADDR_H_REG,
172 : : upper_32_bits(dma));
173 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_RX_DEPTH_REG,
174 : : ring->desc_num >> HNS3_NIC_CMQ_DESC_NUM_S);
175 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_RX_HEAD_REG, 0);
176 : 0 : hns3_write_dev(ring->hw, HNS3_CMDQ_RX_TAIL_REG, 0);
177 : : }
178 : 0 : }
179 : :
180 : : static void
181 : : hns3_cmd_init_regs(struct hns3_hw *hw)
182 : : {
183 : 0 : hns3_cmd_config_regs(&hw->cmq.csq);
184 : 0 : hns3_cmd_config_regs(&hw->cmq.crq);
185 : : }
186 : :
187 : : static int
188 : 0 : hns3_cmd_csq_clean(struct hns3_hw *hw)
189 : : {
190 : : struct hns3_cmq_ring *csq = &hw->cmq.csq;
191 : : uint32_t head;
192 : : uint32_t addr;
193 : : int clean;
194 : :
195 : 0 : head = hns3_read_dev(hw, HNS3_CMDQ_TX_HEAD_REG);
196 : 0 : addr = hns3_read_dev(hw, HNS3_CMDQ_TX_ADDR_L_REG);
197 [ # # # # : 0 : if (!is_valid_csq_clean_head(csq, head) || addr == 0) {
# # ]
198 : 0 : hns3_err(hw, "wrong cmd addr(%0x) head (%u, %u-%u)", addr, head,
199 : : csq->next_to_use, csq->next_to_clean);
200 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
201 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 1,
202 : : rte_memory_order_relaxed);
203 : 0 : hns3_schedule_delayed_reset(HNS3_DEV_HW_TO_ADAPTER(hw));
204 : : }
205 : :
206 : 0 : return -EIO;
207 : : }
208 : :
209 : 0 : clean = (head - csq->next_to_clean + csq->desc_num) % csq->desc_num;
210 : 0 : csq->next_to_clean = head;
211 : 0 : return clean;
212 : : }
213 : :
214 : : static int
215 : : hns3_cmd_csq_done(struct hns3_hw *hw)
216 : : {
217 : 0 : uint32_t head = hns3_read_dev(hw, HNS3_CMDQ_TX_HEAD_REG);
218 : :
219 : 0 : return head == hw->cmq.csq.next_to_use;
220 : : }
221 : :
222 : : static bool
223 : 0 : hns3_is_special_opcode(uint16_t opcode)
224 : : {
225 : : /*
226 : : * These commands have several descriptors,
227 : : * and use the first one to save opcode and return value.
228 : : */
229 : 0 : uint16_t spec_opcode[] = {HNS3_OPC_STATS_64_BIT,
230 : : HNS3_OPC_STATS_32_BIT,
231 : : HNS3_OPC_STATS_MAC,
232 : : HNS3_OPC_STATS_MAC_ALL,
233 : : HNS3_OPC_QUERY_32_BIT_REG,
234 : : HNS3_OPC_QUERY_64_BIT_REG,
235 : : HNS3_OPC_QUERY_CLEAR_MPF_RAS_INT,
236 : : HNS3_OPC_QUERY_CLEAR_PF_RAS_INT,
237 : : HNS3_OPC_QUERY_CLEAR_ALL_MPF_MSIX_INT,
238 : : HNS3_OPC_QUERY_CLEAR_ALL_PF_MSIX_INT,
239 : : HNS3_OPC_QUERY_ALL_ERR_INFO,};
240 : : uint32_t i;
241 : :
242 [ # # ]: 0 : for (i = 0; i < RTE_DIM(spec_opcode); i++)
243 [ # # ]: 0 : if (spec_opcode[i] == opcode)
244 : : return true;
245 : :
246 : : return false;
247 : : }
248 : :
249 : : static int
250 : : hns3_cmd_convert_err_code(uint16_t desc_ret)
251 : : {
252 : : static const struct {
253 : : uint16_t imp_errcode;
254 : : int linux_errcode;
255 : : } hns3_cmdq_status[] = {
256 : : {HNS3_CMD_EXEC_SUCCESS, 0},
257 : : {HNS3_CMD_NO_AUTH, -EPERM},
258 : : {HNS3_CMD_NOT_SUPPORTED, -EOPNOTSUPP},
259 : : {HNS3_CMD_QUEUE_FULL, -EXFULL},
260 : : {HNS3_CMD_NEXT_ERR, -ENOSR},
261 : : {HNS3_CMD_UNEXE_ERR, -ENOTBLK},
262 : : {HNS3_CMD_PARA_ERR, -EINVAL},
263 : : {HNS3_CMD_RESULT_ERR, -ERANGE},
264 : : {HNS3_CMD_TIMEOUT, -ETIME},
265 : : {HNS3_CMD_HILINK_ERR, -ENOLINK},
266 : : {HNS3_CMD_QUEUE_ILLEGAL, -ENXIO},
267 : : {HNS3_CMD_INVALID, -EBADR},
268 : : {HNS3_CMD_ROH_CHECK_FAIL, -EINVAL}
269 : : };
270 : :
271 : : uint32_t i;
272 : :
273 [ # # ]: 0 : for (i = 0; i < RTE_DIM(hns3_cmdq_status); i++)
274 [ # # ]: 0 : if (hns3_cmdq_status[i].imp_errcode == desc_ret)
275 : 0 : return hns3_cmdq_status[i].linux_errcode;
276 : :
277 : : return -EREMOTEIO;
278 : : }
279 : :
280 : : static int
281 : 0 : hns3_cmd_get_hardware_reply(struct hns3_hw *hw,
282 : : struct hns3_cmd_desc *desc, int num, int ntc)
283 : : {
284 : : uint16_t opcode, desc_ret;
285 : : int current_ntc = ntc;
286 : : int handle;
287 : :
288 : 0 : opcode = rte_le_to_cpu_16(desc[0].opcode);
289 [ # # ]: 0 : for (handle = 0; handle < num; handle++) {
290 : : /* Get the result of hardware write back */
291 : 0 : desc[handle] = hw->cmq.csq.desc[current_ntc];
292 : :
293 : 0 : current_ntc++;
294 [ # # ]: 0 : if (current_ntc == hw->cmq.csq.desc_num)
295 : : current_ntc = 0;
296 : : }
297 : :
298 [ # # ]: 0 : if (likely(!hns3_is_special_opcode(opcode)))
299 : 0 : desc_ret = rte_le_to_cpu_16(desc[num - 1].retval);
300 : : else
301 : 0 : desc_ret = rte_le_to_cpu_16(desc[0].retval);
302 : :
303 : 0 : hw->cmq.last_status = desc_ret;
304 : 0 : return hns3_cmd_convert_err_code(desc_ret);
305 : : }
306 : :
307 : : static uint32_t hns3_get_cmd_tx_timeout(uint16_t opcode)
308 : : {
309 : 0 : if (opcode == HNS3_OPC_CFG_RST_TRIGGER)
310 : 0 : return HNS3_COMQ_CFG_RST_TIMEOUT;
311 : :
312 : : return HNS3_CMDQ_TX_TIMEOUT_DEFAULT;
313 : : }
314 : :
315 [ # # ]: 0 : static int hns3_cmd_poll_reply(struct hns3_hw *hw, uint16_t opcode)
316 : : {
317 : : uint32_t cmdq_tx_timeout = hns3_get_cmd_tx_timeout(opcode);
318 : : struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
319 : : uint32_t timeout = 0;
320 : :
321 : : do {
322 [ # # ]: 0 : if (hns3_cmd_csq_done(hw))
323 : : return 0;
324 : :
325 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.disable_cmd, rte_memory_order_relaxed)) {
326 : 0 : hns3_err(hw,
327 : : "Don't wait for reply because of disable_cmd");
328 : 0 : return -EBUSY;
329 : : }
330 : :
331 [ # # ]: 0 : if (is_reset_pending(hns)) {
332 : 0 : hns3_err(hw, "Don't wait for reply because of reset pending");
333 : 0 : return -EIO;
334 : : }
335 : :
336 : 0 : rte_delay_us(1);
337 : 0 : timeout++;
338 [ # # ]: 0 : } while (timeout < cmdq_tx_timeout);
339 : 0 : hns3_err(hw, "Wait for reply timeout");
340 : 0 : return -ETIME;
341 : : }
342 : :
343 : : /*
344 : : * hns3_cmd_send - send command to command queue
345 : : *
346 : : * @param hw
347 : : * pointer to the hw struct
348 : : * @param desc
349 : : * prefilled descriptor for describing the command
350 : : * @param num
351 : : * the number of descriptors to be sent
352 : : * @return
353 : : * - -EBUSY if detect device is in resetting
354 : : * - -EIO if detect cmd csq corrupted (due to reset) or
355 : : * there is reset pending
356 : : * - -ENOMEM/-ETIME/...(Non-Zero) if other error case
357 : : * - Zero if operation completed successfully
358 : : *
359 : : * Note -BUSY/-EIO only used in reset case
360 : : *
361 : : * Note this is the main send command for command queue, it
362 : : * sends the queue, cleans the queue, etc
363 : : */
364 : : int
365 : 0 : hns3_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, int num)
366 : : {
367 : : struct hns3_cmd_desc *desc_to_use;
368 : : int handle = 0;
369 : : int retval;
370 : : uint32_t ntc;
371 : :
372 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.disable_cmd, rte_memory_order_relaxed))
373 : : return -EBUSY;
374 : :
375 : 0 : rte_spinlock_lock(&hw->cmq.csq.lock);
376 : :
377 : : /* Clean the command send queue */
378 : 0 : retval = hns3_cmd_csq_clean(hw);
379 [ # # ]: 0 : if (retval < 0) {
380 : : rte_spinlock_unlock(&hw->cmq.csq.lock);
381 : 0 : return retval;
382 : : }
383 : :
384 [ # # ]: 0 : if (num > hns3_ring_space(&hw->cmq.csq)) {
385 : : rte_spinlock_unlock(&hw->cmq.csq.lock);
386 : 0 : return -ENOMEM;
387 : : }
388 : :
389 : : /*
390 : : * Record the location of desc in the ring for this time
391 : : * which will be use for hardware to write back
392 : : */
393 : : ntc = hw->cmq.csq.next_to_use;
394 : :
395 [ # # ]: 0 : while (handle < num) {
396 : 0 : desc_to_use = &hw->cmq.csq.desc[hw->cmq.csq.next_to_use];
397 : 0 : *desc_to_use = desc[handle];
398 : 0 : (hw->cmq.csq.next_to_use)++;
399 [ # # ]: 0 : if (hw->cmq.csq.next_to_use == hw->cmq.csq.desc_num)
400 : 0 : hw->cmq.csq.next_to_use = 0;
401 : 0 : handle++;
402 : : }
403 : :
404 : : /* Write to hardware */
405 : 0 : hns3_write_dev(hw, HNS3_CMDQ_TX_TAIL_REG, hw->cmq.csq.next_to_use);
406 : :
407 : : /*
408 : : * If the command is sync, wait for the firmware to write back,
409 : : * if multi descriptors to be sent, use the first one to check.
410 : : */
411 [ # # ]: 0 : if (HNS3_CMD_SEND_SYNC(rte_le_to_cpu_16(desc->flag))) {
412 : 0 : retval = hns3_cmd_poll_reply(hw, desc->opcode);
413 [ # # ]: 0 : if (!retval)
414 : 0 : retval = hns3_cmd_get_hardware_reply(hw, desc, num,
415 : : ntc);
416 : : }
417 : :
418 : : rte_spinlock_unlock(&hw->cmq.csq.lock);
419 : 0 : return retval;
420 : : }
421 : :
422 : : static const char *
423 : 0 : hns3_get_caps_name(uint32_t caps_id)
424 : : {
425 : : const struct {
426 : : enum HNS3_CAPS_BITS caps;
427 : : const char *name;
428 : 0 : } dev_caps[] = {
429 : : { HNS3_CAPS_FD_QUEUE_REGION_B, "fd_queue_region" },
430 : : { HNS3_CAPS_PTP_B, "ptp" },
431 : : { HNS3_CAPS_SIMPLE_BD_B, "simple_bd" },
432 : : { HNS3_CAPS_TX_PUSH_B, "tx_push" },
433 : : { HNS3_CAPS_PHY_IMP_B, "phy_imp" },
434 : : { HNS3_CAPS_TQP_TXRX_INDEP_B, "tqp_txrx_indep" },
435 : : { HNS3_CAPS_HW_PAD_B, "hw_pad" },
436 : : { HNS3_CAPS_STASH_B, "stash" },
437 : : { HNS3_CAPS_UDP_TUNNEL_CSUM_B, "udp_tunnel_csum" },
438 : : { HNS3_CAPS_RAS_IMP_B, "ras_imp" },
439 : : { HNS3_CAPS_RXD_ADV_LAYOUT_B, "rxd_adv_layout" },
440 : : { HNS3_CAPS_TM_B, "tm_capability" },
441 : : { HNS3_CAPS_FC_AUTO_B, "fc_autoneg" }
442 : : };
443 : : uint32_t i;
444 : :
445 [ # # ]: 0 : for (i = 0; i < RTE_DIM(dev_caps); i++) {
446 [ # # ]: 0 : if (dev_caps[i].caps == caps_id)
447 : 0 : return dev_caps[i].name;
448 : : }
449 : :
450 : : return "unknown";
451 : : }
452 : :
453 : : static void
454 : 0 : hns3_mask_capability(struct hns3_hw *hw,
455 : : struct hns3_query_version_cmd *cmd)
456 : : {
457 : : #define MAX_CAPS_BIT 64
458 : :
459 : : struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
460 : : uint64_t caps_org, caps_new, caps_masked;
461 : : uint32_t i;
462 : :
463 [ # # ]: 0 : if (hns->dev_caps_mask == 0)
464 : 0 : return;
465 : :
466 : : memcpy(&caps_org, &cmd->caps[0], sizeof(caps_org));
467 : : caps_org = rte_le_to_cpu_64(caps_org);
468 : 0 : caps_new = caps_org ^ (caps_org & hns->dev_caps_mask);
469 : 0 : caps_masked = caps_org ^ caps_new;
470 : : caps_new = rte_cpu_to_le_64(caps_new);
471 : 0 : memcpy(&cmd->caps[0], &caps_new, sizeof(caps_new));
472 : :
473 [ # # ]: 0 : for (i = 0; i < MAX_CAPS_BIT; i++) {
474 [ # # ]: 0 : if (!(caps_masked & BIT_ULL(i)))
475 : 0 : continue;
476 : 0 : hns3_info(hw, "mask capability: id-%u, name-%s.",
477 : : i, hns3_get_caps_name(i));
478 : : }
479 : : }
480 : :
481 : : static void
482 : 0 : hns3_parse_capability(struct hns3_hw *hw,
483 : : struct hns3_query_version_cmd *cmd)
484 : : {
485 : 0 : uint32_t caps = rte_le_to_cpu_32(cmd->caps[0]);
486 : :
487 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_FD_QUEUE_REGION_B))
488 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B,
489 : : 1);
490 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_PTP_B)) {
491 : : /*
492 : : * PTP depends on special packet type reported by hardware which
493 : : * enabled rxd advanced layout, so if the hardware doesn't
494 : : * support rxd advanced layout, driver should ignore the PTP
495 : : * capability.
496 : : */
497 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_RXD_ADV_LAYOUT_B))
498 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_PTP_B, 1);
499 : : else
500 : 0 : hns3_warn(hw, "ignore PTP capability due to lack of "
501 : : "rxd advanced layout capability.");
502 : : }
503 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_SIMPLE_BD_B))
504 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_SIMPLE_BD_B, 1);
505 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_TX_PUSH_B))
506 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TX_PUSH_B, 1);
507 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B))
508 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 1);
509 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_TQP_TXRX_INDEP_B))
510 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B, 1);
511 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_STASH_B))
512 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_STASH_B, 1);
513 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_RXD_ADV_LAYOUT_B))
514 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
515 : : 1);
516 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_UDP_TUNNEL_CSUM_B))
517 : 0 : hns3_set_bit(hw->capability,
518 : : HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, 1);
519 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_RAS_IMP_B))
520 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_RAS_IMP_B, 1);
521 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_TM_B))
522 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TM_B, 1);
523 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_FC_AUTO_B))
524 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_FC_AUTO_B, 1);
525 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3_CAPS_GRO_B))
526 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_GRO_B, 1);
527 : 0 : }
528 : :
529 : : static uint32_t
530 : : hns3_build_api_caps(void)
531 : : {
532 : : uint32_t api_caps = 0;
533 : :
534 : : hns3_set_bit(api_caps, HNS3_API_CAP_FLEX_RSS_TBL_B, 1);
535 : :
536 : : return rte_cpu_to_le_32(api_caps);
537 : : }
538 : :
539 : : static void
540 : 0 : hns3_set_dcb_capability(struct hns3_hw *hw)
541 : : {
542 : : struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
543 : : struct rte_pci_device *pci_dev;
544 : : struct rte_eth_dev *eth_dev;
545 : : uint16_t device_id;
546 : :
547 [ # # ]: 0 : if (hns->is_vf)
548 : : return;
549 : :
550 : 0 : eth_dev = &rte_eth_devices[hw->data->port_id];
551 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
552 : 0 : device_id = pci_dev->id.device_id;
553 : :
554 : 0 : if (device_id == HNS3_DEV_ID_25GE_RDMA ||
555 [ # # ]: 0 : device_id == HNS3_DEV_ID_50GE_RDMA ||
556 : 0 : device_id == HNS3_DEV_ID_100G_RDMA_MACSEC ||
557 [ # # ]: 0 : device_id == HNS3_DEV_ID_200G_RDMA)
558 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1);
559 : : }
560 : :
561 : : static void
562 : : hns3_set_default_capability(struct hns3_hw *hw)
563 : : {
564 : 0 : hns3_set_dcb_capability(hw);
565 : :
566 : : /*
567 : : * The firmware of the network engines with HIP08 do not report some
568 : : * capabilities, like GRO. Set default capabilities for it.
569 : : */
570 [ # # ]: 0 : if (hw->revision < PCI_REVISION_ID_HIP09_A)
571 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_GRO_B, 1);
572 : : }
573 : :
574 : : static int
575 : 0 : hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw)
576 : : {
577 : : struct hns3_query_version_cmd *resp;
578 : : struct hns3_cmd_desc desc;
579 : : int ret;
580 : :
581 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_FW_VER, 1);
582 : : resp = (struct hns3_query_version_cmd *)desc.data;
583 : 0 : resp->api_caps = hns3_build_api_caps();
584 : :
585 : : /* Initialize the cmd function */
586 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
587 [ # # ]: 0 : if (ret)
588 : : return ret;
589 : :
590 : 0 : hw->fw_version = rte_le_to_cpu_32(resp->firmware);
591 : :
592 : : hns3_set_default_capability(hw);
593 : :
594 : : /*
595 : : * Make sure mask the capability before parse capability because it
596 : : * may overwrite resp's data.
597 : : */
598 : 0 : hns3_mask_capability(hw, resp);
599 : 0 : hns3_parse_capability(hw, resp);
600 : :
601 : 0 : return 0;
602 : : }
603 : :
604 : : int
605 : 0 : hns3_cmd_init_queue(struct hns3_hw *hw)
606 : : {
607 : : int ret;
608 : :
609 : : /* Setup the lock for command queue */
610 : : rte_spinlock_init(&hw->cmq.csq.lock);
611 : : rte_spinlock_init(&hw->cmq.crq.lock);
612 : :
613 : : /*
614 : : * Clear up all command register,
615 : : * in case there are some residual values
616 : : */
617 : 0 : hns3_cmd_clear_regs(hw);
618 : :
619 : : /* Setup the queue entries for use cmd queue */
620 : 0 : hw->cmq.csq.desc_num = HNS3_NIC_CMQ_DESC_NUM;
621 : 0 : hw->cmq.crq.desc_num = HNS3_NIC_CMQ_DESC_NUM;
622 : :
623 : : /* Setup queue rings */
624 : 0 : ret = hns3_alloc_cmd_queue(hw, HNS3_TYPE_CSQ);
625 [ # # ]: 0 : if (ret) {
626 : 0 : PMD_INIT_LOG(ERR, "CSQ ring setup error %d", ret);
627 : 0 : return ret;
628 : : }
629 : :
630 : 0 : ret = hns3_alloc_cmd_queue(hw, HNS3_TYPE_CRQ);
631 [ # # ]: 0 : if (ret) {
632 : 0 : PMD_INIT_LOG(ERR, "CRQ ring setup error %d", ret);
633 [ # # ]: 0 : goto err_crq;
634 : : }
635 : :
636 : : return 0;
637 : :
638 : : err_crq:
639 : : hns3_free_cmd_desc(hw, &hw->cmq.csq);
640 : :
641 : : return ret;
642 : : }
643 : :
644 : : static void
645 : : hns3_update_dev_lsc_cap(struct hns3_hw *hw, int fw_compact_cmd_result)
646 : : {
647 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
648 : :
649 [ # # ]: 0 : if (hw->adapter_state != HNS3_NIC_UNINITIALIZED)
650 : : return;
651 : :
652 [ # # ]: 0 : if (fw_compact_cmd_result != 0) {
653 : : /*
654 : : * If fw_compact_cmd_result is not zero, it means firmware don't
655 : : * support link status change interrupt.
656 : : * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver
657 : : * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear
658 : : * the RTE_ETH_DEV_INTR_LSC capability when detect firmware
659 : : * don't support link status change interrupt.
660 : : */
661 : 0 : dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
662 : : }
663 : : }
664 : :
665 : : static void
666 : : hns3_set_fc_autoneg_cap(struct hns3_adapter *hns, int fw_compact_cmd_result)
667 : : {
668 : : struct hns3_hw *hw = &hns->hw;
669 : : struct hns3_mac *mac = &hw->mac;
670 : :
671 [ # # ]: 0 : if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) {
672 : 0 : hns->pf.support_fc_autoneg = true;
673 : 0 : return;
674 : : }
675 : :
676 : : /*
677 : : * Flow control auto-negotiation requires the cooperation of the driver
678 : : * and firmware.
679 : : */
680 : 0 : hns->pf.support_fc_autoneg = (hns3_dev_get_support(hw, FC_AUTO) &&
681 : : fw_compact_cmd_result == 0) ?
682 [ # # # # ]: 0 : true : false;
683 : : }
684 : :
685 : : static int
686 : 0 : hns3_apply_fw_compat_cmd_result(struct hns3_hw *hw, int result)
687 : : {
688 : : struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
689 : :
690 [ # # # # ]: 0 : if (result != 0 && hns3_dev_get_support(hw, COPPER)) {
691 : 0 : hns3_err(hw, "firmware fails to initialize the PHY, ret = %d.",
692 : : result);
693 : 0 : return result;
694 : : }
695 : :
696 : : hns3_update_dev_lsc_cap(hw, result);
697 : : hns3_set_fc_autoneg_cap(hns, result);
698 : :
699 : : return 0;
700 : : }
701 : :
702 : : static int
703 : 0 : hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init)
704 : : {
705 : : struct hns3_firmware_compat_cmd *req;
706 : : struct hns3_cmd_desc desc;
707 : : uint32_t compat = 0;
708 : :
709 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false);
710 : : req = (struct hns3_firmware_compat_cmd *)desc.data;
711 : :
712 [ # # ]: 0 : if (is_init) {
713 : : hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1);
714 : : hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0);
715 : : hns3_set_bit(compat, HNS3_LLRS_FEC_EN_B, 1);
716 [ # # ]: 0 : if (hns3_dev_get_support(hw, COPPER))
717 : : hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1);
718 [ # # ]: 0 : if (hns3_dev_get_support(hw, FC_AUTO))
719 : 0 : hns3_set_bit(compat, HNS3_MAC_FC_AUTONEG_EN_B, 1);
720 : : }
721 : 0 : req->compat = rte_cpu_to_le_32(compat);
722 : :
723 : 0 : return hns3_cmd_send(hw, &desc, 1);
724 : : }
725 : :
726 : : int
727 : 0 : hns3_cmd_init(struct hns3_hw *hw)
728 : : {
729 : : struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
730 : : uint32_t version;
731 : : int ret;
732 : :
733 : 0 : rte_spinlock_lock(&hw->cmq.csq.lock);
734 : 0 : rte_spinlock_lock(&hw->cmq.crq.lock);
735 : :
736 : 0 : hw->cmq.csq.next_to_clean = 0;
737 : 0 : hw->cmq.csq.next_to_use = 0;
738 : 0 : hw->cmq.crq.next_to_clean = 0;
739 : 0 : hw->cmq.crq.next_to_use = 0;
740 : : hns3_cmd_init_regs(hw);
741 : :
742 : : rte_spinlock_unlock(&hw->cmq.crq.lock);
743 : : rte_spinlock_unlock(&hw->cmq.csq.lock);
744 : :
745 : : /*
746 : : * Check if there is new reset pending, because the higher level
747 : : * reset may happen when lower level reset is being processed.
748 : : */
749 [ # # ]: 0 : if (is_reset_pending(HNS3_DEV_HW_TO_ADAPTER(hw))) {
750 : 0 : PMD_INIT_LOG(ERR, "New reset pending, keep disable cmd");
751 : : ret = -EBUSY;
752 : 0 : goto err_cmd_init;
753 : : }
754 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 0, rte_memory_order_relaxed);
755 : :
756 : 0 : ret = hns3_cmd_query_firmware_version_and_capability(hw);
757 [ # # ]: 0 : if (ret) {
758 : 0 : PMD_INIT_LOG(ERR, "firmware version query failed %d", ret);
759 : 0 : goto err_cmd_init;
760 : : }
761 : :
762 : 0 : version = hw->fw_version;
763 : 0 : PMD_INIT_LOG(INFO, "The firmware version is %lu.%lu.%lu.%lu",
764 : : hns3_get_field(version, HNS3_FW_VERSION_BYTE3_M,
765 : : HNS3_FW_VERSION_BYTE3_S),
766 : : hns3_get_field(version, HNS3_FW_VERSION_BYTE2_M,
767 : : HNS3_FW_VERSION_BYTE2_S),
768 : : hns3_get_field(version, HNS3_FW_VERSION_BYTE1_M,
769 : : HNS3_FW_VERSION_BYTE1_S),
770 : : hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M,
771 : : HNS3_FW_VERSION_BYTE0_S));
772 : :
773 [ # # ]: 0 : if (hns->is_vf)
774 : : return 0;
775 : :
776 : : /*
777 : : * Requiring firmware to enable some features, fiber port can still
778 : : * work without it, but copper port can't work because the firmware
779 : : * fails to take over the PHY.
780 : : */
781 : 0 : ret = hns3_firmware_compat_config(hw, true);
782 [ # # ]: 0 : if (ret)
783 : 0 : PMD_INIT_LOG(WARNING, "firmware compatible features not "
784 : : "supported, ret = %d.", ret);
785 : :
786 : : /*
787 : : * Perform some corresponding operations based on the firmware
788 : : * compatibility configuration result.
789 : : */
790 : 0 : ret = hns3_apply_fw_compat_cmd_result(hw, ret);
791 [ # # ]: 0 : if (ret)
792 : 0 : goto err_cmd_init;
793 : :
794 : : return 0;
795 : :
796 : 0 : err_cmd_init:
797 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 1, rte_memory_order_relaxed);
798 : 0 : return ret;
799 : : }
800 : :
801 : : static void
802 : 0 : hns3_destroy_queue(struct hns3_hw *hw, struct hns3_cmq_ring *ring)
803 : : {
804 : 0 : rte_spinlock_lock(&ring->lock);
805 : :
806 : : hns3_free_cmd_desc(hw, ring);
807 : :
808 : : rte_spinlock_unlock(&ring->lock);
809 : 0 : }
810 : :
811 : : void
812 : 0 : hns3_cmd_destroy_queue(struct hns3_hw *hw)
813 : : {
814 : 0 : hns3_destroy_queue(hw, &hw->cmq.csq);
815 : 0 : hns3_destroy_queue(hw, &hw->cmq.crq);
816 : 0 : }
817 : :
818 : : void
819 : 0 : hns3_cmd_uninit(struct hns3_hw *hw)
820 : : {
821 : : struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
822 : :
823 [ # # ]: 0 : if (!hns->is_vf)
824 : 0 : (void)hns3_firmware_compat_config(hw, false);
825 : :
826 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 1, rte_memory_order_relaxed);
827 : :
828 : : /*
829 : : * A delay is added to ensure that the register cleanup operations
830 : : * will not be performed concurrently with the firmware command and
831 : : * ensure that all the reserved commands are executed.
832 : : * Concurrency may occur in two scenarios: asynchronous command and
833 : : * timeout command. If the command fails to be executed due to busy
834 : : * scheduling, the command will be processed in the next scheduling
835 : : * of the firmware.
836 : : */
837 : : rte_delay_ms(HNS3_CMDQ_CLEAR_WAIT_TIME);
838 : :
839 : 0 : rte_spinlock_lock(&hw->cmq.csq.lock);
840 : 0 : rte_spinlock_lock(&hw->cmq.crq.lock);
841 : 0 : hns3_cmd_clear_regs(hw);
842 : : rte_spinlock_unlock(&hw->cmq.crq.lock);
843 : : rte_spinlock_unlock(&hw->cmq.csq.lock);
844 : 0 : }
|