1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Header file defining the driver buffer management interface 29 */ 30 31 #ifndef _OCE_BUF_H_ 32 #define _OCE_BUF_H_ 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 #include <sys/ddidmareq.h> 39 #include <oce_io.h> 40 #include <oce_utils.h> 41 42 #define GET_Q_NEXT(_START, _STEP, _END) \ 43 (((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \ 44 : (((_START) + (_STEP)) - (_END))) 45 46 #define OCE_MAX_TX_HDL 8 47 #define OCE_MAX_TXDMA_COOKIES 18 48 #define OCE_TXMAP_ALIGN 1 49 #define OCE_TX_MAX_FRAGS (OCE_MAX_TX_HDL * OCE_MAX_TXDMA_COOKIES) 50 51 /* helper structure to access OS addresses */ 52 typedef union oce_addr_s { 53 uint64_t addr64; 54 struct { 55 #ifdef _BIG_ENDIAN 56 uint32_t addr_hi; 57 uint32_t addr_lo; 58 #else 59 uint32_t addr_lo; 60 uint32_t addr_hi; 61 #endif 62 }dw; 63 }oce_addr64_t; 64 65 typedef struct oce_dma_buf_s { 66 caddr_t base; 67 uint64_t addr; 68 ddi_acc_handle_t acc_handle; 69 ddi_dma_handle_t dma_handle; 70 /* size of the memory */ 71 size_t size; 72 size_t off; 73 size_t len; 74 uint32_t num_pages; 75 }oce_dma_buf_t; 76 77 #define DBUF_PA(obj) (((oce_dma_buf_t *)(obj))->addr) 78 #define DBUF_VA(obj) (((oce_dma_buf_t *)(obj))->base) 79 #define DBUF_DHDL(obj) (((oce_dma_buf_t *)(obj))->dma_handle) 80 #define DBUF_AHDL(obj) (((oce_dma_buf_t *)obj))->acc_handle) 81 #define DBUF_SYNC(obj, flags) (void) ddi_dma_sync(DBUF_DHDL(obj), 0,\ 82 0, (flags)) 83 84 typedef struct oce_ring_buffer_s { 85 uint16_t cidx; /* Get ptr */ 86 uint16_t pidx; /* Put Ptr */ 87 size_t item_size; /* Size */ 88 size_t num_items; /* count */ 89 uint32_t num_used; 90 oce_dma_buf_t *dbuf; /* dma buffer */ 91 }oce_ring_buffer_t; 92 93 typedef struct oce_rq_bdesc_s { 94 oce_dma_buf_t *rqb; 95 struct oce_rq *rq; 96 oce_addr64_t frag_addr; 97 mblk_t *mp; 98 frtn_t fr_rtn; 99 uint32_t ref_cnt; 100 }oce_rq_bdesc_t; 101 102 typedef struct oce_wq_bdesc_s { 103 OCE_LIST_NODE_T link; 104 oce_dma_buf_t *wqb; 105 oce_addr64_t frag_addr; 106 } oce_wq_bdesc_t; 107 108 typedef struct oce_wq_mdesc_s { 109 OCE_LIST_NODE_T link; 110 ddi_dma_handle_t dma_handle; 111 } oce_wq_mdesc_t; 112 113 enum entry_type { 114 HEADER_WQE = 0x1, /* arbitrary value */ 115 MAPPED_WQE, 116 COPY_WQE, 117 DUMMY_WQE 118 }; 119 120 typedef struct _oce_handle_s { 121 enum entry_type type; 122 void *hdl; /* opaque handle */ 123 }oce_handle_t; 124 125 typedef struct _oce_wqe_desc_s { 126 OCE_LIST_NODE_T link; 127 oce_handle_t hdesc[OCE_MAX_TX_HDL]; 128 struct oce_nic_frag_wqe frag[OCE_TX_MAX_FRAGS]; 129 struct oce_wq *wq; 130 mblk_t *mp; 131 uint16_t wqe_cnt; 132 uint16_t frag_idx; 133 uint16_t frag_cnt; 134 uint16_t nhdl; 135 }oce_wqe_desc_t; 136 137 #pragma pack(1) 138 /* Always keep it 2 mod 4 */ 139 typedef struct _oce_rq_buf_hdr_s { 140 void *datap; 141 uint8_t pad[18]; 142 /* ether_vlan_header_t vhdr; */ 143 } oce_rq_buf_hdr_t; 144 #pragma pack() 145 146 #define OCE_RQE_BUF_HEADROOM sizeof (oce_rq_buf_hdr_t) 147 #define MAX_POOL_NAME 32 148 149 #define RING_NUM_PENDING(ring) ring->num_used 150 151 #define RING_NUM_FREE(ring) \ 152 (uint32_t)(ring->num_items - ring->num_used) 153 154 #define RING_FULL(ring) (ring->num_used == ring->num_items) 155 156 #define RING_EMPTY(ring) (ring->num_used == 0) 157 158 #define RING_GET(ring, n) \ 159 ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items) 160 161 #define RING_PUT(ring, n) \ 162 ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items) 163 164 #define RING_GET_CONSUMER_ITEM_VA(ring, type) \ 165 (void*)(((type *)DBUF_VA(ring->dbuf)) + ring->cidx) 166 167 #define RING_GET_CONSUMER_ITEM_PA(ring, type) \ 168 (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx) 169 170 #define RING_GET_PRODUCER_ITEM_VA(ring, type) \ 171 (void *)(((type *)DBUF_VA(ring->dbuf)) + ring->pidx) 172 173 #define RING_GET_PRODUCER_ITEM_PA(ring, type) \ 174 (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx) 175 176 /* Rq cache */ 177 int oce_rqb_cache_create(struct oce_rq *rq, size_t buf_size); 178 void oce_rqb_cache_destroy(struct oce_rq *rq); 179 180 /* Wq Cache */ 181 int oce_wqe_desc_ctor(void *buf, void *arg, int kmflags); 182 void oce_wqe_desc_dtor(void *buf, void *arg); 183 184 int oce_wqb_cache_create(struct oce_wq *wq, size_t buf_size); 185 void oce_wqb_cache_destroy(struct oce_wq *wq); 186 187 void oce_wqm_cache_destroy(struct oce_wq *wq); 188 int oce_wqm_cache_create(struct oce_wq *wq); 189 190 void oce_page_list(oce_dma_buf_t *dbuf, 191 struct phys_addr *pa_list, int list_size); 192 193 194 #ifdef __cplusplus 195 } 196 #endif 197 198 #endif /* _OCE_BUF_H_ */ 199