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 43 /* The addresses are 64 bit in the HW */ 44 u64 block_paddr; 45 void **shadow_block_vaddr; 46 u64 *block_vaddr; 47 48 int num_q_pages; 49 u8 *shadow_wqe; 50 u16 *shadow_idx; 51 52 atomic_t cons_idx; 53 atomic_t prod_idx; 54 atomic_t delta; 55 u16 mask; 56 }; 57 58 struct hinic_wqs { 59 struct hinic_hwif *hwif; 60 int num_pages; 61 62 /* The addresses are 64 bit in the HW */ 63 u64 *page_paddr; 64 u64 **page_vaddr; 65 void ***shadow_page_vaddr; 66 67 struct hinic_free_block *free_blocks; 68 int alloc_blk_pos; 69 int return_blk_pos; 70 int num_free_blks; 71 72 /* Lock for getting a free block from the WQ set */ 73 struct semaphore alloc_blocks_lock; 74 }; 75 76 struct hinic_cmdq_pages { 77 /* The addresses are 64 bit in the HW */ 78 u64 page_paddr; 79 u64 *page_vaddr; 80 void **shadow_page_vaddr; 81 82 struct hinic_hwif *hwif; 83 }; 84 85 int hinic_wqs_cmdq_alloc(struct hinic_cmdq_pages *cmdq_pages, 86 struct hinic_wq *wq, struct hinic_hwif *hwif, 87 int cmdq_blocks, u16 wqebb_size, u16 wq_page_size, 88 u16 q_depth, u16 max_wqe_size); 89 90 void hinic_wqs_cmdq_free(struct hinic_cmdq_pages *cmdq_pages, 91 struct hinic_wq *wq, int cmdq_blocks); 92 93 int hinic_wqs_alloc(struct hinic_wqs *wqs, int num_wqs, 94 struct hinic_hwif *hwif); 95 96 void hinic_wqs_free(struct hinic_wqs *wqs); 97 98 int hinic_wq_allocate(struct hinic_wqs *wqs, struct hinic_wq *wq, 99 u16 wqebb_size, u16 wq_page_size, u16 q_depth, 100 u16 max_wqe_size); 101 102 void hinic_wq_free(struct hinic_wqs *wqs, struct hinic_wq *wq); 103 104 struct hinic_hw_wqe *hinic_get_wqe(struct hinic_wq *wq, unsigned int wqe_size, 105 u16 *prod_idx); 106 107 void hinic_put_wqe(struct hinic_wq *wq, unsigned int wqe_size); 108 109 struct hinic_hw_wqe *hinic_read_wqe(struct hinic_wq *wq, unsigned int wqe_size, 110 u16 *cons_idx); 111 112 struct hinic_hw_wqe *hinic_read_wqe_direct(struct hinic_wq *wq, u16 cons_idx); 113 114 void hinic_write_wqe(struct hinic_wq *wq, struct hinic_hw_wqe *wqe, 115 unsigned int wqe_size); 116 117 #endif 118