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/ixl/ixl_pf_qmgr.c

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 
    3   Copyright (c) 2013-2018, Intel Corporation
    4   All rights reserved.
    5   
    6   Redistribution and use in source and binary forms, with or without 
    7   modification, are permitted provided that the following conditions are met:
    8   
    9    1. Redistributions of source code must retain the above copyright notice, 
   10       this list of conditions and the following disclaimer.
   11   
   12    2. Redistributions in binary form must reproduce the above copyright 
   13       notice, this list of conditions and the following disclaimer in the 
   14       documentation and/or other materials provided with the distribution.
   15   
   16    3. Neither the name of the Intel Corporation nor the names of its 
   17       contributors may be used to endorse or promote products derived from 
   18       this software without specific prior written permission.
   19   
   20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
   22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
   23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
   24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
   25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
   26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
   27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30   POSSIBILITY OF SUCH DAMAGE.
   31 
   32 ******************************************************************************/
   33 /*$FreeBSD$*/
   34 
   35 
   36 #include "ixl_pf_qmgr.h"
   37 
   38 static int      ixl_pf_qmgr_find_free_contiguous_block(struct ixl_pf_qmgr *qmgr, int num);
   39 
   40 int
   41 ixl_pf_qmgr_init(struct ixl_pf_qmgr *qmgr, u16 num_queues)
   42 {
   43         if (num_queues < 1)
   44                 return (EINVAL);
   45 
   46         qmgr->num_queues = num_queues;
   47         qmgr->qinfo = malloc(num_queues * sizeof(struct ixl_pf_qmgr_qinfo),
   48             M_IXL, M_ZERO | M_NOWAIT);
   49         if (qmgr->qinfo == NULL)
   50                 return ENOMEM;
   51 
   52         return (0);
   53 }
   54 
   55 int
   56 ixl_pf_qmgr_alloc_contiguous(struct ixl_pf_qmgr *qmgr, u16 num, struct ixl_pf_qtag *qtag)
   57 {
   58         int i;
   59         int avail;
   60         int block_start;
   61         u16 alloc_size;
   62 
   63         if (qtag == NULL || num < 1)
   64                 return (EINVAL);
   65         
   66         /* We have to allocate in power-of-two chunks, so get next power of two */
   67         alloc_size = (u16)next_power_of_two(num);
   68 
   69         /* Don't try if there aren't enough queues */
   70         avail = ixl_pf_qmgr_get_num_free(qmgr);
   71         if (avail < alloc_size)
   72                 return (ENOSPC);
   73 
   74         block_start = ixl_pf_qmgr_find_free_contiguous_block(qmgr, alloc_size);
   75         if (block_start < 0)
   76                 return (ENOSPC);
   77 
   78         /* Mark queues as allocated */
   79         for (i = block_start; i < block_start + alloc_size; i++)
   80                 qmgr->qinfo[i].allocated = true;
   81 
   82         bzero(qtag, sizeof(*qtag));
   83         qtag->qmgr = qmgr;
   84         qtag->type = IXL_PF_QALLOC_CONTIGUOUS;
   85         qtag->qidx[0] = block_start;
   86         qtag->num_allocated = alloc_size;
   87         qtag->num_active = num;
   88 
   89         return (0);
   90 }
   91 
   92 /*
   93  * NB: indices is u16 because this is the queue index width used in the Add VSI AQ command
   94  */
   95 int
   96 ixl_pf_qmgr_alloc_scattered(struct ixl_pf_qmgr *qmgr, u16 num, struct ixl_pf_qtag *qtag)
   97 {
   98         int i;
   99         int avail, count = 0;
  100         u16 alloc_size;
  101 
  102         if (qtag == NULL || num < 1 || num > 16)
  103                 return (EINVAL);
  104 
  105         /* We have to allocate in power-of-two chunks, so get next power of two */
  106         alloc_size = (u16)next_power_of_two(num);
  107 
  108         avail = ixl_pf_qmgr_get_num_free(qmgr);
  109         if (avail < alloc_size)
  110                 return (ENOSPC);
  111 
  112         bzero(qtag, sizeof(*qtag));
  113         qtag->qmgr = qmgr;
  114         qtag->type = IXL_PF_QALLOC_SCATTERED;
  115         qtag->num_active = num;
  116         qtag->num_allocated = alloc_size;
  117 
  118         for (i = 0; i < qmgr->num_queues; i++) {
  119                 if (!qmgr->qinfo[i].allocated) {
  120                         qtag->qidx[count] = i;
  121                         count++;
  122                         qmgr->qinfo[i].allocated = true;
  123                         if (count == alloc_size)
  124                                 return (0);
  125                 }
  126         }
  127 
  128         // Shouldn't get here
  129         return (EDOOFUS);
  130 }
  131 
  132 int
  133 ixl_pf_qmgr_release(struct ixl_pf_qmgr *qmgr, struct ixl_pf_qtag *qtag)
  134 {
  135         u16 i, qidx;
  136 
  137         if (qtag == NULL)
  138                 return (EINVAL);
  139 
  140         if (qtag->type == IXL_PF_QALLOC_SCATTERED) {
  141                 for (i = 0; i < qtag->num_allocated; i++) {
  142                         qidx = qtag->qidx[i];
  143                         bzero(&qmgr->qinfo[qidx], sizeof(qmgr->qinfo[qidx]));
  144                 }
  145         } else {
  146                 u16 first_index = qtag->qidx[0];
  147                 for (i = first_index; i < first_index + qtag->num_allocated; i++)
  148                         bzero(&qmgr->qinfo[i], sizeof(qmgr->qinfo[qidx]));
  149         }
  150 
  151         qtag->qmgr = NULL;
  152         return (0);
  153 }
  154 
  155 int
  156 ixl_pf_qmgr_get_num_queues(struct ixl_pf_qmgr *qmgr)
  157 {
  158         return (qmgr->num_queues);
  159 }
  160 
  161 /*
  162  * ERJ: This assumes the info array isn't longer than INT_MAX.
  163  * This assumption might cause a y3k bug or something, I'm sure.
  164  */
  165 int
  166 ixl_pf_qmgr_get_num_free(struct ixl_pf_qmgr *qmgr)
  167 {
  168         int count = 0;
  169 
  170         for (int i = 0; i < qmgr->num_queues; i++) {
  171                 if (!qmgr->qinfo[i].allocated)
  172                         count++;
  173         }
  174 
  175         return (count);
  176 }
  177 
  178 int
  179 ixl_pf_qmgr_get_first_free(struct ixl_pf_qmgr *qmgr, u16 start)
  180 {
  181         int i;
  182 
  183         if (start > qmgr->num_queues - 1)
  184                 return (-EINVAL);
  185 
  186         for (i = start; i < qmgr->num_queues; i++) {
  187                 if (qmgr->qinfo[i].allocated)
  188                         continue;
  189                 else
  190                         return (i);
  191         }
  192 
  193         // No free queues
  194         return (-ENOSPC);
  195 }
  196 
  197 void
  198 ixl_pf_qmgr_destroy(struct ixl_pf_qmgr *qmgr)
  199 {
  200         free(qmgr->qinfo, M_IXL);
  201         qmgr->qinfo = NULL;
  202 }
  203 
  204 void
  205 ixl_pf_qmgr_mark_queue_enabled(struct ixl_pf_qtag *qtag, u16 vsi_qidx, bool tx)
  206 {
  207         MPASS(qtag != NULL);
  208 
  209         struct ixl_pf_qmgr *qmgr = qtag->qmgr;
  210         u16 pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
  211         if (tx)
  212                 qmgr->qinfo[pf_qidx].tx_enabled = true;
  213         else
  214                 qmgr->qinfo[pf_qidx].rx_enabled = true;
  215 }
  216 
  217 void
  218 ixl_pf_qmgr_mark_queue_disabled(struct ixl_pf_qtag *qtag, u16 vsi_qidx, bool tx)
  219 {
  220         MPASS(qtag != NULL);
  221 
  222         struct ixl_pf_qmgr *qmgr = qtag->qmgr;
  223         u16 pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
  224         if (tx)
  225                 qmgr->qinfo[pf_qidx].tx_enabled = false;
  226         else
  227                 qmgr->qinfo[pf_qidx].rx_enabled = false;
  228 }
  229 
  230 void
  231 ixl_pf_qmgr_mark_queue_configured(struct ixl_pf_qtag *qtag, u16 vsi_qidx, bool tx)
  232 {
  233         MPASS(qtag != NULL);
  234 
  235         struct ixl_pf_qmgr *qmgr = qtag->qmgr;
  236         u16 pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
  237         if (tx)
  238                 qmgr->qinfo[pf_qidx].tx_configured = true;
  239         else
  240                 qmgr->qinfo[pf_qidx].rx_configured = true;
  241 }
  242 
  243 bool
  244 ixl_pf_qmgr_is_queue_enabled(struct ixl_pf_qtag *qtag, u16 vsi_qidx, bool tx)
  245 {
  246         MPASS(qtag != NULL);
  247 
  248         struct ixl_pf_qmgr *qmgr = qtag->qmgr;
  249         u16 pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
  250         if (tx)
  251                 return (qmgr->qinfo[pf_qidx].tx_enabled);
  252         else
  253                 return (qmgr->qinfo[pf_qidx].rx_enabled);
  254 }
  255 
  256 bool
  257 ixl_pf_qmgr_is_queue_configured(struct ixl_pf_qtag *qtag, u16 vsi_qidx, bool tx)
  258 {
  259         MPASS(qtag != NULL);
  260 
  261         struct ixl_pf_qmgr *qmgr = qtag->qmgr;
  262         u16 pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
  263         if (tx)
  264                 return (qmgr->qinfo[pf_qidx].tx_configured);
  265         else
  266                 return (qmgr->qinfo[pf_qidx].rx_configured);
  267 }
  268 
  269 void
  270 ixl_pf_qmgr_clear_queue_flags(struct ixl_pf_qtag *qtag)
  271 {
  272         MPASS(qtag != NULL);
  273 
  274         struct ixl_pf_qmgr *qmgr = qtag->qmgr;
  275         for (u16 i = 0; i < qtag->num_allocated; i++) {
  276                 u16 pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, i);
  277 
  278                 qmgr->qinfo[pf_qidx].tx_configured = 0;
  279                 qmgr->qinfo[pf_qidx].rx_configured = 0;
  280                 qmgr->qinfo[pf_qidx].rx_enabled = 0;
  281                 qmgr->qinfo[pf_qidx].tx_enabled = 0;
  282         }
  283 }
  284 
  285 u16
  286 ixl_pf_qidx_from_vsi_qidx(struct ixl_pf_qtag *qtag, u16 index)
  287 {
  288         MPASS(index < qtag->num_allocated);
  289 
  290         if (qtag->type == IXL_PF_QALLOC_CONTIGUOUS)
  291                 return qtag->first_qidx + index;
  292         else
  293                 return qtag->qidx[index];
  294 }
  295 
  296 /* Static Functions */
  297 
  298 static int
  299 ixl_pf_qmgr_find_free_contiguous_block(struct ixl_pf_qmgr *qmgr, int num)
  300 {
  301         int i;
  302         int count = 0;
  303         bool block_started = false;
  304         int possible_start;
  305 
  306         for (i = 0; i < qmgr->num_queues; i++) {
  307                 if (!qmgr->qinfo[i].allocated) {
  308                         if (!block_started) {
  309                                 block_started = true;
  310                                 possible_start = i;
  311                         }
  312                         count++;
  313                         if (count == num)
  314                                 return (possible_start);
  315                 } else { /* this queue is already allocated */
  316                         block_started = false;
  317                         count = 0;
  318                 }
  319         }
  320 
  321         /* Can't find a contiguous block of the requested size */
  322         return (-1);
  323 }
  324 

Cache object: 9d755497862c5a71d5d95cf8fe32382c


[ 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.