1 /* 2 * Huawei HiNIC PCI Express Linux driver 3 * Copyright(c) 2017 Huawei Technologies Co., Ltd 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * for more details. 13 * 14 */ 15 16 #ifndef HINIC_HW_WQ_H 17 #define HINIC_HW_WQ_H 18 19 #include <linux/types.h> 20 #include <linux/semaphore.h> 21 #include <linux/atomic.h> 22 23 #include "hinic_hw_if.h" 24 #include "hinic_hw_wqe.h" 25 26 struct hinic_free_block { 27 int page_idx; 28 int block_idx; 29 }; 30 31 struct hinic_wq { 32 struct hinic_hwif *hwif; 33 34 int page_idx; 35 int block_idx; 36 37 u16 wqebb_size; 38 u16 wq_page_size; 39 u16 q_depth; 40 u16 max_wqe_size; 41 u16 num_wqebbs_per_page; 42 u16 wqebbs_per_page_shift; 43 u16 wqebb_size_shift; 44 /* The addresses are 64 bit in the HW */ 45 u64 block_paddr; 46 void **shadow_block_vaddr; 47 u64 *block_vaddr; 48 49 int num_q_pages; 50 u8 *shadow_wqe; 51 u16 *shadow_idx; 52 53 atomic_t cons_idx; 54 atomic_t prod_idx; 55 atomic_t delta; 56 u16 mask; 57 }; 58 59 struct hinic_wqs { 60 struct hinic_hwif *hwif; 61 int num_pages; 62 63 /* The addresses are 64 bit in the HW */ 64 u64 *page_paddr; 65 u64 **page_vaddr; 66 void ***shadow_page_vaddr; 67 68 struct hinic_free_block *free_blocks; 69 int alloc_blk_pos; 70 int return_blk_pos; 71 int num_free_blks; 72 73 /* Lock for getting a free block from the WQ set */ 74 struct semaphore alloc_blocks_lock; 75 }; 76 77 struct hinic_cmdq_pages { 78 /* The addresses are 64 bit in the HW */ 79 u64 page_paddr; 80 u64 *page_vaddr; 81 void **shadow_page_vaddr; 82 83 struct hinic_hwif *hwif; 84 }; 85 86 int hinic_wqs_cmdq_alloc(struct hinic_cmdq_pages *cmdq_pages, 87 struct hinic_wq *wq, struct hinic_hwif *hwif, 88 int cmdq_blocks, u16 wqebb_size, u16 wq_page_size, 89 u16 q_depth, u16 max_wqe_size); 90 91 void hinic_wqs_cmdq_free(struct hinic_cmdq_pages *cmdq_pages, 92 struct hinic_wq *wq, int cmdq_blocks); 93 94 int hinic_wqs_alloc(struct hinic_wqs *wqs, int num_wqs, 95 struct hinic_hwif *hwif); 96 97 void hinic_wqs_free(struct hinic_wqs *wqs); 98 99 int hinic_wq_allocate(struct hinic_wqs *wqs, struct hinic_wq *wq, 100 u16 wqebb_size, u16 wq_page_size, u16 q_depth, 101 u16 max_wqe_size); 102 103 void hinic_wq_free(struct hinic_wqs *wqs, struct hinic_wq *wq); 104 105 struct hinic_hw_wqe *hinic_get_wqe(struct hinic_wq *wq, unsigned int wqe_size, 106 u16 *prod_idx); 107 108 void hinic_return_wqe(struct hinic_wq *wq, unsigned int wqe_size); 109 110 void hinic_put_wqe(struct hinic_wq *wq, unsigned int wqe_size); 111 112 struct hinic_hw_wqe *hinic_read_wqe(struct hinic_wq *wq, unsigned int wqe_size, 113 u16 *cons_idx); 114 115 struct hinic_hw_wqe *hinic_read_wqe_direct(struct hinic_wq *wq, u16 cons_idx); 116 117 void hinic_write_wqe(struct hinic_wq *wq, struct hinic_hw_wqe *wqe, 118 unsigned int wqe_size); 119 120 #endif 121