1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. */ 3 4 #ifndef _HINIC3_WQ_H_ 5 #define _HINIC3_WQ_H_ 6 7 #include <linux/io.h> 8 9 #include "hinic3_queue_common.h" 10 11 struct hinic3_sq_bufdesc { 12 /* 31-bits Length, L2NIC only uses length[17:0] */ 13 u32 len; 14 u32 rsvd; 15 u32 hi_addr; 16 u32 lo_addr; 17 }; 18 19 /* Work queue is used to submit elements (tx, rx, cmd) to hw. 20 * Driver is the producer that advances prod_idx. cons_idx is advanced when 21 * HW reports completions of previously submitted elements. 22 */ 23 struct hinic3_wq { 24 struct hinic3_queue_pages qpages; 25 /* Unmasked producer/consumer indices that are advanced to natural 26 * integer overflow regardless of queue depth. 27 */ 28 u16 cons_idx; 29 u16 prod_idx; 30 31 u32 q_depth; 32 u16 idx_mask; 33 34 /* Work Queue (logical WQEBB array) is mapped to hw via Chip Logical 35 * Address (CLA) using 1 of 2 levels: 36 * level 0 - direct mapping of single wq page 37 * level 1 - indirect mapping of multiple pages via additional page 38 * table. 39 * When wq uses level 1, wq_block will hold the allocated indirection 40 * table. 41 */ 42 dma_addr_t wq_block_paddr; 43 __be64 *wq_block_vaddr; 44 } ____cacheline_aligned; 45 46 /* Get number of elements in work queue that are in-use. */ 47 static inline u16 hinic3_wq_get_used(const struct hinic3_wq *wq) 48 { 49 return READ_ONCE(wq->prod_idx) - READ_ONCE(wq->cons_idx); 50 } 51 52 static inline u16 hinic3_wq_free_wqebbs(struct hinic3_wq *wq) 53 { 54 /* Don't allow queue to become completely full, report (free - 1). */ 55 return wq->q_depth - hinic3_wq_get_used(wq) - 1; 56 } 57 58 static inline void *hinic3_wq_get_one_wqebb(struct hinic3_wq *wq, u16 *pi) 59 { 60 *pi = wq->prod_idx & wq->idx_mask; 61 wq->prod_idx++; 62 return get_q_element(&wq->qpages, *pi, NULL); 63 } 64 65 static inline void hinic3_wq_put_wqebbs(struct hinic3_wq *wq, u16 num_wqebbs) 66 { 67 wq->cons_idx += num_wqebbs; 68 } 69 70 void hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq, 71 u16 num_wqebbs, u16 *prod_idx, 72 struct hinic3_sq_bufdesc **first_part_wqebbs, 73 struct hinic3_sq_bufdesc **second_part_wqebbs, 74 u16 *first_part_wqebbs_num); 75 76 #endif 77