1325618Ssbruno/* 2325618Ssbruno * BSD LICENSE 3325618Ssbruno * 4325618Ssbruno * Copyright(c) 2017 Cavium, Inc.. All rights reserved. 5325618Ssbruno * All rights reserved. 6325618Ssbruno * 7325618Ssbruno * Redistribution and use in source and binary forms, with or without 8325618Ssbruno * modification, are permitted provided that the following conditions 9325618Ssbruno * are met: 10325618Ssbruno * 11325618Ssbruno * * Redistributions of source code must retain the above copyright 12325618Ssbruno * notice, this list of conditions and the following disclaimer. 13325618Ssbruno * * Redistributions in binary form must reproduce the above copyright 14325618Ssbruno * notice, this list of conditions and the following disclaimer in 15325618Ssbruno * the documentation and/or other materials provided with the 16325618Ssbruno * distribution. 17325618Ssbruno * * Neither the name of Cavium, Inc. nor the names of its 18325618Ssbruno * contributors may be used to endorse or promote products derived 19325618Ssbruno * from this software without specific prior written permission. 20325618Ssbruno * 21325618Ssbruno * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22325618Ssbruno * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23325618Ssbruno * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24325618Ssbruno * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25325618Ssbruno * OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26325618Ssbruno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27325618Ssbruno * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28325618Ssbruno * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29325618Ssbruno * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30325618Ssbruno * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31325618Ssbruno * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32325618Ssbruno */ 33325618Ssbruno/*$FreeBSD: stable/11/sys/dev/liquidio/base/lio_iq.h 325618 2017-11-09 19:52:56Z sbruno $*/ 34325618Ssbruno 35325618Ssbruno/* \file lio_iq.h 36325618Ssbruno * \brief Host Driver: Implementation of Octeon input queues. "Input" is 37325618Ssbruno * with respect to the Octeon device on the NIC. From this driver's 38325618Ssbruno * point of view they are egress queues. 39325618Ssbruno */ 40325618Ssbruno 41325618Ssbruno#ifndef __LIO_IQ_H__ 42325618Ssbruno#define __LIO_IQ_H__ 43325618Ssbruno 44325618Ssbruno#define LIO_IQ_SEND_OK 0 45325618Ssbruno#define LIO_IQ_SEND_STOP 1 46325618Ssbruno#define LIO_IQ_SEND_FAILED -1 47325618Ssbruno 48325618Ssbruno/*------------------------- INSTRUCTION QUEUE --------------------------*/ 49325618Ssbruno 50325618Ssbruno#define LIO_REQTYPE_NONE 0 51325618Ssbruno#define LIO_REQTYPE_NORESP_NET 1 52325618Ssbruno#define LIO_REQTYPE_NORESP_NET_SG 2 53325618Ssbruno#define LIO_REQTYPE_RESP_NET 3 54325618Ssbruno#define LIO_REQTYPE_SOFT_COMMAND 4 55325618Ssbruno 56325618Ssbruno/* 57325618Ssbruno * This structure is used by NIC driver to store information required 58325618Ssbruno * to free the mbuf when the packet has been fetched by Octeon. 59325618Ssbruno * Bytes offset below assume worst-case of a 64-bit system. 60325618Ssbruno */ 61325618Ssbrunostruct lio_mbuf_free_info { 62325618Ssbruno /* Pointer to mbuf. */ 63325618Ssbruno struct mbuf *mb; 64325618Ssbruno 65325618Ssbruno /* Pointer to gather list. */ 66325618Ssbruno struct lio_gather *g; 67325618Ssbruno 68325618Ssbruno bus_dmamap_t map; 69325618Ssbruno}; 70325618Ssbruno 71325618Ssbrunostruct lio_request_list { 72325618Ssbruno uint32_t reqtype; 73325618Ssbruno void *buf; 74325618Ssbruno bus_dmamap_t map; 75325618Ssbruno struct lio_mbuf_free_info finfo; 76325618Ssbruno}; 77325618Ssbruno 78325618Ssbruno/* Input Queue statistics. Each input queue has four stats fields. */ 79325618Ssbrunostruct lio_iq_stats { 80325618Ssbruno uint64_t instr_posted; /**< Instructions posted to this queue. */ 81325618Ssbruno uint64_t instr_processed; /**< Instructions processed in this queue. */ 82325618Ssbruno uint64_t instr_dropped; /**< Instructions that could not be processed */ 83325618Ssbruno uint64_t bytes_sent; /**< Bytes sent through this queue. */ 84325618Ssbruno uint64_t sgentry_sent; /**< Gather entries sent through this queue. */ 85325618Ssbruno uint64_t tx_done; /**< Num of packets sent to network. */ 86325618Ssbruno uint64_t tx_iq_busy; /**< Numof times this iq was found to be full. */ 87325618Ssbruno uint64_t tx_dropped; /**< Numof pkts dropped dueto xmitpath errors. */ 88325618Ssbruno uint64_t tx_tot_bytes; /**< Total count of bytes sento to network. */ 89325618Ssbruno uint64_t tx_gso; /* count of tso */ 90325618Ssbruno uint64_t tx_vxlan; /* tunnel */ 91325618Ssbruno uint64_t tx_dmamap_fail; 92325618Ssbruno uint64_t tx_restart; 93325618Ssbruno uint64_t mbuf_defrag_failed; 94325618Ssbruno}; 95325618Ssbruno 96325618Ssbruno/* 97325618Ssbruno * The instruction (input) queue. 98325618Ssbruno * The input queue is used to post raw (instruction) mode data or packet 99325618Ssbruno * data to Octeon device from the host. Each input queue for 100325618Ssbruno * a Octeon device has one such structure to represent it. 101325618Ssbruno */ 102325618Ssbrunostruct lio_instr_queue { 103325618Ssbruno struct octeon_device *oct_dev; 104325618Ssbruno 105325618Ssbruno /* A lock to protect access to the input ring. */ 106325618Ssbruno struct mtx lock; 107325618Ssbruno 108325618Ssbruno /* A lock to protect while enqueue to the input ring. */ 109325618Ssbruno struct mtx enq_lock; 110325618Ssbruno 111325618Ssbruno /* A lock to protect while posting on the ring. */ 112325618Ssbruno struct mtx post_lock; 113325618Ssbruno 114325618Ssbruno uint32_t pkt_in_done; 115325618Ssbruno 116325618Ssbruno /* A lock to protect access to the input ring. */ 117325618Ssbruno struct mtx iq_flush_running_lock; 118325618Ssbruno 119325618Ssbruno /* Flag that indicates if the queue uses 64 byte commands. */ 120325618Ssbruno uint32_t iqcmd_64B:1; 121325618Ssbruno 122325618Ssbruno /* Queue info. */ 123325618Ssbruno union octeon_txpciq txpciq; 124325618Ssbruno 125325618Ssbruno uint32_t rsvd:17; 126325618Ssbruno 127325618Ssbruno uint32_t status:8; 128325618Ssbruno 129325618Ssbruno /* Maximum no. of instructions in this queue. */ 130325618Ssbruno uint32_t max_count; 131325618Ssbruno 132325618Ssbruno /* Index in input ring where the driver should write the next packet */ 133325618Ssbruno uint32_t host_write_index; 134325618Ssbruno 135325618Ssbruno /* 136325618Ssbruno * Index in input ring where Octeon is expected to read the next 137325618Ssbruno * packet. 138325618Ssbruno */ 139325618Ssbruno uint32_t octeon_read_index; 140325618Ssbruno 141325618Ssbruno /* 142325618Ssbruno * This index aids in finding the window in the queue where Octeon 143325618Ssbruno * has read the commands. 144325618Ssbruno */ 145325618Ssbruno uint32_t flush_index; 146325618Ssbruno 147325618Ssbruno /* This field keeps track of the instructions pending in this queue. */ 148325618Ssbruno volatile int instr_pending; 149325618Ssbruno 150325618Ssbruno uint32_t reset_instr_cnt; 151325618Ssbruno 152325618Ssbruno /* Pointer to the Virtual Base addr of the input ring. */ 153325618Ssbruno uint8_t *base_addr; 154325618Ssbruno bus_dma_tag_t txtag; 155325618Ssbruno 156325618Ssbruno struct lio_request_list *request_list; 157325618Ssbruno 158325618Ssbruno struct buf_ring *br; 159325618Ssbruno 160325618Ssbruno /* Octeon doorbell register for the ring. */ 161325618Ssbruno uint32_t doorbell_reg; 162325618Ssbruno 163325618Ssbruno /* Octeon instruction count register for this ring. */ 164325618Ssbruno uint32_t inst_cnt_reg; 165325618Ssbruno 166325618Ssbruno /* Number of instructions pending to be posted to Octeon. */ 167325618Ssbruno uint32_t fill_cnt; 168325618Ssbruno 169325618Ssbruno /* The last time that the doorbell was rung. */ 170325618Ssbruno uint64_t last_db_time; 171325618Ssbruno 172325618Ssbruno /* 173325618Ssbruno * The doorbell timeout. If the doorbell was not rung for this time 174325618Ssbruno * and fill_cnt is non-zero, ring the doorbell again. 175325618Ssbruno */ 176325618Ssbruno uint32_t db_timeout; 177325618Ssbruno 178325618Ssbruno /* Statistics for this input queue. */ 179325618Ssbruno struct lio_iq_stats stats; 180325618Ssbruno 181325618Ssbruno /* DMA mapped base address of the input descriptor ring. */ 182325618Ssbruno uint64_t base_addr_dma; 183325618Ssbruno 184325618Ssbruno /* Application context */ 185325618Ssbruno void *app_ctx; 186325618Ssbruno 187325618Ssbruno /* network stack queue index */ 188325618Ssbruno int q_index; 189325618Ssbruno 190325618Ssbruno /* os ifidx associated with this queue */ 191325618Ssbruno int ifidx; 192325618Ssbruno 193325618Ssbruno}; 194325618Ssbruno 195325618Ssbruno/*---------------------- INSTRUCTION FORMAT ----------------------------*/ 196325618Ssbruno 197325618Ssbrunostruct lio_instr3_64B { 198325618Ssbruno /* Pointer where the input data is available. */ 199325618Ssbruno uint64_t dptr; 200325618Ssbruno 201325618Ssbruno /* Instruction Header. */ 202325618Ssbruno uint64_t ih3; 203325618Ssbruno 204325618Ssbruno /* Instruction Header. */ 205325618Ssbruno uint64_t pki_ih3; 206325618Ssbruno 207325618Ssbruno /* Input Request Header. */ 208325618Ssbruno uint64_t irh; 209325618Ssbruno 210325618Ssbruno /* opcode/subcode specific parameters */ 211325618Ssbruno uint64_t ossp[2]; 212325618Ssbruno 213325618Ssbruno /* Return Data Parameters */ 214325618Ssbruno uint64_t rdp; 215325618Ssbruno 216325618Ssbruno /* 217325618Ssbruno * Pointer where the response for a RAW mode packet will be written 218325618Ssbruno * by Octeon. 219325618Ssbruno */ 220325618Ssbruno uint64_t rptr; 221325618Ssbruno 222325618Ssbruno}; 223325618Ssbruno 224325618Ssbrunounion lio_instr_64B { 225325618Ssbruno struct lio_instr3_64B cmd3; 226325618Ssbruno}; 227325618Ssbruno 228325618Ssbruno/* The size of each buffer in soft command buffer pool */ 229325618Ssbruno#define LIO_SOFT_COMMAND_BUFFER_SIZE 2048 230325618Ssbruno 231325618Ssbrunostruct lio_soft_command { 232325618Ssbruno /* Soft command buffer info. */ 233325618Ssbruno struct lio_stailq_node node; 234325618Ssbruno uint64_t dma_addr; 235325618Ssbruno uint32_t size; 236325618Ssbruno 237325618Ssbruno /* Command and return status */ 238325618Ssbruno union lio_instr_64B cmd; 239325618Ssbruno 240325618Ssbruno#define COMPLETION_WORD_INIT 0xffffffffffffffffULL 241325618Ssbruno uint64_t *status_word; 242325618Ssbruno 243325618Ssbruno /* Data buffer info */ 244325618Ssbruno void *virtdptr; 245325618Ssbruno uint64_t dmadptr; 246325618Ssbruno uint32_t datasize; 247325618Ssbruno 248325618Ssbruno /* Return buffer info */ 249325618Ssbruno void *virtrptr; 250325618Ssbruno uint64_t dmarptr; 251325618Ssbruno uint32_t rdatasize; 252325618Ssbruno 253325618Ssbruno /* Context buffer info */ 254325618Ssbruno void *ctxptr; 255325618Ssbruno uint32_t ctxsize; 256325618Ssbruno 257325618Ssbruno /* Time out and callback */ 258325618Ssbruno int wait_time; 259325618Ssbruno int timeout; 260325618Ssbruno uint32_t iq_no; 261325618Ssbruno void (*callback) (struct octeon_device *, uint32_t, 262325618Ssbruno void *); 263325618Ssbruno void *callback_arg; 264325618Ssbruno}; 265325618Ssbruno 266325618Ssbruno/* Maximum number of buffers to allocate into soft command buffer pool */ 267325618Ssbruno#define LIO_MAX_SOFT_COMMAND_BUFFERS 256 268325618Ssbruno 269325618Ssbruno/* Head of a soft command buffer pool. */ 270325618Ssbrunostruct lio_sc_buffer_pool { 271325618Ssbruno /* List structure to add delete pending entries to */ 272325618Ssbruno struct lio_stailq_head head; 273325618Ssbruno 274325618Ssbruno /* A lock for this response list */ 275325618Ssbruno struct mtx lock; 276325618Ssbruno 277325618Ssbruno volatile uint32_t alloc_buf_count; 278325618Ssbruno}; 279325618Ssbruno 280325618Ssbruno#define LIO_INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ 281325618Ssbruno (((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count) 282325618Ssbruno 283325618Ssbrunoint lio_setup_sc_buffer_pool(struct octeon_device *oct); 284325618Ssbrunoint lio_free_sc_buffer_pool(struct octeon_device *oct); 285325618Ssbrunostruct lio_soft_command *lio_alloc_soft_command(struct octeon_device *oct, 286325618Ssbruno uint32_t datasize, 287325618Ssbruno uint32_t rdatasize, 288325618Ssbruno uint32_t ctxsize); 289325618Ssbrunovoid lio_free_soft_command(struct octeon_device *oct, 290325618Ssbruno struct lio_soft_command *sc); 291325618Ssbruno 292325618Ssbruno/* 293325618Ssbruno * lio_init_instr_queue() 294325618Ssbruno * @param octeon_dev - pointer to the octeon device structure. 295325618Ssbruno * @param txpciq - queue to be initialized (0 <= q_no <= 3). 296325618Ssbruno * 297325618Ssbruno * Called at driver init time for each input queue. iq_conf has the 298325618Ssbruno * configuration parameters for the queue. 299325618Ssbruno * 300325618Ssbruno * @return Success: 0 Failure: 1 301325618Ssbruno */ 302325618Ssbrunoint lio_init_instr_queue(struct octeon_device *octeon_dev, 303325618Ssbruno union octeon_txpciq txpciq, uint32_t num_descs); 304325618Ssbruno 305325618Ssbruno/* 306325618Ssbruno * lio_delete_instr_queue() 307325618Ssbruno * @param octeon_dev - pointer to the octeon device structure. 308325618Ssbruno * @param iq_no - queue to be deleted 309325618Ssbruno * 310325618Ssbruno * Called at driver unload time for each input queue. Deletes all 311325618Ssbruno * allocated resources for the input queue. 312325618Ssbruno * 313325618Ssbruno * @return Success: 0 Failure: 1 314325618Ssbruno */ 315325618Ssbrunoint lio_delete_instr_queue(struct octeon_device *octeon_dev, 316325618Ssbruno uint32_t iq_no); 317325618Ssbruno 318325618Ssbrunoint lio_wait_for_instr_fetch(struct octeon_device *oct); 319325618Ssbruno 320325618Ssbrunoint lio_process_iq_request_list(struct octeon_device *oct, 321325618Ssbruno struct lio_instr_queue *iq, 322325618Ssbruno uint32_t budget); 323325618Ssbruno 324325618Ssbrunoint lio_send_command(struct octeon_device *oct, uint32_t iq_no, 325325618Ssbruno uint32_t force_db, void *cmd, void *buf, 326325618Ssbruno uint32_t datasize, uint32_t reqtype); 327325618Ssbruno 328325618Ssbrunovoid lio_prepare_soft_command(struct octeon_device *oct, 329325618Ssbruno struct lio_soft_command *sc, 330325618Ssbruno uint8_t opcode, uint8_t subcode, 331325618Ssbruno uint32_t irh_ossp, uint64_t ossp0, 332325618Ssbruno uint64_t ossp1); 333325618Ssbruno 334325618Ssbrunoint lio_send_soft_command(struct octeon_device *oct, 335325618Ssbruno struct lio_soft_command *sc); 336325618Ssbruno 337325618Ssbrunoint lio_setup_iq(struct octeon_device *oct, int ifidx, 338325618Ssbruno int q_index, union octeon_txpciq iq_no, 339325618Ssbruno uint32_t num_descs); 340325618Ssbrunoint lio_flush_iq(struct octeon_device *oct, struct lio_instr_queue *iq, 341325618Ssbruno uint32_t budget); 342325618Ssbruno#endif /* __LIO_IQ_H__ */ 343