1 /* QLogic qed NIC Driver
2 * Copyright (c) 2015 QLogic Corporation
4 * This software is available under the terms of the GNU General Public License
5 * (GPL) Version 2, available from the file COPYING in the main directory of
9 #include <linux/types.h>
11 #include <linux/delay.h>
12 #include <linux/dma-mapping.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/list.h>
16 #include <linux/mutex.h>
17 #include <linux/pci.h>
18 #include <linux/slab.h>
19 #include <linux/spinlock.h>
20 #include <linux/string.h>
21 #include <linux/qed/qed_chain.h>
25 #include "qed_reg_addr.h"
27 #define QED_BAR_ACQUIRE_TIMEOUT 1000
30 #define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1))
33 struct list_head list_entry
;
35 struct pxp_ptt_entry pxp
;
39 struct list_head free_list
;
40 spinlock_t lock
; /* ptt synchronized access */
41 struct qed_ptt ptts
[PXP_EXTERNAL_BAR_PF_WINDOW_NUM
];
44 int qed_ptt_pool_alloc(struct qed_hwfn
*p_hwfn
)
46 struct qed_ptt_pool
*p_pool
= kmalloc(sizeof(*p_pool
),
53 INIT_LIST_HEAD(&p_pool
->free_list
);
54 for (i
= 0; i
< PXP_EXTERNAL_BAR_PF_WINDOW_NUM
; i
++) {
55 p_pool
->ptts
[i
].idx
= i
;
56 p_pool
->ptts
[i
].pxp
.offset
= QED_BAR_INVALID_OFFSET
;
57 p_pool
->ptts
[i
].pxp
.pretend
.control
= 0;
58 if (i
>= RESERVED_PTT_MAX
)
59 list_add(&p_pool
->ptts
[i
].list_entry
,
63 p_hwfn
->p_ptt_pool
= p_pool
;
64 spin_lock_init(&p_pool
->lock
);
69 void qed_ptt_invalidate(struct qed_hwfn
*p_hwfn
)
71 struct qed_ptt
*p_ptt
;
74 for (i
= 0; i
< PXP_EXTERNAL_BAR_PF_WINDOW_NUM
; i
++) {
75 p_ptt
= &p_hwfn
->p_ptt_pool
->ptts
[i
];
76 p_ptt
->pxp
.offset
= QED_BAR_INVALID_OFFSET
;
80 void qed_ptt_pool_free(struct qed_hwfn
*p_hwfn
)
82 kfree(p_hwfn
->p_ptt_pool
);
83 p_hwfn
->p_ptt_pool
= NULL
;
86 struct qed_ptt
*qed_ptt_acquire(struct qed_hwfn
*p_hwfn
)
88 struct qed_ptt
*p_ptt
;
91 /* Take the free PTT from the list */
92 for (i
= 0; i
< QED_BAR_ACQUIRE_TIMEOUT
; i
++) {
93 spin_lock_bh(&p_hwfn
->p_ptt_pool
->lock
);
95 if (!list_empty(&p_hwfn
->p_ptt_pool
->free_list
)) {
96 p_ptt
= list_first_entry(&p_hwfn
->p_ptt_pool
->free_list
,
97 struct qed_ptt
, list_entry
);
98 list_del(&p_ptt
->list_entry
);
100 spin_unlock_bh(&p_hwfn
->p_ptt_pool
->lock
);
102 DP_VERBOSE(p_hwfn
, NETIF_MSG_HW
,
103 "allocated ptt %d\n", p_ptt
->idx
);
107 spin_unlock_bh(&p_hwfn
->p_ptt_pool
->lock
);
108 usleep_range(1000, 2000);
111 DP_NOTICE(p_hwfn
, "PTT acquire timeout - failed to allocate PTT\n");
115 void qed_ptt_release(struct qed_hwfn
*p_hwfn
,
116 struct qed_ptt
*p_ptt
)
118 spin_lock_bh(&p_hwfn
->p_ptt_pool
->lock
);
119 list_add(&p_ptt
->list_entry
, &p_hwfn
->p_ptt_pool
->free_list
);
120 spin_unlock_bh(&p_hwfn
->p_ptt_pool
->lock
);
123 u32
qed_ptt_get_hw_addr(struct qed_hwfn
*p_hwfn
,
124 struct qed_ptt
*p_ptt
)
126 /* The HW is using DWORDS and we need to translate it to Bytes */
127 return le32_to_cpu(p_ptt
->pxp
.offset
) << 2;
130 static u32
qed_ptt_config_addr(struct qed_ptt
*p_ptt
)
132 return PXP_PF_WINDOW_ADMIN_PER_PF_START
+
133 p_ptt
->idx
* sizeof(struct pxp_ptt_entry
);
136 u32
qed_ptt_get_bar_addr(struct qed_ptt
*p_ptt
)
138 return PXP_EXTERNAL_BAR_PF_WINDOW_START
+
139 p_ptt
->idx
* PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE
;
142 void qed_ptt_set_win(struct qed_hwfn
*p_hwfn
,
143 struct qed_ptt
*p_ptt
,
148 prev_hw_addr
= qed_ptt_get_hw_addr(p_hwfn
, p_ptt
);
150 if (new_hw_addr
== prev_hw_addr
)
153 /* Update PTT entery in admin window */
154 DP_VERBOSE(p_hwfn
, NETIF_MSG_HW
,
155 "Updating PTT entry %d to offset 0x%x\n",
156 p_ptt
->idx
, new_hw_addr
);
158 /* The HW is using DWORDS and the address is in Bytes */
159 p_ptt
->pxp
.offset
= cpu_to_le32(new_hw_addr
>> 2);
162 qed_ptt_config_addr(p_ptt
) +
163 offsetof(struct pxp_ptt_entry
, offset
),
164 le32_to_cpu(p_ptt
->pxp
.offset
));
167 static u32
qed_set_ptt(struct qed_hwfn
*p_hwfn
,
168 struct qed_ptt
*p_ptt
,
171 u32 win_hw_addr
= qed_ptt_get_hw_addr(p_hwfn
, p_ptt
);
174 offset
= hw_addr
- win_hw_addr
;
176 /* Verify the address is within the window */
177 if (hw_addr
< win_hw_addr
||
178 offset
>= PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE
) {
179 qed_ptt_set_win(p_hwfn
, p_ptt
, hw_addr
);
183 return qed_ptt_get_bar_addr(p_ptt
) + offset
;
186 struct qed_ptt
*qed_get_reserved_ptt(struct qed_hwfn
*p_hwfn
,
187 enum reserved_ptts ptt_idx
)
189 if (ptt_idx
>= RESERVED_PTT_MAX
) {
191 "Requested PTT %d is out of range\n", ptt_idx
);
195 return &p_hwfn
->p_ptt_pool
->ptts
[ptt_idx
];
198 void qed_wr(struct qed_hwfn
*p_hwfn
,
199 struct qed_ptt
*p_ptt
,
200 u32 hw_addr
, u32 val
)
202 u32 bar_addr
= qed_set_ptt(p_hwfn
, p_ptt
, hw_addr
);
204 REG_WR(p_hwfn
, bar_addr
, val
);
205 DP_VERBOSE(p_hwfn
, NETIF_MSG_HW
,
206 "bar_addr 0x%x, hw_addr 0x%x, val 0x%x\n",
207 bar_addr
, hw_addr
, val
);
210 u32
qed_rd(struct qed_hwfn
*p_hwfn
,
211 struct qed_ptt
*p_ptt
,
214 u32 bar_addr
= qed_set_ptt(p_hwfn
, p_ptt
, hw_addr
);
215 u32 val
= REG_RD(p_hwfn
, bar_addr
);
217 DP_VERBOSE(p_hwfn
, NETIF_MSG_HW
,
218 "bar_addr 0x%x, hw_addr 0x%x, val 0x%x\n",
219 bar_addr
, hw_addr
, val
);
224 static void qed_memcpy_hw(struct qed_hwfn
*p_hwfn
,
225 struct qed_ptt
*p_ptt
,
231 u32 dw_count
, *host_addr
, hw_offset
;
232 size_t quota
, done
= 0;
233 u32 __iomem
*reg_addr
;
236 quota
= min_t(size_t, n
- done
,
237 PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE
);
239 qed_ptt_set_win(p_hwfn
, p_ptt
, hw_addr
+ done
);
240 hw_offset
= qed_ptt_get_bar_addr(p_ptt
);
242 dw_count
= quota
/ 4;
243 host_addr
= (u32
*)((u8
*)addr
+ done
);
244 reg_addr
= (u32 __iomem
*)REG_ADDR(p_hwfn
, hw_offset
);
247 DIRECT_REG_WR(reg_addr
++, *host_addr
++);
250 *host_addr
++ = DIRECT_REG_RD(reg_addr
++);
256 void qed_memcpy_from(struct qed_hwfn
*p_hwfn
,
257 struct qed_ptt
*p_ptt
,
258 void *dest
, u32 hw_addr
, size_t n
)
260 DP_VERBOSE(p_hwfn
, NETIF_MSG_HW
,
261 "hw_addr 0x%x, dest %p hw_addr 0x%x, size %lu\n",
262 hw_addr
, dest
, hw_addr
, (unsigned long)n
);
264 qed_memcpy_hw(p_hwfn
, p_ptt
, dest
, hw_addr
, n
, false);
267 void qed_memcpy_to(struct qed_hwfn
*p_hwfn
,
268 struct qed_ptt
*p_ptt
,
269 u32 hw_addr
, void *src
, size_t n
)
271 DP_VERBOSE(p_hwfn
, NETIF_MSG_HW
,
272 "hw_addr 0x%x, hw_addr 0x%x, src %p size %lu\n",
273 hw_addr
, hw_addr
, src
, (unsigned long)n
);
275 qed_memcpy_hw(p_hwfn
, p_ptt
, src
, hw_addr
, n
, true);
278 void qed_fid_pretend(struct qed_hwfn
*p_hwfn
,
279 struct qed_ptt
*p_ptt
,
284 SET_FIELD(control
, PXP_PRETEND_CMD_IS_CONCRETE
, 1);
285 SET_FIELD(control
, PXP_PRETEND_CMD_PRETEND_FUNCTION
, 1);
287 /* Every pretend undos previous pretends, including
288 * previous port pretend.
290 SET_FIELD(control
, PXP_PRETEND_CMD_PORT
, 0);
291 SET_FIELD(control
, PXP_PRETEND_CMD_USE_PORT
, 0);
292 SET_FIELD(control
, PXP_PRETEND_CMD_PRETEND_PORT
, 1);
294 if (!GET_FIELD(fid
, PXP_CONCRETE_FID_VFVALID
))
295 fid
= GET_FIELD(fid
, PXP_CONCRETE_FID_PFID
);
297 p_ptt
->pxp
.pretend
.control
= cpu_to_le16(control
);
298 p_ptt
->pxp
.pretend
.fid
.concrete_fid
.fid
= cpu_to_le16(fid
);
301 qed_ptt_config_addr(p_ptt
) +
302 offsetof(struct pxp_ptt_entry
, pretend
),
303 *(u32
*)&p_ptt
->pxp
.pretend
);
306 void qed_port_pretend(struct qed_hwfn
*p_hwfn
,
307 struct qed_ptt
*p_ptt
,
312 SET_FIELD(control
, PXP_PRETEND_CMD_PORT
, port_id
);
313 SET_FIELD(control
, PXP_PRETEND_CMD_USE_PORT
, 1);
314 SET_FIELD(control
, PXP_PRETEND_CMD_PRETEND_PORT
, 1);
316 p_ptt
->pxp
.pretend
.control
= cpu_to_le16(control
);
319 qed_ptt_config_addr(p_ptt
) +
320 offsetof(struct pxp_ptt_entry
, pretend
),
321 *(u32
*)&p_ptt
->pxp
.pretend
);
324 void qed_port_unpretend(struct qed_hwfn
*p_hwfn
,
325 struct qed_ptt
*p_ptt
)
329 SET_FIELD(control
, PXP_PRETEND_CMD_PORT
, 0);
330 SET_FIELD(control
, PXP_PRETEND_CMD_USE_PORT
, 0);
331 SET_FIELD(control
, PXP_PRETEND_CMD_PRETEND_PORT
, 1);
333 p_ptt
->pxp
.pretend
.control
= cpu_to_le16(control
);
336 qed_ptt_config_addr(p_ptt
) +
337 offsetof(struct pxp_ptt_entry
, pretend
),
338 *(u32
*)&p_ptt
->pxp
.pretend
);
342 static void qed_dmae_opcode(struct qed_hwfn
*p_hwfn
,
343 const u8 is_src_type_grc
,
344 const u8 is_dst_type_grc
,
345 struct qed_dmae_params
*p_params
)
350 /* Whether the source is the PCIe or the GRC.
351 * 0- The source is the PCIe
352 * 1- The source is the GRC.
354 opcode
|= (is_src_type_grc
? DMAE_CMD_SRC_MASK_GRC
355 : DMAE_CMD_SRC_MASK_PCIE
) <<
357 opcode
|= ((p_hwfn
->rel_pf_id
& DMAE_CMD_SRC_PF_ID_MASK
) <<
358 DMAE_CMD_SRC_PF_ID_SHIFT
);
360 /* The destination of the DMA can be: 0-None 1-PCIe 2-GRC 3-None */
361 opcode
|= (is_dst_type_grc
? DMAE_CMD_DST_MASK_GRC
362 : DMAE_CMD_DST_MASK_PCIE
) <<
364 opcode
|= ((p_hwfn
->rel_pf_id
& DMAE_CMD_DST_PF_ID_MASK
) <<
365 DMAE_CMD_DST_PF_ID_SHIFT
);
367 /* Whether to write a completion word to the completion destination:
368 * 0-Do not write a completion word
369 * 1-Write the completion word
371 opcode
|= (DMAE_CMD_COMP_WORD_EN_MASK
<< DMAE_CMD_COMP_WORD_EN_SHIFT
);
372 opcode
|= (DMAE_CMD_SRC_ADDR_RESET_MASK
<<
373 DMAE_CMD_SRC_ADDR_RESET_SHIFT
);
375 if (p_params
->flags
& QED_DMAE_FLAG_COMPLETION_DST
)
376 opcode
|= (1 << DMAE_CMD_COMP_FUNC_SHIFT
);
378 opcode
|= (DMAE_CMD_ENDIANITY
<< DMAE_CMD_ENDIANITY_MODE_SHIFT
);
380 opcode
|= ((p_hwfn
->port_id
) << DMAE_CMD_PORT_ID_SHIFT
);
382 /* reset source address in next go */
383 opcode
|= (DMAE_CMD_SRC_ADDR_RESET_MASK
<<
384 DMAE_CMD_SRC_ADDR_RESET_SHIFT
);
386 /* reset dest address in next go */
387 opcode
|= (DMAE_CMD_DST_ADDR_RESET_MASK
<<
388 DMAE_CMD_DST_ADDR_RESET_SHIFT
);
390 opcodeB
|= (DMAE_CMD_SRC_VF_ID_MASK
<<
391 DMAE_CMD_SRC_VF_ID_SHIFT
);
393 opcodeB
|= (DMAE_CMD_DST_VF_ID_MASK
<<
394 DMAE_CMD_DST_VF_ID_SHIFT
);
396 p_hwfn
->dmae_info
.p_dmae_cmd
->opcode
= cpu_to_le32(opcode
);
397 p_hwfn
->dmae_info
.p_dmae_cmd
->opcode_b
= cpu_to_le16(opcodeB
);
400 u32
qed_dmae_idx_to_go_cmd(u8 idx
)
402 /* All the DMAE 'go' registers form an array in internal memory */
403 return DMAE_REG_GO_C0
+ (idx
<< 2);
407 qed_dmae_post_command(struct qed_hwfn
*p_hwfn
,
408 struct qed_ptt
*p_ptt
)
410 struct dmae_cmd
*command
= p_hwfn
->dmae_info
.p_dmae_cmd
;
411 u8 idx_cmd
= p_hwfn
->dmae_info
.channel
, i
;
414 /* verify address is not NULL */
415 if ((((command
->dst_addr_lo
== 0) && (command
->dst_addr_hi
== 0)) ||
416 ((command
->src_addr_lo
== 0) && (command
->src_addr_hi
== 0)))) {
418 "source or destination address 0 idx_cmd=%d\n"
419 "opcode = [0x%08x,0x%04x] len=0x%x src=0x%x:%x dst=0x%x:%x\n",
421 le32_to_cpu(command
->opcode
),
422 le16_to_cpu(command
->opcode_b
),
423 le16_to_cpu(command
->length
),
424 le32_to_cpu(command
->src_addr_hi
),
425 le32_to_cpu(command
->src_addr_lo
),
426 le32_to_cpu(command
->dst_addr_hi
),
427 le32_to_cpu(command
->dst_addr_lo
));
434 "Posting DMAE command [idx %d]: opcode = [0x%08x,0x%04x] len=0x%x src=0x%x:%x dst=0x%x:%x\n",
436 le32_to_cpu(command
->opcode
),
437 le16_to_cpu(command
->opcode_b
),
438 le16_to_cpu(command
->length
),
439 le32_to_cpu(command
->src_addr_hi
),
440 le32_to_cpu(command
->src_addr_lo
),
441 le32_to_cpu(command
->dst_addr_hi
),
442 le32_to_cpu(command
->dst_addr_lo
));
444 /* Copy the command to DMAE - need to do it before every call
445 * for source/dest address no reset.
446 * The first 9 DWs are the command registers, the 10 DW is the
447 * GO register, and the rest are result registers
448 * (which are read only by the client).
450 for (i
= 0; i
< DMAE_CMD_SIZE
; i
++) {
451 u32 data
= (i
< DMAE_CMD_SIZE_TO_FILL
) ?
452 *(((u32
*)command
) + i
) : 0;
454 qed_wr(p_hwfn
, p_ptt
,
456 (idx_cmd
* DMAE_CMD_SIZE
* sizeof(u32
)) +
457 (i
* sizeof(u32
)), data
);
460 qed_wr(p_hwfn
, p_ptt
,
461 qed_dmae_idx_to_go_cmd(idx_cmd
),
467 int qed_dmae_info_alloc(struct qed_hwfn
*p_hwfn
)
469 dma_addr_t
*p_addr
= &p_hwfn
->dmae_info
.completion_word_phys_addr
;
470 struct dmae_cmd
**p_cmd
= &p_hwfn
->dmae_info
.p_dmae_cmd
;
471 u32
**p_buff
= &p_hwfn
->dmae_info
.p_intermediate_buffer
;
472 u32
**p_comp
= &p_hwfn
->dmae_info
.p_completion_word
;
474 *p_comp
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
479 DP_NOTICE(p_hwfn
, "Failed to allocate `p_completion_word'\n");
483 p_addr
= &p_hwfn
->dmae_info
.dmae_cmd_phys_addr
;
484 *p_cmd
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
485 sizeof(struct dmae_cmd
),
488 DP_NOTICE(p_hwfn
, "Failed to allocate `struct dmae_cmd'\n");
492 p_addr
= &p_hwfn
->dmae_info
.intermediate_buffer_phys_addr
;
493 *p_buff
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
494 sizeof(u32
) * DMAE_MAX_RW_SIZE
,
497 DP_NOTICE(p_hwfn
, "Failed to allocate `intermediate_buffer'\n");
501 p_hwfn
->dmae_info
.channel
= p_hwfn
->rel_pf_id
;
505 qed_dmae_info_free(p_hwfn
);
509 void qed_dmae_info_free(struct qed_hwfn
*p_hwfn
)
513 /* Just make sure no one is in the middle */
514 mutex_lock(&p_hwfn
->dmae_info
.mutex
);
516 if (p_hwfn
->dmae_info
.p_completion_word
) {
517 p_phys
= p_hwfn
->dmae_info
.completion_word_phys_addr
;
518 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
520 p_hwfn
->dmae_info
.p_completion_word
,
522 p_hwfn
->dmae_info
.p_completion_word
= NULL
;
525 if (p_hwfn
->dmae_info
.p_dmae_cmd
) {
526 p_phys
= p_hwfn
->dmae_info
.dmae_cmd_phys_addr
;
527 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
528 sizeof(struct dmae_cmd
),
529 p_hwfn
->dmae_info
.p_dmae_cmd
,
531 p_hwfn
->dmae_info
.p_dmae_cmd
= NULL
;
534 if (p_hwfn
->dmae_info
.p_intermediate_buffer
) {
535 p_phys
= p_hwfn
->dmae_info
.intermediate_buffer_phys_addr
;
536 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
537 sizeof(u32
) * DMAE_MAX_RW_SIZE
,
538 p_hwfn
->dmae_info
.p_intermediate_buffer
,
540 p_hwfn
->dmae_info
.p_intermediate_buffer
= NULL
;
543 mutex_unlock(&p_hwfn
->dmae_info
.mutex
);
546 static int qed_dmae_operation_wait(struct qed_hwfn
*p_hwfn
)
549 u32 wait_cnt_limit
= 10000;
554 while (*p_hwfn
->dmae_info
.p_completion_word
!= DMAE_COMPLETION_VAL
) {
555 udelay(DMAE_MIN_WAIT_TIME
);
556 if (++wait_cnt
> wait_cnt_limit
) {
557 DP_NOTICE(p_hwfn
->cdev
,
558 "Timed-out waiting for operation to complete. Completion word is 0x%08x expected 0x%08x.\n",
559 *p_hwfn
->dmae_info
.p_completion_word
,
560 DMAE_COMPLETION_VAL
);
565 /* to sync the completion_word since we are not
566 * using the volatile keyword for p_completion_word
572 *p_hwfn
->dmae_info
.p_completion_word
= 0;
577 static int qed_dmae_execute_sub_operation(struct qed_hwfn
*p_hwfn
,
578 struct qed_ptt
*p_ptt
,
585 dma_addr_t phys
= p_hwfn
->dmae_info
.intermediate_buffer_phys_addr
;
586 struct dmae_cmd
*cmd
= p_hwfn
->dmae_info
.p_dmae_cmd
;
590 case QED_DMAE_ADDRESS_GRC
:
591 case QED_DMAE_ADDRESS_HOST_PHYS
:
592 cmd
->src_addr_hi
= cpu_to_le32(upper_32_bits(src_addr
));
593 cmd
->src_addr_lo
= cpu_to_le32(lower_32_bits(src_addr
));
595 /* for virtual source addresses we use the intermediate buffer. */
596 case QED_DMAE_ADDRESS_HOST_VIRT
:
597 cmd
->src_addr_hi
= cpu_to_le32(upper_32_bits(phys
));
598 cmd
->src_addr_lo
= cpu_to_le32(lower_32_bits(phys
));
599 memcpy(&p_hwfn
->dmae_info
.p_intermediate_buffer
[0],
600 (void *)(uintptr_t)src_addr
,
601 length
* sizeof(u32
));
608 case QED_DMAE_ADDRESS_GRC
:
609 case QED_DMAE_ADDRESS_HOST_PHYS
:
610 cmd
->dst_addr_hi
= cpu_to_le32(upper_32_bits(dst_addr
));
611 cmd
->dst_addr_lo
= cpu_to_le32(lower_32_bits(dst_addr
));
613 /* for virtual source addresses we use the intermediate buffer. */
614 case QED_DMAE_ADDRESS_HOST_VIRT
:
615 cmd
->dst_addr_hi
= cpu_to_le32(upper_32_bits(phys
));
616 cmd
->dst_addr_lo
= cpu_to_le32(lower_32_bits(phys
));
622 cmd
->length
= cpu_to_le16((u16
)length
);
624 qed_dmae_post_command(p_hwfn
, p_ptt
);
626 qed_status
= qed_dmae_operation_wait(p_hwfn
);
630 "qed_dmae_host2grc: Wait Failed. source_addr 0x%llx, grc_addr 0x%llx, size_in_dwords 0x%x\n",
637 if (dst_type
== QED_DMAE_ADDRESS_HOST_VIRT
)
638 memcpy((void *)(uintptr_t)(dst_addr
),
639 &p_hwfn
->dmae_info
.p_intermediate_buffer
[0],
640 length
* sizeof(u32
));
645 static int qed_dmae_execute_command(struct qed_hwfn
*p_hwfn
,
646 struct qed_ptt
*p_ptt
,
647 u64 src_addr
, u64 dst_addr
,
648 u8 src_type
, u8 dst_type
,
650 struct qed_dmae_params
*p_params
)
652 dma_addr_t phys
= p_hwfn
->dmae_info
.completion_word_phys_addr
;
653 u16 length_cur
= 0, i
= 0, cnt_split
= 0, length_mod
= 0;
654 struct dmae_cmd
*cmd
= p_hwfn
->dmae_info
.p_dmae_cmd
;
655 u64 src_addr_split
= 0, dst_addr_split
= 0;
656 u16 length_limit
= DMAE_MAX_RW_SIZE
;
660 qed_dmae_opcode(p_hwfn
,
661 (src_type
== QED_DMAE_ADDRESS_GRC
),
662 (dst_type
== QED_DMAE_ADDRESS_GRC
),
665 cmd
->comp_addr_lo
= cpu_to_le32(lower_32_bits(phys
));
666 cmd
->comp_addr_hi
= cpu_to_le32(upper_32_bits(phys
));
667 cmd
->comp_val
= cpu_to_le32(DMAE_COMPLETION_VAL
);
669 /* Check if the grc_addr is valid like < MAX_GRC_OFFSET */
670 cnt_split
= size_in_dwords
/ length_limit
;
671 length_mod
= size_in_dwords
% length_limit
;
673 src_addr_split
= src_addr
;
674 dst_addr_split
= dst_addr
;
676 for (i
= 0; i
<= cnt_split
; i
++) {
677 offset
= length_limit
* i
;
679 if (!(p_params
->flags
& QED_DMAE_FLAG_RW_REPL_SRC
)) {
680 if (src_type
== QED_DMAE_ADDRESS_GRC
)
681 src_addr_split
= src_addr
+ offset
;
683 src_addr_split
= src_addr
+ (offset
* 4);
686 if (dst_type
== QED_DMAE_ADDRESS_GRC
)
687 dst_addr_split
= dst_addr
+ offset
;
689 dst_addr_split
= dst_addr
+ (offset
* 4);
691 length_cur
= (cnt_split
== i
) ? length_mod
: length_limit
;
693 /* might be zero on last iteration */
697 qed_status
= qed_dmae_execute_sub_operation(p_hwfn
,
706 "qed_dmae_execute_sub_operation Failed with error 0x%x. source_addr 0x%llx, destination addr 0x%llx, size_in_dwords 0x%x\n",
718 int qed_dmae_host2grc(struct qed_hwfn
*p_hwfn
,
719 struct qed_ptt
*p_ptt
,
725 u32 grc_addr_in_dw
= grc_addr
/ sizeof(u32
);
726 struct qed_dmae_params params
;
729 memset(¶ms
, 0, sizeof(struct qed_dmae_params
));
730 params
.flags
= flags
;
732 mutex_lock(&p_hwfn
->dmae_info
.mutex
);
734 rc
= qed_dmae_execute_command(p_hwfn
, p_ptt
, source_addr
,
736 QED_DMAE_ADDRESS_HOST_VIRT
,
737 QED_DMAE_ADDRESS_GRC
,
738 size_in_dwords
, ¶ms
);
740 mutex_unlock(&p_hwfn
->dmae_info
.mutex
);
745 u16
qed_get_qm_pq(struct qed_hwfn
*p_hwfn
,
746 enum protocol_type proto
,
747 union qed_qm_pq_params
*p_params
)
751 if ((proto
== PROTOCOLID_CORE
|| proto
== PROTOCOLID_ETH
) &&
754 "Protocol %d received NULL PQ params\n",
760 case PROTOCOLID_CORE
:
761 if (p_params
->core
.tc
== LB_TC
)
762 pq_id
= p_hwfn
->qm_info
.pure_lb_pq
;
764 pq_id
= p_hwfn
->qm_info
.offload_pq
;
767 pq_id
= p_params
->eth
.tc
;
773 pq_id
= CM_TX_PQ_BASE
+ pq_id
+ RESC_START(p_hwfn
, QED_PQ
);