12025cf9eSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2b15a9f37SAviad Krawczyk /*
3b15a9f37SAviad Krawczyk  * Huawei HiNIC PCI Express Linux driver
4b15a9f37SAviad Krawczyk  * Copyright(c) 2017 Huawei Technologies Co., Ltd
5b15a9f37SAviad Krawczyk  */
6b15a9f37SAviad Krawczyk 
7b15a9f37SAviad Krawczyk #ifndef HINIC_HW_WQ_H
8b15a9f37SAviad Krawczyk #define HINIC_HW_WQ_H
9b15a9f37SAviad Krawczyk 
10b15a9f37SAviad Krawczyk #include <linux/types.h>
11b15a9f37SAviad Krawczyk #include <linux/semaphore.h>
12b15a9f37SAviad Krawczyk #include <linux/atomic.h>
13b15a9f37SAviad Krawczyk 
14b15a9f37SAviad Krawczyk #include "hinic_hw_if.h"
1576baca2eSAviad Krawczyk #include "hinic_hw_wqe.h"
16b15a9f37SAviad Krawczyk 
17b15a9f37SAviad Krawczyk struct hinic_free_block {
18b15a9f37SAviad Krawczyk 	int     page_idx;
19b15a9f37SAviad Krawczyk 	int     block_idx;
20b15a9f37SAviad Krawczyk };
21b15a9f37SAviad Krawczyk 
22b15a9f37SAviad Krawczyk struct hinic_wq {
23b15a9f37SAviad Krawczyk 	struct hinic_hwif       *hwif;
24b15a9f37SAviad Krawczyk 
25b15a9f37SAviad Krawczyk 	int             page_idx;
26b15a9f37SAviad Krawczyk 	int             block_idx;
27b15a9f37SAviad Krawczyk 
28b15a9f37SAviad Krawczyk 	u16             wqebb_size;
297dd29ee1SLuo bin 	u32             wq_page_size;
30b15a9f37SAviad Krawczyk 	u16             q_depth;
31b15a9f37SAviad Krawczyk 	u16             max_wqe_size;
32b15a9f37SAviad Krawczyk 	u16             num_wqebbs_per_page;
33ebda9b46SXue Chaojing 	u16		wqebbs_per_page_shift;
34ebda9b46SXue Chaojing 	u16		wqebb_size_shift;
35b15a9f37SAviad Krawczyk 	/* The addresses are 64 bit in the HW */
36b15a9f37SAviad Krawczyk 	u64             block_paddr;
37b15a9f37SAviad Krawczyk 	void            **shadow_block_vaddr;
38b15a9f37SAviad Krawczyk 	u64             *block_vaddr;
39b15a9f37SAviad Krawczyk 
40b15a9f37SAviad Krawczyk 	int             num_q_pages;
41b15a9f37SAviad Krawczyk 	u8              *shadow_wqe;
42b15a9f37SAviad Krawczyk 	u16             *shadow_idx;
43b15a9f37SAviad Krawczyk 
44b15a9f37SAviad Krawczyk 	atomic_t        cons_idx;
45b15a9f37SAviad Krawczyk 	atomic_t        prod_idx;
46b15a9f37SAviad Krawczyk 	atomic_t        delta;
47b15a9f37SAviad Krawczyk 	u16             mask;
48b15a9f37SAviad Krawczyk };
49b15a9f37SAviad Krawczyk 
50b15a9f37SAviad Krawczyk struct hinic_wqs {
51b15a9f37SAviad Krawczyk 	struct hinic_hwif       *hwif;
52b15a9f37SAviad Krawczyk 	int                     num_pages;
53b15a9f37SAviad Krawczyk 
54b15a9f37SAviad Krawczyk 	/* The addresses are 64 bit in the HW */
55b15a9f37SAviad Krawczyk 	u64                     *page_paddr;
56b15a9f37SAviad Krawczyk 	u64                     **page_vaddr;
57b15a9f37SAviad Krawczyk 	void                    ***shadow_page_vaddr;
58b15a9f37SAviad Krawczyk 
59b15a9f37SAviad Krawczyk 	struct hinic_free_block *free_blocks;
60b15a9f37SAviad Krawczyk 	int                     alloc_blk_pos;
61b15a9f37SAviad Krawczyk 	int                     return_blk_pos;
62b15a9f37SAviad Krawczyk 	int                     num_free_blks;
63b15a9f37SAviad Krawczyk 
64b15a9f37SAviad Krawczyk 	/* Lock for getting a free block from the WQ set */
65b15a9f37SAviad Krawczyk 	struct semaphore        alloc_blocks_lock;
66b15a9f37SAviad Krawczyk };
67b15a9f37SAviad Krawczyk 
6853e7d6feSAviad Krawczyk struct hinic_cmdq_pages {
6953e7d6feSAviad Krawczyk 	/* The addresses are 64 bit in the HW */
7053e7d6feSAviad Krawczyk 	u64                     page_paddr;
7153e7d6feSAviad Krawczyk 	u64                     *page_vaddr;
7253e7d6feSAviad Krawczyk 	void                    **shadow_page_vaddr;
7353e7d6feSAviad Krawczyk 
7453e7d6feSAviad Krawczyk 	struct hinic_hwif       *hwif;
7553e7d6feSAviad Krawczyk };
7653e7d6feSAviad Krawczyk 
77d0b9805eSAviad Krawczyk int hinic_wqs_cmdq_alloc(struct hinic_cmdq_pages *cmdq_pages,
78d0b9805eSAviad Krawczyk 			 struct hinic_wq *wq, struct hinic_hwif *hwif,
797dd29ee1SLuo bin 			 int cmdq_blocks, u16 wqebb_size, u32 wq_page_size,
80d0b9805eSAviad Krawczyk 			 u16 q_depth, u16 max_wqe_size);
81d0b9805eSAviad Krawczyk 
82d0b9805eSAviad Krawczyk void hinic_wqs_cmdq_free(struct hinic_cmdq_pages *cmdq_pages,
83d0b9805eSAviad Krawczyk 			 struct hinic_wq *wq, int cmdq_blocks);
84d0b9805eSAviad Krawczyk 
85b15a9f37SAviad Krawczyk int hinic_wqs_alloc(struct hinic_wqs *wqs, int num_wqs,
86b15a9f37SAviad Krawczyk 		    struct hinic_hwif *hwif);
87b15a9f37SAviad Krawczyk 
88b15a9f37SAviad Krawczyk void hinic_wqs_free(struct hinic_wqs *wqs);
89b15a9f37SAviad Krawczyk 
90b15a9f37SAviad Krawczyk int hinic_wq_allocate(struct hinic_wqs *wqs, struct hinic_wq *wq,
917dd29ee1SLuo bin 		      u16 wqebb_size, u32 wq_page_size, u16 q_depth,
92b15a9f37SAviad Krawczyk 		      u16 max_wqe_size);
93b15a9f37SAviad Krawczyk 
94b15a9f37SAviad Krawczyk void hinic_wq_free(struct hinic_wqs *wqs, struct hinic_wq *wq);
95b15a9f37SAviad Krawczyk 
9676baca2eSAviad Krawczyk struct hinic_hw_wqe *hinic_get_wqe(struct hinic_wq *wq, unsigned int wqe_size,
9776baca2eSAviad Krawczyk 				   u16 *prod_idx);
9876baca2eSAviad Krawczyk 
99cc18a754SZhao Chen void hinic_return_wqe(struct hinic_wq *wq, unsigned int wqe_size);
100cc18a754SZhao Chen 
10176baca2eSAviad Krawczyk void hinic_put_wqe(struct hinic_wq *wq, unsigned int wqe_size);
10276baca2eSAviad Krawczyk 
10376baca2eSAviad Krawczyk struct hinic_hw_wqe *hinic_read_wqe(struct hinic_wq *wq, unsigned int wqe_size,
10476baca2eSAviad Krawczyk 				    u16 *cons_idx);
10576baca2eSAviad Krawczyk 
106e2585ea7SAviad Krawczyk struct hinic_hw_wqe *hinic_read_wqe_direct(struct hinic_wq *wq, u16 cons_idx);
107e2585ea7SAviad Krawczyk 
10876baca2eSAviad Krawczyk void hinic_write_wqe(struct hinic_wq *wq, struct hinic_hw_wqe *wqe,
10976baca2eSAviad Krawczyk 		     unsigned int wqe_size);
11076baca2eSAviad Krawczyk 
111b15a9f37SAviad Krawczyk #endif
112