LCOV - code coverage report
Current view: top level - drivers/net/enic/base - vnic_wq.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 4 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 0 -
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 4 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2008-2017 Cisco Systems, Inc.  All rights reserved.
       3                 :            :  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #ifndef _VNIC_WQ_H_
       7                 :            : #define _VNIC_WQ_H_
       8                 :            : 
       9                 :            : 
      10                 :            : #include "vnic_dev.h"
      11                 :            : #include "vnic_cq.h"
      12                 :            : #include <rte_memzone.h>
      13                 :            : 
      14                 :            : /* Work queue control */
      15                 :            : struct vnic_wq_ctrl {
      16                 :            :         uint64_t ring_base;                     /* 0x00 */
      17                 :            :         uint32_t ring_size;                     /* 0x08 */
      18                 :            :         uint32_t pad0;
      19                 :            :         uint32_t posted_index;                  /* 0x10 */
      20                 :            :         uint32_t pad1;
      21                 :            :         uint32_t cq_index;                      /* 0x18 */
      22                 :            :         uint32_t pad2;
      23                 :            :         uint32_t enable;                        /* 0x20 */
      24                 :            :         uint32_t pad3;
      25                 :            :         uint32_t running;                       /* 0x28 */
      26                 :            :         uint32_t pad4;
      27                 :            :         uint32_t fetch_index;                   /* 0x30 */
      28                 :            :         uint32_t pad5;
      29                 :            :         uint32_t dca_value;                     /* 0x38 */
      30                 :            :         uint32_t pad6;
      31                 :            :         uint32_t error_interrupt_enable;        /* 0x40 */
      32                 :            :         uint32_t pad7;
      33                 :            :         uint32_t error_interrupt_offset;        /* 0x48 */
      34                 :            :         uint32_t pad8;
      35                 :            :         uint32_t error_status;                  /* 0x50 */
      36                 :            :         uint32_t pad9;
      37                 :            : };
      38                 :            : 
      39                 :            : struct vnic_wq {
      40                 :            :         unsigned int index;
      41                 :            :         uint64_t tx_offload_notsup_mask;
      42                 :            :         struct vnic_dev *vdev;
      43                 :            :         struct vnic_wq_ctrl __iomem *ctrl;              /* memory-mapped */
      44                 :            :         struct vnic_dev_ring ring;
      45                 :            :         struct rte_mbuf **bufs;
      46                 :            :         unsigned int head_idx;
      47                 :            :         unsigned int cq_pend;
      48                 :            :         unsigned int tail_idx;
      49                 :            :         unsigned int socket_id;
      50                 :            :         const struct rte_memzone *cqmsg_rz;
      51                 :            :         uint16_t last_completed_index;
      52                 :            :         uint64_t offloads;
      53                 :            :         bool admin_chan;
      54                 :            :         const struct rte_memzone *admin_msg_rz;
      55                 :            :         uint64_t soft_stats_tx;
      56                 :            : };
      57                 :            : 
      58                 :            : static inline unsigned int vnic_wq_desc_avail(struct vnic_wq *wq)
      59                 :            : {
      60                 :            :         /* how many does SW own? */
      61                 :          0 :         return wq->ring.desc_avail;
      62                 :            : }
      63                 :            : 
      64                 :            : static inline unsigned int vnic_wq_desc_used(struct vnic_wq *wq)
      65                 :            : {
      66                 :            :         /* how many does HW own? */
      67         [ #  # ]:          0 :         return wq->ring.desc_count - wq->ring.desc_avail - 1;
      68                 :            : }
      69                 :            : 
      70                 :            : #define PI_LOG2_CACHE_LINE_SIZE        5
      71                 :            : #define PI_INDEX_BITS            12
      72                 :            : #define PI_INDEX_MASK ((1U << PI_INDEX_BITS) - 1)
      73                 :            : #define PI_PREFETCH_LEN_MASK ((1U << PI_LOG2_CACHE_LINE_SIZE) - 1)
      74                 :            : #define PI_PREFETCH_LEN_OFF 16
      75                 :            : #define PI_PREFETCH_ADDR_BITS 43
      76                 :            : #define PI_PREFETCH_ADDR_MASK ((1ULL << PI_PREFETCH_ADDR_BITS) - 1)
      77                 :            : #define PI_PREFETCH_ADDR_OFF 21
      78                 :            : 
      79                 :            : /** How many cache lines are touched by buffer (addr, len). */
      80                 :            : static inline unsigned int num_cache_lines_touched(dma_addr_t addr,
      81                 :            :                                                         unsigned int len)
      82                 :            : {
      83                 :            :         const unsigned long mask = PI_PREFETCH_LEN_MASK;
      84                 :            :         const unsigned long laddr = (unsigned long)addr;
      85                 :            :         unsigned long lines, equiv_len;
      86                 :            :         /* A. If addr is aligned, our solution is just to round up len to the
      87                 :            :         next boundary.
      88                 :            : 
      89                 :            :         e.g. addr = 0, len = 48
      90                 :            :         +--------------------+
      91                 :            :         |XXXXXXXXXXXXXXXXXXXX|    32-byte cacheline a
      92                 :            :         +--------------------+
      93                 :            :         |XXXXXXXXXX          |    cacheline b
      94                 :            :         +--------------------+
      95                 :            : 
      96                 :            :         B. If addr is not aligned, however, we may use an extra
      97                 :            :         cacheline.  e.g. addr = 12, len = 22
      98                 :            : 
      99                 :            :         +--------------------+
     100                 :            :         |       XXXXXXXXXXXXX|
     101                 :            :         +--------------------+
     102                 :            :         |XX                  |
     103                 :            :         +--------------------+
     104                 :            : 
     105                 :            :         Our solution is to make the problem equivalent to case A
     106                 :            :         above by adding the empty space in the first cacheline to the length:
     107                 :            :         unsigned long len;
     108                 :            : 
     109                 :            :         +--------------------+
     110                 :            :         |eeeeeeeXXXXXXXXXXXXX|    "e" is empty space, which we add to len
     111                 :            :         +--------------------+
     112                 :            :         |XX                  |
     113                 :            :         +--------------------+
     114                 :            : 
     115                 :            :         */
     116                 :            :         equiv_len = len + (laddr & mask);
     117                 :            : 
     118                 :            :         /* Now we can just round up this len to the next 32-byte boundary. */
     119                 :            :         lines = (equiv_len + mask) & (~mask);
     120                 :            : 
     121                 :            :         /* Scale bytes -> cachelines. */
     122                 :            :         return lines >> PI_LOG2_CACHE_LINE_SIZE;
     123                 :            : }
     124                 :            : 
     125                 :            : static inline uint64_t vnic_cached_posted_index(dma_addr_t addr,
     126                 :            :                                                 unsigned int len,
     127                 :            :                                                 unsigned int index)
     128                 :            : {
     129                 :            :         unsigned int num_cache_lines = num_cache_lines_touched(addr, len);
     130                 :            :         /* Wish we could avoid a branch here.  We could have separate
     131                 :            :          * vnic_wq_post() and vinc_wq_post_inline(), the latter
     132                 :            :          * only supporting < 1k (2^5 * 2^5) sends, I suppose.  This would
     133                 :            :          * eliminate the if (eop) branch as well.
     134                 :            :          */
     135                 :            :         if (num_cache_lines > PI_PREFETCH_LEN_MASK)
     136                 :            :                 num_cache_lines = 0;
     137                 :            :         return (index & PI_INDEX_MASK) |
     138                 :            :         ((num_cache_lines & PI_PREFETCH_LEN_MASK) << PI_PREFETCH_LEN_OFF) |
     139                 :            :                 (((addr >> PI_LOG2_CACHE_LINE_SIZE) &
     140                 :            :         PI_PREFETCH_ADDR_MASK) << PI_PREFETCH_ADDR_OFF);
     141                 :            : }
     142                 :            : 
     143                 :            : static inline uint32_t
     144                 :            : buf_idx_incr(uint32_t n_descriptors, uint32_t idx)
     145                 :            : {
     146                 :          0 :         idx++;
     147         [ #  # ]:          0 :         if (unlikely(idx == n_descriptors))
     148                 :            :                 idx = 0;
     149                 :            :         return idx;
     150                 :            : }
     151                 :            : 
     152                 :            : void vnic_wq_free(struct vnic_wq *wq);
     153                 :            : int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
     154                 :            :         unsigned int desc_count, unsigned int desc_size);
     155                 :            : int vnic_admin_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,
     156                 :            :         unsigned int desc_count, unsigned int desc_size);
     157                 :            : void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
     158                 :            :         unsigned int fetch_index, unsigned int posted_index,
     159                 :            :         unsigned int error_interrupt_enable,
     160                 :            :         unsigned int error_interrupt_offset);
     161                 :            : void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
     162                 :            :         unsigned int error_interrupt_enable,
     163                 :            :         unsigned int error_interrupt_offset);
     164                 :            : void vnic_wq_error_out(struct vnic_wq *wq, unsigned int error);
     165                 :            : unsigned int vnic_wq_error_status(struct vnic_wq *wq);
     166                 :            : void vnic_wq_enable(struct vnic_wq *wq);
     167                 :            : int vnic_wq_disable(struct vnic_wq *wq);
     168                 :            : void vnic_wq_clean(struct vnic_wq *wq,
     169                 :            :                    void (*buf_clean)(struct rte_mbuf **buf));
     170                 :            : #endif /* _VNIC_WQ_H_ */

Generated by: LCOV version 1.14