Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/liquidio/base/lio_iq.h
/* | |||||
* BSD LICENSE | |||||
* | |||||
* Copyright(c) 2017 Cavium, Inc.. All rights reserved. | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in | |||||
* the documentation and/or other materials provided with the | |||||
* distribution. | |||||
* * Neither the name of Cavium, Inc. nor the names of its | |||||
* contributors may be used to endorse or promote products derived | |||||
* from this software without specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||||
* OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
/*$FreeBSD$*/ | |||||
/* \file lio_iq.h | |||||
* \brief Host Driver: Implementation of Octeon input queues. "Input" is | |||||
* with respect to the Octeon device on the NIC. From this driver's | |||||
* point of view they are egress queues. | |||||
*/ | |||||
#ifndef __LIO_IQ_H__ | |||||
#define __LIO_IQ_H__ | |||||
#define LIO_IQ_SEND_OK 0 | |||||
#define LIO_IQ_SEND_STOP 1 | |||||
#define LIO_IQ_SEND_FAILED -1 | |||||
/*------------------------- INSTRUCTION QUEUE --------------------------*/ | |||||
#define LIO_REQTYPE_NONE 0 | |||||
#define LIO_REQTYPE_NORESP_NET 1 | |||||
#define LIO_REQTYPE_NORESP_NET_SG 2 | |||||
#define LIO_REQTYPE_RESP_NET 3 | |||||
#define LIO_REQTYPE_SOFT_COMMAND 4 | |||||
/* | |||||
* This structure is used by NIC driver to store information required | |||||
* to free the mbuf when the packet has been fetched by Octeon. | |||||
* Bytes offset below assume worst-case of a 64-bit system. | |||||
*/ | |||||
struct lio_mbuf_free_info { | |||||
/* Pointer to mbuf. */ | |||||
struct mbuf *mb; | |||||
/* Pointer to gather list. */ | |||||
struct lio_gather *g; | |||||
bus_dmamap_t map; | |||||
}; | |||||
struct lio_request_list { | |||||
uint32_t reqtype; | |||||
void *buf; | |||||
bus_dmamap_t map; | |||||
struct lio_mbuf_free_info finfo; | |||||
}; | |||||
/* Input Queue statistics. Each input queue has four stats fields. */ | |||||
struct lio_iq_stats { | |||||
uint64_t instr_posted; /**< Instructions posted to this queue. */ | |||||
uint64_t instr_processed; /**< Instructions processed in this queue. */ | |||||
uint64_t instr_dropped; /**< Instructions that could not be processed */ | |||||
uint64_t bytes_sent; /**< Bytes sent through this queue. */ | |||||
uint64_t sgentry_sent; /**< Gather entries sent through this queue. */ | |||||
uint64_t tx_done; /**< Num of packets sent to network. */ | |||||
uint64_t tx_iq_busy; /**< Numof times this iq was found to be full. */ | |||||
uint64_t tx_dropped; /**< Numof pkts dropped dueto xmitpath errors. */ | |||||
uint64_t tx_tot_bytes; /**< Total count of bytes sento to network. */ | |||||
uint64_t tx_gso; /* count of tso */ | |||||
uint64_t tx_vxlan; /* tunnel */ | |||||
uint64_t tx_dmamap_fail; | |||||
uint64_t tx_restart; | |||||
uint64_t mbuf_defrag_failed; | |||||
}; | |||||
/* | |||||
* The instruction (input) queue. | |||||
* The input queue is used to post raw (instruction) mode data or packet | |||||
* data to Octeon device from the host. Each input queue for | |||||
* a Octeon device has one such structure to represent it. | |||||
*/ | |||||
struct lio_instr_queue { | |||||
struct octeon_device *oct_dev; | |||||
/* A lock to protect access to the input ring. */ | |||||
struct mtx lock; | |||||
/* A lock to protect while enqueue to the input ring. */ | |||||
struct mtx enq_lock; | |||||
/* A lock to protect while posting on the ring. */ | |||||
struct mtx post_lock; | |||||
uint32_t pkt_in_done; | |||||
/* A lock to protect access to the input ring. */ | |||||
struct mtx iq_flush_running_lock; | |||||
/* Flag that indicates if the queue uses 64 byte commands. */ | |||||
uint32_t iqcmd_64B:1; | |||||
/* Queue info. */ | |||||
union octeon_txpciq txpciq; | |||||
uint32_t rsvd:17; | |||||
uint32_t status:8; | |||||
/* Maximum no. of instructions in this queue. */ | |||||
uint32_t max_count; | |||||
/* Index in input ring where the driver should write the next packet */ | |||||
uint32_t host_write_index; | |||||
/* | |||||
* Index in input ring where Octeon is expected to read the next | |||||
* packet. | |||||
*/ | |||||
uint32_t octeon_read_index; | |||||
/* | |||||
* This index aids in finding the window in the queue where Octeon | |||||
* has read the commands. | |||||
*/ | |||||
uint32_t flush_index; | |||||
/* This field keeps track of the instructions pending in this queue. */ | |||||
volatile int instr_pending; | |||||
uint32_t reset_instr_cnt; | |||||
/* Pointer to the Virtual Base addr of the input ring. */ | |||||
uint8_t *base_addr; | |||||
bus_dma_tag_t txtag; | |||||
struct lio_request_list *request_list; | |||||
struct buf_ring *br; | |||||
/* Octeon doorbell register for the ring. */ | |||||
uint32_t doorbell_reg; | |||||
/* Octeon instruction count register for this ring. */ | |||||
uint32_t inst_cnt_reg; | |||||
/* Number of instructions pending to be posted to Octeon. */ | |||||
uint32_t fill_cnt; | |||||
/* The last time that the doorbell was rung. */ | |||||
uint64_t last_db_time; | |||||
/* | |||||
* The doorbell timeout. If the doorbell was not rung for this time | |||||
* and fill_cnt is non-zero, ring the doorbell again. | |||||
*/ | |||||
uint32_t db_timeout; | |||||
/* Statistics for this input queue. */ | |||||
struct lio_iq_stats stats; | |||||
/* DMA mapped base address of the input descriptor ring. */ | |||||
uint64_t base_addr_dma; | |||||
/* Application context */ | |||||
void *app_ctx; | |||||
/* network stack queue index */ | |||||
int q_index; | |||||
/* os ifidx associated with this queue */ | |||||
int ifidx; | |||||
}; | |||||
/*---------------------- INSTRUCTION FORMAT ----------------------------*/ | |||||
struct lio_instr3_64B { | |||||
/* Pointer where the input data is available. */ | |||||
uint64_t dptr; | |||||
/* Instruction Header. */ | |||||
uint64_t ih3; | |||||
/* Instruction Header. */ | |||||
uint64_t pki_ih3; | |||||
/* Input Request Header. */ | |||||
uint64_t irh; | |||||
/* opcode/subcode specific parameters */ | |||||
uint64_t ossp[2]; | |||||
/* Return Data Parameters */ | |||||
uint64_t rdp; | |||||
/* | |||||
* Pointer where the response for a RAW mode packet will be written | |||||
* by Octeon. | |||||
*/ | |||||
uint64_t rptr; | |||||
}; | |||||
union lio_instr_64B { | |||||
struct lio_instr3_64B cmd3; | |||||
}; | |||||
/* The size of each buffer in soft command buffer pool */ | |||||
#define LIO_SOFT_COMMAND_BUFFER_SIZE 2048 | |||||
struct lio_soft_command { | |||||
/* Soft command buffer info. */ | |||||
struct lio_stailq_node node; | |||||
uint64_t dma_addr; | |||||
uint32_t size; | |||||
/* Command and return status */ | |||||
union lio_instr_64B cmd; | |||||
#define COMPLETION_WORD_INIT 0xffffffffffffffffULL | |||||
uint64_t *status_word; | |||||
/* Data buffer info */ | |||||
void *virtdptr; | |||||
uint64_t dmadptr; | |||||
uint32_t datasize; | |||||
/* Return buffer info */ | |||||
void *virtrptr; | |||||
uint64_t dmarptr; | |||||
uint32_t rdatasize; | |||||
/* Context buffer info */ | |||||
void *ctxptr; | |||||
uint32_t ctxsize; | |||||
/* Time out and callback */ | |||||
int wait_time; | |||||
int timeout; | |||||
uint32_t iq_no; | |||||
void (*callback) (struct octeon_device *, uint32_t, | |||||
void *); | |||||
void *callback_arg; | |||||
}; | |||||
/* Maximum number of buffers to allocate into soft command buffer pool */ | |||||
#define LIO_MAX_SOFT_COMMAND_BUFFERS 256 | |||||
/* Head of a soft command buffer pool. */ | |||||
struct lio_sc_buffer_pool { | |||||
/* List structure to add delete pending entries to */ | |||||
struct lio_stailq_head head; | |||||
/* A lock for this response list */ | |||||
struct mtx lock; | |||||
volatile uint32_t alloc_buf_count; | |||||
}; | |||||
#define LIO_INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ | |||||
(((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count) | |||||
int lio_setup_sc_buffer_pool(struct octeon_device *oct); | |||||
int lio_free_sc_buffer_pool(struct octeon_device *oct); | |||||
struct lio_soft_command *lio_alloc_soft_command(struct octeon_device *oct, | |||||
uint32_t datasize, | |||||
uint32_t rdatasize, | |||||
uint32_t ctxsize); | |||||
void lio_free_soft_command(struct octeon_device *oct, | |||||
struct lio_soft_command *sc); | |||||
/* | |||||
* lio_init_instr_queue() | |||||
* @param octeon_dev - pointer to the octeon device structure. | |||||
* @param txpciq - queue to be initialized (0 <= q_no <= 3). | |||||
* | |||||
* Called at driver init time for each input queue. iq_conf has the | |||||
* configuration parameters for the queue. | |||||
* | |||||
* @return Success: 0 Failure: 1 | |||||
*/ | |||||
int lio_init_instr_queue(struct octeon_device *octeon_dev, | |||||
union octeon_txpciq txpciq, uint32_t num_descs); | |||||
/* | |||||
* lio_delete_instr_queue() | |||||
* @param octeon_dev - pointer to the octeon device structure. | |||||
* @param iq_no - queue to be deleted | |||||
* | |||||
* Called at driver unload time for each input queue. Deletes all | |||||
* allocated resources for the input queue. | |||||
* | |||||
* @return Success: 0 Failure: 1 | |||||
*/ | |||||
int lio_delete_instr_queue(struct octeon_device *octeon_dev, | |||||
uint32_t iq_no); | |||||
int lio_wait_for_instr_fetch(struct octeon_device *oct); | |||||
int lio_process_iq_request_list(struct octeon_device *oct, | |||||
struct lio_instr_queue *iq, | |||||
uint32_t budget); | |||||
int lio_send_command(struct octeon_device *oct, uint32_t iq_no, | |||||
uint32_t force_db, void *cmd, void *buf, | |||||
uint32_t datasize, uint32_t reqtype); | |||||
void lio_prepare_soft_command(struct octeon_device *oct, | |||||
struct lio_soft_command *sc, | |||||
uint8_t opcode, uint8_t subcode, | |||||
uint32_t irh_ossp, uint64_t ossp0, | |||||
uint64_t ossp1); | |||||
int lio_send_soft_command(struct octeon_device *oct, | |||||
struct lio_soft_command *sc); | |||||
int lio_setup_iq(struct octeon_device *oct, int ifidx, | |||||
int q_index, union octeon_txpciq iq_no, | |||||
uint32_t num_descs); | |||||
int lio_flush_iq(struct octeon_device *oct, struct lio_instr_queue *iq, | |||||
uint32_t budget); | |||||
#endif /* __LIO_IQ_H__ */ |