The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/liquidio/base/lio_droq.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *   BSD LICENSE
    3  *
    4  *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
    5  *   All rights reserved.
    6  *
    7  *   Redistribution and use in source and binary forms, with or without
    8  *   modification, are permitted provided that the following conditions
    9  *   are met:
   10  *
   11  *     * Redistributions of source code must retain the above copyright
   12  *       notice, this list of conditions and the following disclaimer.
   13  *     * Redistributions in binary form must reproduce the above copyright
   14  *       notice, this list of conditions and the following disclaimer in
   15  *       the documentation and/or other materials provided with the
   16  *       distribution.
   17  *     * Neither the name of Cavium, Inc. nor the names of its
   18  *       contributors may be used to endorse or promote products derived
   19  *       from this software without specific prior written permission.
   20  *
   21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   25  *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 /*$FreeBSD$*/
   34 
   35 /*   \file  lio_droq.h
   36  *   \brief Implementation of Octeon Output queues. "Output" is with
   37  *   respect to the Octeon device on the NIC. From this driver's point of
   38  *   view they are ingress queues.
   39  */
   40 
   41 #ifndef __LIO_DROQ_H__
   42 #define __LIO_DROQ_H__
   43 
   44 /*
   45  *  Octeon descriptor format.
   46  *  The descriptor ring is made of descriptors which have 2 64-bit values:
   47  *  -# Physical (bus) address of the data buffer.
   48  *  -# Physical (bus) address of a lio_droq_info structure.
   49  *  The Octeon device DMA's incoming packets and its information at the address
   50  *  given by these descriptor fields.
   51  */
   52 struct lio_droq_desc {
   53         /* The buffer pointer */
   54         uint64_t        buffer_ptr;
   55 
   56         /* The Info pointer */
   57         uint64_t        info_ptr;
   58 };
   59 
   60 #define LIO_DROQ_DESC_SIZE      (sizeof(struct lio_droq_desc))
   61 
   62 /*
   63  *  Information about packet DMA'ed by Octeon.
   64  *  The format of the information available at Info Pointer after Octeon
   65  *  has posted a packet. Not all descriptors have valid information. Only
   66  *  the Info field of the first descriptor for a packet has information
   67  *  about the packet.
   68  */
   69 struct lio_droq_info {
   70         /* The Length of the packet. */
   71         uint64_t        length;
   72 
   73         /* The Output Receive Header. */
   74         union           octeon_rh rh;
   75 
   76 };
   77 
   78 #define LIO_DROQ_INFO_SIZE      (sizeof(struct lio_droq_info))
   79 
   80 /*
   81  *  Pointer to data buffer.
   82  *  Driver keeps a pointer to the data buffer that it made available to
   83  *  the Octeon device. Since the descriptor ring keeps physical (bus)
   84  *  addresses, this field is required for the driver to keep track of
   85  *  the virtual address pointers.
   86  */
   87 struct lio_recv_buffer {
   88         /* Packet buffer, including metadata. */
   89         void    *buffer;
   90 
   91         /* Data in the packet buffer.  */
   92         uint8_t *data;
   93 };
   94 
   95 #define LIO_DROQ_RECVBUF_SIZE   (sizeof(struct lio_recv_buffer))
   96 
   97 /* Output Queue statistics. Each output queue has four stats fields. */
   98 struct lio_droq_stats {
   99         /* Number of packets received in this queue. */
  100         uint64_t        pkts_received;
  101 
  102         /* Bytes received by this queue. */
  103         uint64_t        bytes_received;
  104 
  105         /* Packets dropped due to no dispatch function. */
  106         uint64_t        dropped_nodispatch;
  107 
  108         /* Packets dropped due to no memory available. */
  109         uint64_t        dropped_nomem;
  110 
  111         /* Packets dropped due to large number of pkts to process. */
  112         uint64_t        dropped_toomany;
  113 
  114         /* Number of packets  sent to stack from this queue. */
  115         uint64_t        rx_pkts_received;
  116 
  117         /* Number of Bytes sent to stack from this queue. */
  118         uint64_t        rx_bytes_received;
  119 
  120         /* Num of Packets dropped due to receive path failures. */
  121         uint64_t        rx_dropped;
  122 
  123         uint64_t        rx_vxlan;
  124 
  125         /* Num of failures of lio_recv_buffer_alloc() */
  126         uint64_t        rx_alloc_failure;
  127 
  128 };
  129 
  130 /*
  131  * The maximum number of buffers that can be dispatched from the
  132  * output/dma queue. Set to 64 assuming 1K buffers in DROQ and the fact that
  133  * max packet size from DROQ is 64K.
  134  */
  135 #define LIO_MAX_RECV_BUFS       64
  136 
  137 /*
  138  *  Receive Packet format used when dispatching output queue packets
  139  *  with non-raw opcodes.
  140  *  The received packet will be sent to the upper layers using this
  141  *  structure which is passed as a parameter to the dispatch function
  142  */
  143 struct lio_recv_pkt {
  144         /* Number of buffers in this received packet */
  145         uint16_t        buffer_count;
  146 
  147         /* Id of the device that is sending the packet up */
  148         uint16_t        octeon_id;
  149 
  150         /* Length of data in the packet buffer */
  151         uint32_t        length;
  152 
  153         /* The receive header */
  154         union octeon_rh rh;
  155 
  156         /* Pointer to the OS-specific packet buffer */
  157         struct mbuf     *buffer_ptr[LIO_MAX_RECV_BUFS];
  158 
  159         /* Size of the buffers pointed to by ptr's in buffer_ptr */
  160         uint32_t        buffer_size[LIO_MAX_RECV_BUFS];
  161 };
  162 
  163 #define LIO_RECV_PKT_SIZE       (sizeof(struct lio_recv_pkt))
  164 
  165 /*
  166  *  The first parameter of a dispatch function.
  167  *  For a raw mode opcode, the driver dispatches with the device
  168  *  pointer in this structure.
  169  *  For non-raw mode opcode, the driver dispatches the recv_pkt
  170  *  created to contain the buffers with data received from Octeon.
  171  *  ---------------------
  172  *  |     *recv_pkt ----|---
  173  *  |-------------------|   |
  174  *  | 0 or more bytes   |   |
  175  *  | reserved by driver|   |
  176  *  |-------------------|<-/
  177  *  | lio_recv_pkt   |
  178  *  |                   |
  179  *  |___________________|
  180  */
  181 struct lio_recv_info {
  182         void                    *rsvd;
  183         struct lio_recv_pkt     *recv_pkt;
  184 };
  185 
  186 #define LIO_RECV_INFO_SIZE      (sizeof(struct lio_recv_info))
  187 
  188 /*
  189  *  Allocate a recv_info structure. The recv_pkt pointer in the recv_info
  190  *  structure is filled in before this call returns.
  191  *  @param extra_bytes - extra bytes to be allocated at the end of the recv info
  192  *                       structure.
  193  *  @return - pointer to a newly allocated recv_info structure.
  194  */
  195 static inline struct lio_recv_info *
  196 lio_alloc_recv_info(int extra_bytes)
  197 {
  198         struct lio_recv_info    *recv_info;
  199         uint8_t                 *buf;
  200 
  201         buf = malloc(LIO_RECV_PKT_SIZE + LIO_RECV_INFO_SIZE +
  202                      extra_bytes, M_DEVBUF, M_NOWAIT | M_ZERO);
  203         if (buf == NULL)
  204                 return (NULL);
  205 
  206         recv_info = (struct lio_recv_info *)buf;
  207         recv_info->recv_pkt = (struct lio_recv_pkt *)(buf + LIO_RECV_INFO_SIZE);
  208         recv_info->rsvd = NULL;
  209         if (extra_bytes)
  210                 recv_info->rsvd = buf + LIO_RECV_INFO_SIZE + LIO_RECV_PKT_SIZE;
  211 
  212         return (recv_info);
  213 }
  214 
  215 /*
  216  *  Free a recv_info structure.
  217  *  @param recv_info - Pointer to receive_info to be freed
  218  */
  219 static inline void
  220 lio_free_recv_info(struct lio_recv_info *recv_info)
  221 {
  222 
  223         free(recv_info, M_DEVBUF);
  224 }
  225 
  226 typedef int     (*lio_dispatch_fn_t)(struct lio_recv_info *, void *);
  227 
  228 /*
  229  * Used by NIC module to register packet handler and to get device
  230  * information for each octeon device.
  231  */
  232 struct lio_droq_ops {
  233         /*
  234          *  This registered function will be called by the driver with
  235          *  the pointer to buffer from droq and length of
  236          *  data in the buffer. The receive header gives the port
  237          *  number to the caller.  Function pointer is set by caller.
  238          */
  239         void            (*fptr) (void *, uint32_t, union octeon_rh *, void  *,
  240                                  void *);
  241         void            *farg;
  242 
  243         /*
  244          *  Flag indicating if the DROQ handler should drop packets that
  245          *  it cannot handle in one iteration. Set by caller.
  246          */
  247         uint32_t        drop_on_max;
  248 };
  249 
  250 /*
  251  * The Descriptor Ring Output Queue structure.
  252  *  This structure has all the information required to implement a
  253  *  Octeon DROQ.
  254  */
  255 struct lio_droq {
  256         /* A lock to protect access to this ring. */
  257         struct mtx              lock;
  258 
  259         uint32_t                q_no;
  260 
  261         uint32_t                pkt_count;
  262 
  263         struct lio_droq_ops     ops;
  264 
  265         struct octeon_device    *oct_dev;
  266 
  267         /* The 8B aligned descriptor ring starts at this address. */
  268         struct lio_droq_desc    *desc_ring;
  269 
  270         /* Index in the ring where the driver should read the next packet */
  271         uint32_t                read_idx;
  272 
  273         /*
  274          * Index in the ring where the driver will refill the descriptor's
  275          * buffer
  276          */
  277         uint32_t                refill_idx;
  278 
  279         /* Packets pending to be processed */
  280         volatile int            pkts_pending;
  281 
  282         /* Number of  descriptors in this ring. */
  283         uint32_t                max_count;
  284 
  285         /* The number of descriptors pending refill. */
  286         uint32_t                refill_count;
  287 
  288         uint32_t                pkts_per_intr;
  289         uint32_t                refill_threshold;
  290 
  291         /*
  292          * The max number of descriptors in DROQ without a buffer.
  293          * This field is used to keep track of empty space threshold. If the
  294          * refill_count reaches this value, the DROQ cannot accept a max-sized
  295          * (64K) packet.
  296          */
  297         uint32_t                max_empty_descs;
  298 
  299         /*
  300          * The receive buffer list. This list has the virtual addresses of
  301          * the buffers.
  302          */
  303         struct lio_recv_buffer  *recv_buf_list;
  304 
  305         /* The size of each buffer pointed by the buffer pointer. */
  306         uint32_t                buffer_size;
  307 
  308         /*
  309          * Offset to packet credit register.
  310          * Host writes number of info/buffer ptrs available to this register
  311          */
  312         uint32_t                pkts_credit_reg;
  313 
  314         /*
  315          * Offset packet sent register.
  316          * Octeon writes the number of packets DMA'ed to host memory
  317          * in this register.
  318          */
  319         uint32_t                pkts_sent_reg;
  320 
  321         struct lio_stailq_head  dispatch_stq_head;
  322 
  323         /* Statistics for this DROQ. */
  324         struct lio_droq_stats   stats;
  325 
  326         /* DMA mapped address of the DROQ descriptor ring. */
  327         vm_paddr_t              desc_ring_dma;
  328 
  329         /* application context */
  330         void                    *app_ctx;
  331 
  332         uint32_t                cpu_id;
  333 
  334         struct task             droq_task;
  335         struct taskqueue        *droq_taskqueue;
  336 
  337         struct lro_ctrl         lro;
  338 };
  339 
  340 #define LIO_DROQ_SIZE   (sizeof(struct lio_droq))
  341 
  342 /*
  343  * Allocates space for the descriptor ring for the droq and sets the
  344  *   base addr, num desc etc in Octeon registers.
  345  *
  346  * @param  oct_dev    - pointer to the octeon device structure
  347  * @param  q_no       - droq no.
  348  * @param app_ctx     - pointer to application context
  349  * @return Success: 0    Failure: 1
  350  */
  351 int     lio_init_droq(struct octeon_device *oct_dev,
  352                       uint32_t q_no, uint32_t num_descs, uint32_t desc_size,
  353                       void *app_ctx);
  354 
  355 /*
  356  *  Frees the space for descriptor ring for the droq.
  357  *
  358  *  @param oct_dev - pointer to the octeon device structure
  359  *  @param q_no    - droq no.
  360  *  @return:    Success: 0    Failure: 1
  361  */
  362 int     lio_delete_droq(struct octeon_device *oct_dev, uint32_t q_no);
  363 
  364 /*
  365  * Register a change in droq operations. The ops field has a pointer to a
  366  * function which will called by the DROQ handler for all packets arriving
  367  * on output queues given by q_no irrespective of the type of packet.
  368  * The ops field also has a flag which if set tells the DROQ handler to
  369  * drop packets if it receives more than what it can process in one
  370  * invocation of the handler.
  371  * @param oct       - octeon device
  372  * @param q_no      - octeon output queue number (0 <= q_no <= MAX_OCTEON_DROQ-1
  373  * @param ops       - the droq_ops settings for this queue
  374  * @return          - 0 on success, -ENODEV or -EINVAL on error.
  375  */
  376 int     lio_register_droq_ops(struct octeon_device *oct, uint32_t q_no,
  377                               struct lio_droq_ops *ops);
  378 
  379 /*
  380  * Resets the function pointer and flag settings made by
  381  * lio_register_droq_ops(). After this routine is called, the DROQ handler
  382  * will lookup dispatch function for each arriving packet on the output queue
  383  * given by q_no.
  384  * @param oct       - octeon device
  385  * @param q_no      - octeon output queue number (0 <= q_no <= MAX_OCTEON_DROQ-1
  386  * @return          - 0 on success, -ENODEV or -EINVAL on error.
  387  */
  388 int     lio_unregister_droq_ops(struct octeon_device *oct, uint32_t q_no);
  389 
  390 /*
  391  *    Register a dispatch function for a opcode/subcode. The driver will call
  392  *    this dispatch function when it receives a packet with the given
  393  *    opcode/subcode in its output queues along with the user specified
  394  *    argument.
  395  *    @param  oct        - the octeon device to register with.
  396  *    @param  opcode     - the opcode for which the dispatch will be registered.
  397  *    @param  subcode    - the subcode for which the dispatch will be registered
  398  *    @param  fn         - the dispatch function.
  399  *    @param  fn_arg     - user specified that will be passed along with the
  400  *                         dispatch function by the driver.
  401  *    @return Success: 0; Failure: 1
  402  */
  403 int     lio_register_dispatch_fn(struct octeon_device *oct, uint16_t opcode,
  404                                  uint16_t subcode, lio_dispatch_fn_t fn,
  405                                  void *fn_arg);
  406 
  407 /*
  408  *   Remove registration for an opcode/subcode. This will delete the mapping for
  409  *   an opcode/subcode. The dispatch function will be unregistered and will no
  410  *   longer be called if a packet with the opcode/subcode arrives in the driver
  411  *   output queues.
  412  *   @param  oct        -  the octeon device to unregister from.
  413  *   @param  opcode     -  the opcode to be unregistered.
  414  *   @param  subcode    -  the subcode to be unregistered.
  415  *
  416  *   @return Success: 0; Failure: 1
  417  */
  418 int     lio_unregister_dispatch_fn(struct octeon_device *oct, uint16_t opcode,
  419                                    uint16_t subcode);
  420 
  421 uint32_t        lio_droq_check_hw_for_pkts(struct lio_droq *droq);
  422 
  423 int     lio_create_droq(struct octeon_device *oct, uint32_t q_no,
  424                         uint32_t num_descs, uint32_t desc_size, void *app_ctx);
  425 
  426 int     lio_droq_process_packets(struct octeon_device *oct,
  427                                  struct lio_droq *droq, uint32_t budget);
  428 
  429 uint32_t        lio_droq_refill(struct octeon_device *octeon_dev,
  430                                 struct lio_droq *droq);
  431 void    lio_droq_bh(void *ptr, int pending __unused);
  432 #endif  /* __LIO_DROQ_H__ */

Cache object: 899b314e189a2b0757ccb8c155700dc7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.