1*f173c2b7SSean Bruno /* 2*f173c2b7SSean Bruno * BSD LICENSE 3*f173c2b7SSean Bruno * 4*f173c2b7SSean Bruno * Copyright(c) 2017 Cavium, Inc.. All rights reserved. 5*f173c2b7SSean Bruno * All rights reserved. 6*f173c2b7SSean Bruno * 7*f173c2b7SSean Bruno * Redistribution and use in source and binary forms, with or without 8*f173c2b7SSean Bruno * modification, are permitted provided that the following conditions 9*f173c2b7SSean Bruno * are met: 10*f173c2b7SSean Bruno * 11*f173c2b7SSean Bruno * * Redistributions of source code must retain the above copyright 12*f173c2b7SSean Bruno * notice, this list of conditions and the following disclaimer. 13*f173c2b7SSean Bruno * * Redistributions in binary form must reproduce the above copyright 14*f173c2b7SSean Bruno * notice, this list of conditions and the following disclaimer in 15*f173c2b7SSean Bruno * the documentation and/or other materials provided with the 16*f173c2b7SSean Bruno * distribution. 17*f173c2b7SSean Bruno * * Neither the name of Cavium, Inc. nor the names of its 18*f173c2b7SSean Bruno * contributors may be used to endorse or promote products derived 19*f173c2b7SSean Bruno * from this software without specific prior written permission. 20*f173c2b7SSean Bruno * 21*f173c2b7SSean Bruno * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*f173c2b7SSean Bruno * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*f173c2b7SSean Bruno * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24*f173c2b7SSean Bruno * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25*f173c2b7SSean Bruno * OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26*f173c2b7SSean Bruno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27*f173c2b7SSean Bruno * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28*f173c2b7SSean Bruno * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29*f173c2b7SSean Bruno * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30*f173c2b7SSean Bruno * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31*f173c2b7SSean Bruno * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32*f173c2b7SSean Bruno */ 33*f173c2b7SSean Bruno 34*f173c2b7SSean Bruno /* \file lio_iq.h 35*f173c2b7SSean Bruno * \brief Host Driver: Implementation of Octeon input queues. "Input" is 36*f173c2b7SSean Bruno * with respect to the Octeon device on the NIC. From this driver's 37*f173c2b7SSean Bruno * point of view they are egress queues. 38*f173c2b7SSean Bruno */ 39*f173c2b7SSean Bruno 40*f173c2b7SSean Bruno #ifndef __LIO_IQ_H__ 41*f173c2b7SSean Bruno #define __LIO_IQ_H__ 42*f173c2b7SSean Bruno 43*f173c2b7SSean Bruno #define LIO_IQ_SEND_OK 0 44*f173c2b7SSean Bruno #define LIO_IQ_SEND_STOP 1 45*f173c2b7SSean Bruno #define LIO_IQ_SEND_FAILED -1 46*f173c2b7SSean Bruno 47*f173c2b7SSean Bruno /*------------------------- INSTRUCTION QUEUE --------------------------*/ 48*f173c2b7SSean Bruno 49*f173c2b7SSean Bruno #define LIO_REQTYPE_NONE 0 50*f173c2b7SSean Bruno #define LIO_REQTYPE_NORESP_NET 1 51*f173c2b7SSean Bruno #define LIO_REQTYPE_NORESP_NET_SG 2 52*f173c2b7SSean Bruno #define LIO_REQTYPE_RESP_NET 3 53*f173c2b7SSean Bruno #define LIO_REQTYPE_SOFT_COMMAND 4 54*f173c2b7SSean Bruno 55*f173c2b7SSean Bruno /* 56*f173c2b7SSean Bruno * This structure is used by NIC driver to store information required 57*f173c2b7SSean Bruno * to free the mbuf when the packet has been fetched by Octeon. 58*f173c2b7SSean Bruno * Bytes offset below assume worst-case of a 64-bit system. 59*f173c2b7SSean Bruno */ 60*f173c2b7SSean Bruno struct lio_mbuf_free_info { 61*f173c2b7SSean Bruno /* Pointer to mbuf. */ 62*f173c2b7SSean Bruno struct mbuf *mb; 63*f173c2b7SSean Bruno 64*f173c2b7SSean Bruno /* Pointer to gather list. */ 65*f173c2b7SSean Bruno struct lio_gather *g; 66*f173c2b7SSean Bruno 67*f173c2b7SSean Bruno bus_dmamap_t map; 68*f173c2b7SSean Bruno }; 69*f173c2b7SSean Bruno 70*f173c2b7SSean Bruno struct lio_request_list { 71*f173c2b7SSean Bruno uint32_t reqtype; 72*f173c2b7SSean Bruno void *buf; 73*f173c2b7SSean Bruno bus_dmamap_t map; 74*f173c2b7SSean Bruno struct lio_mbuf_free_info finfo; 75*f173c2b7SSean Bruno }; 76*f173c2b7SSean Bruno 77*f173c2b7SSean Bruno /* Input Queue statistics. Each input queue has four stats fields. */ 78*f173c2b7SSean Bruno struct lio_iq_stats { 79*f173c2b7SSean Bruno uint64_t instr_posted; /**< Instructions posted to this queue. */ 80*f173c2b7SSean Bruno uint64_t instr_processed; /**< Instructions processed in this queue. */ 81*f173c2b7SSean Bruno uint64_t instr_dropped; /**< Instructions that could not be processed */ 82*f173c2b7SSean Bruno uint64_t bytes_sent; /**< Bytes sent through this queue. */ 83*f173c2b7SSean Bruno uint64_t sgentry_sent; /**< Gather entries sent through this queue. */ 84*f173c2b7SSean Bruno uint64_t tx_done; /**< Num of packets sent to network. */ 85*f173c2b7SSean Bruno uint64_t tx_iq_busy; /**< Numof times this iq was found to be full. */ 86*f173c2b7SSean Bruno uint64_t tx_dropped; /**< Numof pkts dropped dueto xmitpath errors. */ 87*f173c2b7SSean Bruno uint64_t tx_tot_bytes; /**< Total count of bytes sento to network. */ 88*f173c2b7SSean Bruno uint64_t tx_gso; /* count of tso */ 89*f173c2b7SSean Bruno uint64_t tx_vxlan; /* tunnel */ 90*f173c2b7SSean Bruno uint64_t tx_dmamap_fail; 91*f173c2b7SSean Bruno uint64_t tx_restart; 92*f173c2b7SSean Bruno uint64_t mbuf_defrag_failed; 93*f173c2b7SSean Bruno }; 94*f173c2b7SSean Bruno 95*f173c2b7SSean Bruno /* 96*f173c2b7SSean Bruno * The instruction (input) queue. 97*f173c2b7SSean Bruno * The input queue is used to post raw (instruction) mode data or packet 98*f173c2b7SSean Bruno * data to Octeon device from the host. Each input queue for 99*f173c2b7SSean Bruno * a Octeon device has one such structure to represent it. 100*f173c2b7SSean Bruno */ 101*f173c2b7SSean Bruno struct lio_instr_queue { 102*f173c2b7SSean Bruno struct octeon_device *oct_dev; 103*f173c2b7SSean Bruno 104*f173c2b7SSean Bruno /* A lock to protect access to the input ring. */ 105*f173c2b7SSean Bruno struct mtx lock; 106*f173c2b7SSean Bruno 107*f173c2b7SSean Bruno /* A lock to protect while enqueue to the input ring. */ 108*f173c2b7SSean Bruno struct mtx enq_lock; 109*f173c2b7SSean Bruno 110*f173c2b7SSean Bruno /* A lock to protect while posting on the ring. */ 111*f173c2b7SSean Bruno struct mtx post_lock; 112*f173c2b7SSean Bruno 113*f173c2b7SSean Bruno uint32_t pkt_in_done; 114*f173c2b7SSean Bruno 115*f173c2b7SSean Bruno /* A lock to protect access to the input ring. */ 116*f173c2b7SSean Bruno struct mtx iq_flush_running_lock; 117*f173c2b7SSean Bruno 118*f173c2b7SSean Bruno /* Flag that indicates if the queue uses 64 byte commands. */ 119*f173c2b7SSean Bruno uint32_t iqcmd_64B:1; 120*f173c2b7SSean Bruno 121*f173c2b7SSean Bruno /* Queue info. */ 122*f173c2b7SSean Bruno union octeon_txpciq txpciq; 123*f173c2b7SSean Bruno 124*f173c2b7SSean Bruno uint32_t rsvd:17; 125*f173c2b7SSean Bruno 126*f173c2b7SSean Bruno uint32_t status:8; 127*f173c2b7SSean Bruno 128*f173c2b7SSean Bruno /* Maximum no. of instructions in this queue. */ 129*f173c2b7SSean Bruno uint32_t max_count; 130*f173c2b7SSean Bruno 131*f173c2b7SSean Bruno /* Index in input ring where the driver should write the next packet */ 132*f173c2b7SSean Bruno uint32_t host_write_index; 133*f173c2b7SSean Bruno 134*f173c2b7SSean Bruno /* 135*f173c2b7SSean Bruno * Index in input ring where Octeon is expected to read the next 136*f173c2b7SSean Bruno * packet. 137*f173c2b7SSean Bruno */ 138*f173c2b7SSean Bruno uint32_t octeon_read_index; 139*f173c2b7SSean Bruno 140*f173c2b7SSean Bruno /* 141*f173c2b7SSean Bruno * This index aids in finding the window in the queue where Octeon 142*f173c2b7SSean Bruno * has read the commands. 143*f173c2b7SSean Bruno */ 144*f173c2b7SSean Bruno uint32_t flush_index; 145*f173c2b7SSean Bruno 146*f173c2b7SSean Bruno /* This field keeps track of the instructions pending in this queue. */ 147*f173c2b7SSean Bruno volatile int instr_pending; 148*f173c2b7SSean Bruno 149*f173c2b7SSean Bruno uint32_t reset_instr_cnt; 150*f173c2b7SSean Bruno 151*f173c2b7SSean Bruno /* Pointer to the Virtual Base addr of the input ring. */ 152*f173c2b7SSean Bruno uint8_t *base_addr; 153*f173c2b7SSean Bruno bus_dma_tag_t txtag; 154*f173c2b7SSean Bruno 155*f173c2b7SSean Bruno struct lio_request_list *request_list; 156*f173c2b7SSean Bruno 157*f173c2b7SSean Bruno struct buf_ring *br; 158*f173c2b7SSean Bruno 159*f173c2b7SSean Bruno /* Octeon doorbell register for the ring. */ 160*f173c2b7SSean Bruno uint32_t doorbell_reg; 161*f173c2b7SSean Bruno 162*f173c2b7SSean Bruno /* Octeon instruction count register for this ring. */ 163*f173c2b7SSean Bruno uint32_t inst_cnt_reg; 164*f173c2b7SSean Bruno 165*f173c2b7SSean Bruno /* Number of instructions pending to be posted to Octeon. */ 166*f173c2b7SSean Bruno uint32_t fill_cnt; 167*f173c2b7SSean Bruno 168*f173c2b7SSean Bruno /* The last time that the doorbell was rung. */ 169*f173c2b7SSean Bruno uint64_t last_db_time; 170*f173c2b7SSean Bruno 171*f173c2b7SSean Bruno /* 172*f173c2b7SSean Bruno * The doorbell timeout. If the doorbell was not rung for this time 173*f173c2b7SSean Bruno * and fill_cnt is non-zero, ring the doorbell again. 174*f173c2b7SSean Bruno */ 175*f173c2b7SSean Bruno uint32_t db_timeout; 176*f173c2b7SSean Bruno 177*f173c2b7SSean Bruno /* Statistics for this input queue. */ 178*f173c2b7SSean Bruno struct lio_iq_stats stats; 179*f173c2b7SSean Bruno 180*f173c2b7SSean Bruno /* DMA mapped base address of the input descriptor ring. */ 181*f173c2b7SSean Bruno uint64_t base_addr_dma; 182*f173c2b7SSean Bruno 183*f173c2b7SSean Bruno /* Application context */ 184*f173c2b7SSean Bruno void *app_ctx; 185*f173c2b7SSean Bruno 186*f173c2b7SSean Bruno /* network stack queue index */ 187*f173c2b7SSean Bruno int q_index; 188*f173c2b7SSean Bruno 189*f173c2b7SSean Bruno /* os ifidx associated with this queue */ 190*f173c2b7SSean Bruno int ifidx; 191*f173c2b7SSean Bruno 192*f173c2b7SSean Bruno }; 193*f173c2b7SSean Bruno 194*f173c2b7SSean Bruno /*---------------------- INSTRUCTION FORMAT ----------------------------*/ 195*f173c2b7SSean Bruno 196*f173c2b7SSean Bruno struct lio_instr3_64B { 197*f173c2b7SSean Bruno /* Pointer where the input data is available. */ 198*f173c2b7SSean Bruno uint64_t dptr; 199*f173c2b7SSean Bruno 200*f173c2b7SSean Bruno /* Instruction Header. */ 201*f173c2b7SSean Bruno uint64_t ih3; 202*f173c2b7SSean Bruno 203*f173c2b7SSean Bruno /* Instruction Header. */ 204*f173c2b7SSean Bruno uint64_t pki_ih3; 205*f173c2b7SSean Bruno 206*f173c2b7SSean Bruno /* Input Request Header. */ 207*f173c2b7SSean Bruno uint64_t irh; 208*f173c2b7SSean Bruno 209*f173c2b7SSean Bruno /* opcode/subcode specific parameters */ 210*f173c2b7SSean Bruno uint64_t ossp[2]; 211*f173c2b7SSean Bruno 212*f173c2b7SSean Bruno /* Return Data Parameters */ 213*f173c2b7SSean Bruno uint64_t rdp; 214*f173c2b7SSean Bruno 215*f173c2b7SSean Bruno /* 216*f173c2b7SSean Bruno * Pointer where the response for a RAW mode packet will be written 217*f173c2b7SSean Bruno * by Octeon. 218*f173c2b7SSean Bruno */ 219*f173c2b7SSean Bruno uint64_t rptr; 220*f173c2b7SSean Bruno 221*f173c2b7SSean Bruno }; 222*f173c2b7SSean Bruno 223*f173c2b7SSean Bruno union lio_instr_64B { 224*f173c2b7SSean Bruno struct lio_instr3_64B cmd3; 225*f173c2b7SSean Bruno }; 226*f173c2b7SSean Bruno 227*f173c2b7SSean Bruno /* The size of each buffer in soft command buffer pool */ 228*f173c2b7SSean Bruno #define LIO_SOFT_COMMAND_BUFFER_SIZE 2048 229*f173c2b7SSean Bruno 230*f173c2b7SSean Bruno struct lio_soft_command { 231*f173c2b7SSean Bruno /* Soft command buffer info. */ 232*f173c2b7SSean Bruno struct lio_stailq_node node; 233*f173c2b7SSean Bruno uint64_t dma_addr; 234*f173c2b7SSean Bruno uint32_t size; 235*f173c2b7SSean Bruno 236*f173c2b7SSean Bruno /* Command and return status */ 237*f173c2b7SSean Bruno union lio_instr_64B cmd; 238*f173c2b7SSean Bruno 239*f173c2b7SSean Bruno #define COMPLETION_WORD_INIT 0xffffffffffffffffULL 240*f173c2b7SSean Bruno uint64_t *status_word; 241*f173c2b7SSean Bruno 242*f173c2b7SSean Bruno /* Data buffer info */ 243*f173c2b7SSean Bruno void *virtdptr; 244*f173c2b7SSean Bruno uint64_t dmadptr; 245*f173c2b7SSean Bruno uint32_t datasize; 246*f173c2b7SSean Bruno 247*f173c2b7SSean Bruno /* Return buffer info */ 248*f173c2b7SSean Bruno void *virtrptr; 249*f173c2b7SSean Bruno uint64_t dmarptr; 250*f173c2b7SSean Bruno uint32_t rdatasize; 251*f173c2b7SSean Bruno 252*f173c2b7SSean Bruno /* Context buffer info */ 253*f173c2b7SSean Bruno void *ctxptr; 254*f173c2b7SSean Bruno uint32_t ctxsize; 255*f173c2b7SSean Bruno 256*f173c2b7SSean Bruno /* Time out and callback */ 257*f173c2b7SSean Bruno int wait_time; 258*f173c2b7SSean Bruno int timeout; 259*f173c2b7SSean Bruno uint32_t iq_no; 260*f173c2b7SSean Bruno void (*callback) (struct octeon_device *, uint32_t, 261*f173c2b7SSean Bruno void *); 262*f173c2b7SSean Bruno void *callback_arg; 263*f173c2b7SSean Bruno }; 264*f173c2b7SSean Bruno 265*f173c2b7SSean Bruno /* Maximum number of buffers to allocate into soft command buffer pool */ 266*f173c2b7SSean Bruno #define LIO_MAX_SOFT_COMMAND_BUFFERS 256 267*f173c2b7SSean Bruno 268*f173c2b7SSean Bruno /* Head of a soft command buffer pool. */ 269*f173c2b7SSean Bruno struct lio_sc_buffer_pool { 270*f173c2b7SSean Bruno /* List structure to add delete pending entries to */ 271*f173c2b7SSean Bruno struct lio_stailq_head head; 272*f173c2b7SSean Bruno 273*f173c2b7SSean Bruno /* A lock for this response list */ 274*f173c2b7SSean Bruno struct mtx lock; 275*f173c2b7SSean Bruno 276*f173c2b7SSean Bruno volatile uint32_t alloc_buf_count; 277*f173c2b7SSean Bruno }; 278*f173c2b7SSean Bruno 279*f173c2b7SSean Bruno #define LIO_INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ 280*f173c2b7SSean Bruno (((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count) 281*f173c2b7SSean Bruno 282*f173c2b7SSean Bruno int lio_setup_sc_buffer_pool(struct octeon_device *oct); 283*f173c2b7SSean Bruno int lio_free_sc_buffer_pool(struct octeon_device *oct); 284*f173c2b7SSean Bruno struct lio_soft_command *lio_alloc_soft_command(struct octeon_device *oct, 285*f173c2b7SSean Bruno uint32_t datasize, 286*f173c2b7SSean Bruno uint32_t rdatasize, 287*f173c2b7SSean Bruno uint32_t ctxsize); 288*f173c2b7SSean Bruno void lio_free_soft_command(struct octeon_device *oct, 289*f173c2b7SSean Bruno struct lio_soft_command *sc); 290*f173c2b7SSean Bruno 291*f173c2b7SSean Bruno /* 292*f173c2b7SSean Bruno * lio_init_instr_queue() 293*f173c2b7SSean Bruno * @param octeon_dev - pointer to the octeon device structure. 294*f173c2b7SSean Bruno * @param txpciq - queue to be initialized (0 <= q_no <= 3). 295*f173c2b7SSean Bruno * 296*f173c2b7SSean Bruno * Called at driver init time for each input queue. iq_conf has the 297*f173c2b7SSean Bruno * configuration parameters for the queue. 298*f173c2b7SSean Bruno * 299*f173c2b7SSean Bruno * @return Success: 0 Failure: 1 300*f173c2b7SSean Bruno */ 301*f173c2b7SSean Bruno int lio_init_instr_queue(struct octeon_device *octeon_dev, 302*f173c2b7SSean Bruno union octeon_txpciq txpciq, uint32_t num_descs); 303*f173c2b7SSean Bruno 304*f173c2b7SSean Bruno /* 305*f173c2b7SSean Bruno * lio_delete_instr_queue() 306*f173c2b7SSean Bruno * @param octeon_dev - pointer to the octeon device structure. 307*f173c2b7SSean Bruno * @param iq_no - queue to be deleted 308*f173c2b7SSean Bruno * 309*f173c2b7SSean Bruno * Called at driver unload time for each input queue. Deletes all 310*f173c2b7SSean Bruno * allocated resources for the input queue. 311*f173c2b7SSean Bruno * 312*f173c2b7SSean Bruno * @return Success: 0 Failure: 1 313*f173c2b7SSean Bruno */ 314*f173c2b7SSean Bruno int lio_delete_instr_queue(struct octeon_device *octeon_dev, 315*f173c2b7SSean Bruno uint32_t iq_no); 316*f173c2b7SSean Bruno 317*f173c2b7SSean Bruno int lio_wait_for_instr_fetch(struct octeon_device *oct); 318*f173c2b7SSean Bruno 319*f173c2b7SSean Bruno int lio_process_iq_request_list(struct octeon_device *oct, 320*f173c2b7SSean Bruno struct lio_instr_queue *iq, 321*f173c2b7SSean Bruno uint32_t budget); 322*f173c2b7SSean Bruno 323*f173c2b7SSean Bruno int lio_send_command(struct octeon_device *oct, uint32_t iq_no, 324*f173c2b7SSean Bruno uint32_t force_db, void *cmd, void *buf, 325*f173c2b7SSean Bruno uint32_t datasize, uint32_t reqtype); 326*f173c2b7SSean Bruno 327*f173c2b7SSean Bruno void lio_prepare_soft_command(struct octeon_device *oct, 328*f173c2b7SSean Bruno struct lio_soft_command *sc, 329*f173c2b7SSean Bruno uint8_t opcode, uint8_t subcode, 330*f173c2b7SSean Bruno uint32_t irh_ossp, uint64_t ossp0, 331*f173c2b7SSean Bruno uint64_t ossp1); 332*f173c2b7SSean Bruno 333*f173c2b7SSean Bruno int lio_send_soft_command(struct octeon_device *oct, 334*f173c2b7SSean Bruno struct lio_soft_command *sc); 335*f173c2b7SSean Bruno 336*f173c2b7SSean Bruno int lio_setup_iq(struct octeon_device *oct, int ifidx, 337*f173c2b7SSean Bruno int q_index, union octeon_txpciq iq_no, 338*f173c2b7SSean Bruno uint32_t num_descs); 339*f173c2b7SSean Bruno int lio_flush_iq(struct octeon_device *oct, struct lio_instr_queue *iq, 340*f173c2b7SSean Bruno uint32_t budget); 341*f173c2b7SSean Bruno #endif /* __LIO_IQ_H__ */ 342