LCOV - code coverage report
Current view: top level - drivers/scsi/snic - snic_res.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 107 0.0 %
Date: 2022-04-01 14:17:54 Functions: 0 5 0.0 %
Branches: 0 82 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright 2014 Cisco Systems, Inc.  All rights reserved.
       3                 :            :  *
       4                 :            :  * This program is free software; you may redistribute it and/or modify
       5                 :            :  * it under the terms of the GNU General Public License as published by
       6                 :            :  * the Free Software Foundation; version 2 of the License.
       7                 :            :  *
       8                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       9                 :            :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      10                 :            :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      11                 :            :  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
      12                 :            :  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
      13                 :            :  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
      14                 :            :  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      15                 :            :  * SOFTWARE.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include <linux/errno.h>
      19                 :            : #include <linux/types.h>
      20                 :            : #include <linux/pci.h>
      21                 :            : 
      22                 :            : #include "wq_enet_desc.h"
      23                 :            : #include "cq_enet_desc.h"
      24                 :            : #include "vnic_resource.h"
      25                 :            : #include "vnic_dev.h"
      26                 :            : #include "vnic_wq.h"
      27                 :            : #include "vnic_cq.h"
      28                 :            : #include "vnic_intr.h"
      29                 :            : #include "vnic_stats.h"
      30                 :            : #include "snic.h"
      31                 :            : 
      32                 :            : int
      33                 :          0 : snic_get_vnic_config(struct snic *snic)
      34                 :            : {
      35                 :          0 :         struct vnic_snic_config *c = &snic->config;
      36                 :          0 :         int ret;
      37                 :            : 
      38                 :            : #define GET_CONFIG(m) \
      39                 :            :         do { \
      40                 :            :                 ret = svnic_dev_spec(snic->vdev, \
      41                 :            :                                      offsetof(struct vnic_snic_config, m), \
      42                 :            :                                      sizeof(c->m), \
      43                 :            :                                      &c->m); \
      44                 :            :                 if (ret) { \
      45                 :            :                         SNIC_HOST_ERR(snic->shost, \
      46                 :            :                                       "Error getting %s, %d\n", #m, ret); \
      47                 :            :                         return ret; \
      48                 :            :                 } \
      49                 :            :         } while (0)
      50                 :            : 
      51         [ #  # ]:          0 :         GET_CONFIG(wq_enet_desc_count);
      52         [ #  # ]:          0 :         GET_CONFIG(maxdatafieldsize);
      53         [ #  # ]:          0 :         GET_CONFIG(intr_timer);
      54         [ #  # ]:          0 :         GET_CONFIG(intr_timer_type);
      55         [ #  # ]:          0 :         GET_CONFIG(flags);
      56         [ #  # ]:          0 :         GET_CONFIG(io_throttle_count);
      57         [ #  # ]:          0 :         GET_CONFIG(port_down_timeout);
      58         [ #  # ]:          0 :         GET_CONFIG(port_down_io_retries);
      59         [ #  # ]:          0 :         GET_CONFIG(luns_per_tgt);
      60         [ #  # ]:          0 :         GET_CONFIG(xpt_type);
      61         [ #  # ]:          0 :         GET_CONFIG(hid);
      62                 :            : 
      63                 :          0 :         c->wq_enet_desc_count = min_t(u32,
      64                 :            :                                       VNIC_SNIC_WQ_DESCS_MAX,
      65                 :            :                                       max_t(u32,
      66                 :            :                                             VNIC_SNIC_WQ_DESCS_MIN,
      67                 :            :                                             c->wq_enet_desc_count));
      68                 :            : 
      69                 :          0 :         c->wq_enet_desc_count = ALIGN(c->wq_enet_desc_count, 16);
      70                 :            : 
      71                 :          0 :         c->maxdatafieldsize = min_t(u32,
      72                 :            :                                     VNIC_SNIC_MAXDATAFIELDSIZE_MAX,
      73                 :            :                                     max_t(u32,
      74                 :            :                                           VNIC_SNIC_MAXDATAFIELDSIZE_MIN,
      75                 :            :                                           c->maxdatafieldsize));
      76                 :            : 
      77                 :          0 :         c->io_throttle_count = min_t(u32,
      78                 :            :                                      VNIC_SNIC_IO_THROTTLE_COUNT_MAX,
      79                 :            :                                      max_t(u32,
      80                 :            :                                            VNIC_SNIC_IO_THROTTLE_COUNT_MIN,
      81                 :            :                                            c->io_throttle_count));
      82                 :            : 
      83                 :          0 :         c->port_down_timeout = min_t(u32,
      84                 :            :                                      VNIC_SNIC_PORT_DOWN_TIMEOUT_MAX,
      85                 :            :                                      c->port_down_timeout);
      86                 :            : 
      87                 :          0 :         c->port_down_io_retries = min_t(u32,
      88                 :            :                                      VNIC_SNIC_PORT_DOWN_IO_RETRIES_MAX,
      89                 :            :                                      c->port_down_io_retries);
      90                 :            : 
      91                 :          0 :         c->luns_per_tgt = min_t(u32,
      92                 :            :                                 VNIC_SNIC_LUNS_PER_TARGET_MAX,
      93                 :            :                                 max_t(u32,
      94                 :            :                                       VNIC_SNIC_LUNS_PER_TARGET_MIN,
      95                 :            :                                       c->luns_per_tgt));
      96                 :            : 
      97                 :          0 :         c->intr_timer = min_t(u32, VNIC_INTR_TIMER_MAX, c->intr_timer);
      98                 :            : 
      99                 :          0 :         SNIC_INFO("vNIC resources wq %d\n", c->wq_enet_desc_count);
     100                 :          0 :         SNIC_INFO("vNIC mtu %d intr timer %d\n",
     101                 :            :                   c->maxdatafieldsize,
     102                 :            :                   c->intr_timer);
     103                 :            : 
     104                 :          0 :         SNIC_INFO("vNIC flags 0x%x luns per tgt %d\n",
     105                 :            :                   c->flags,
     106                 :            :                   c->luns_per_tgt);
     107                 :            : 
     108                 :          0 :         SNIC_INFO("vNIC io throttle count %d\n", c->io_throttle_count);
     109                 :          0 :         SNIC_INFO("vNIC port down timeout %d port down io retries %d\n",
     110                 :            :                   c->port_down_timeout,
     111                 :            :                   c->port_down_io_retries);
     112                 :            : 
     113                 :          0 :         SNIC_INFO("vNIC back end type = %d\n", c->xpt_type);
     114                 :          0 :         SNIC_INFO("vNIC hid = %d\n", c->hid);
     115                 :            : 
     116                 :          0 :         return 0;
     117                 :            : }
     118                 :            : 
     119                 :            : void
     120                 :          0 : snic_get_res_counts(struct snic *snic)
     121                 :            : {
     122                 :          0 :         snic->wq_count = svnic_dev_get_res_count(snic->vdev, RES_TYPE_WQ);
     123   [ #  #  #  # ]:          0 :         SNIC_BUG_ON(snic->wq_count == 0);
     124                 :          0 :         snic->cq_count = svnic_dev_get_res_count(snic->vdev, RES_TYPE_CQ);
     125   [ #  #  #  # ]:          0 :         SNIC_BUG_ON(snic->cq_count == 0);
     126                 :          0 :         snic->intr_count = svnic_dev_get_res_count(snic->vdev,
     127                 :            :                                                   RES_TYPE_INTR_CTRL);
     128   [ #  #  #  # ]:          0 :         SNIC_BUG_ON(snic->intr_count == 0);
     129                 :          0 : }
     130                 :            : 
     131                 :            : void
     132                 :          0 : snic_free_vnic_res(struct snic *snic)
     133                 :            : {
     134                 :          0 :         unsigned int i;
     135                 :            : 
     136         [ #  # ]:          0 :         for (i = 0; i < snic->wq_count; i++)
     137                 :          0 :                 svnic_wq_free(&snic->wq[i]);
     138                 :            : 
     139         [ #  # ]:          0 :         for (i = 0; i < snic->cq_count; i++)
     140                 :          0 :                 svnic_cq_free(&snic->cq[i]);
     141                 :            : 
     142         [ #  # ]:          0 :         for (i = 0; i < snic->intr_count; i++)
     143                 :          0 :                 svnic_intr_free(&snic->intr[i]);
     144                 :          0 : }
     145                 :            : 
     146                 :            : int
     147                 :          0 : snic_alloc_vnic_res(struct snic *snic)
     148                 :            : {
     149                 :          0 :         enum vnic_dev_intr_mode intr_mode;
     150                 :          0 :         unsigned int mask_on_assertion;
     151                 :          0 :         unsigned int intr_offset;
     152                 :          0 :         unsigned int err_intr_enable;
     153                 :          0 :         unsigned int err_intr_offset;
     154                 :          0 :         unsigned int i;
     155                 :          0 :         int ret;
     156                 :            : 
     157                 :          0 :         intr_mode = svnic_dev_get_intr_mode(snic->vdev);
     158                 :            : 
     159   [ #  #  #  #  :          0 :         SNIC_INFO("vNIC interrupt mode: %s\n",
                   #  # ]
     160                 :            :                   ((intr_mode == VNIC_DEV_INTR_MODE_INTX) ?
     161                 :            :                    "Legacy PCI INTx" :
     162                 :            :                    ((intr_mode == VNIC_DEV_INTR_MODE_MSI) ?
     163                 :            :                     "MSI" :
     164                 :            :                     ((intr_mode == VNIC_DEV_INTR_MODE_MSIX) ?
     165                 :            :                      "MSI-X" : "Unknown"))));
     166                 :            : 
     167                 :            :         /* only MSI-X is supported */
     168         [ #  # ]:          0 :         SNIC_BUG_ON(intr_mode != VNIC_DEV_INTR_MODE_MSIX);
     169                 :            : 
     170                 :          0 :         SNIC_INFO("wq %d cq %d intr %d\n", snic->wq_count,
     171                 :            :                   snic->cq_count,
     172                 :            :                   snic->intr_count);
     173                 :            : 
     174                 :            : 
     175                 :            :         /* Allocate WQs used for SCSI IOs */
     176         [ #  # ]:          0 :         for (i = 0; i < snic->wq_count; i++) {
     177                 :          0 :                 ret = svnic_wq_alloc(snic->vdev,
     178                 :            :                                      &snic->wq[i],
     179                 :            :                                      i,
     180                 :            :                                      snic->config.wq_enet_desc_count,
     181                 :            :                                      sizeof(struct wq_enet_desc));
     182         [ #  # ]:          0 :                 if (ret)
     183                 :          0 :                         goto error_cleanup;
     184                 :            :         }
     185                 :            : 
     186                 :            :         /* CQ for each WQ */
     187         [ #  # ]:          0 :         for (i = 0; i < snic->wq_count; i++) {
     188                 :          0 :                 ret = svnic_cq_alloc(snic->vdev,
     189                 :            :                                      &snic->cq[i],
     190                 :            :                                      i,
     191                 :            :                                      snic->config.wq_enet_desc_count,
     192                 :            :                                      sizeof(struct cq_enet_wq_desc));
     193         [ #  # ]:          0 :                 if (ret)
     194                 :          0 :                         goto error_cleanup;
     195                 :            :         }
     196                 :            : 
     197   [ #  #  #  # ]:          0 :         SNIC_BUG_ON(snic->cq_count != 2 * snic->wq_count);
     198                 :            :         /* CQ for FW TO host */
     199         [ #  # ]:          0 :         for (i = snic->wq_count; i < snic->cq_count; i++) {
     200                 :          0 :                 ret = svnic_cq_alloc(snic->vdev,
     201                 :            :                                      &snic->cq[i],
     202                 :            :                                      i,
     203                 :          0 :                                      (snic->config.wq_enet_desc_count * 3),
     204                 :            :                                      sizeof(struct snic_fw_req));
     205         [ #  # ]:          0 :                 if (ret)
     206                 :          0 :                         goto error_cleanup;
     207                 :            :         }
     208                 :            : 
     209         [ #  # ]:          0 :         for (i = 0; i < snic->intr_count; i++) {
     210                 :          0 :                 ret = svnic_intr_alloc(snic->vdev, &snic->intr[i], i);
     211         [ #  # ]:          0 :                 if (ret)
     212                 :          0 :                         goto error_cleanup;
     213                 :            :         }
     214                 :            : 
     215                 :            :         /*
     216                 :            :          * Init WQ Resources.
     217                 :            :          * WQ[0 to n] points to CQ[0 to n-1]
     218                 :            :          * firmware to host comm points to CQ[n to m+1]
     219                 :            :          */
     220                 :          0 :         err_intr_enable = 1;
     221                 :          0 :         err_intr_offset = snic->err_intr_offset;
     222                 :            : 
     223         [ #  # ]:          0 :         for (i = 0; i < snic->wq_count; i++) {
     224                 :          0 :                 svnic_wq_init(&snic->wq[i],
     225                 :            :                               i,
     226                 :            :                               err_intr_enable,
     227                 :            :                               err_intr_offset);
     228                 :            :         }
     229                 :            : 
     230         [ #  # ]:          0 :         for (i = 0; i < snic->cq_count; i++) {
     231                 :          0 :                 intr_offset = i;
     232                 :            : 
     233                 :          0 :                 svnic_cq_init(&snic->cq[i],
     234                 :            :                               0 /* flow_control_enable */,
     235                 :            :                               1 /* color_enable */,
     236                 :            :                               0 /* cq_head */,
     237                 :            :                               0 /* cq_tail */,
     238                 :            :                               1 /* cq_tail_color */,
     239                 :            :                               1 /* interrupt_enable */,
     240                 :            :                               1 /* cq_entry_enable */,
     241                 :            :                               0 /* cq_message_enable */,
     242                 :            :                               intr_offset,
     243                 :            :                               0 /* cq_message_addr */);
     244                 :            :         }
     245                 :            : 
     246                 :            :         /*
     247                 :            :          * Init INTR resources
     248                 :            :          * Assumption : snic is always in MSI-X mode
     249                 :            :          */
     250         [ #  # ]:          0 :         SNIC_BUG_ON(intr_mode != VNIC_DEV_INTR_MODE_MSIX);
     251                 :            :         mask_on_assertion = 1;
     252                 :            : 
     253         [ #  # ]:          0 :         for (i = 0; i < snic->intr_count; i++) {
     254                 :          0 :                 svnic_intr_init(&snic->intr[i],
     255                 :          0 :                                 snic->config.intr_timer,
     256                 :          0 :                                 snic->config.intr_timer_type,
     257                 :            :                                 mask_on_assertion);
     258                 :            :         }
     259                 :            : 
     260                 :            :         /* init the stats memory by making the first call here */
     261                 :          0 :         ret = svnic_dev_stats_dump(snic->vdev, &snic->stats);
     262         [ #  # ]:          0 :         if (ret) {
     263                 :          0 :                 SNIC_HOST_ERR(snic->shost,
     264                 :            :                               "svnic_dev_stats_dump failed - x%x\n",
     265                 :            :                               ret);
     266                 :          0 :                 goto error_cleanup;
     267                 :            :         }
     268                 :            : 
     269                 :            :         /* Clear LIF stats */
     270                 :          0 :         svnic_dev_stats_clear(snic->vdev);
     271                 :          0 :         ret = 0;
     272                 :            : 
     273                 :          0 :         return ret;
     274                 :            : 
     275                 :          0 : error_cleanup:
     276                 :          0 :         snic_free_vnic_res(snic);
     277                 :            : 
     278                 :          0 :         return ret;
     279                 :            : }
     280                 :            : 
     281                 :            : void
     282                 :          0 : snic_log_q_error(struct snic *snic)
     283                 :            : {
     284                 :          0 :         unsigned int i;
     285                 :          0 :         u32 err_status;
     286                 :            : 
     287         [ #  # ]:          0 :         for (i = 0; i < snic->wq_count; i++) {
     288                 :          0 :                 err_status = ioread32(&snic->wq[i].ctrl->error_status);
     289         [ #  # ]:          0 :                 if (err_status)
     290                 :          0 :                         SNIC_HOST_ERR(snic->shost,
     291                 :            :                                       "WQ[%d] error status %d\n",
     292                 :            :                                       i,
     293                 :            :                                       err_status);
     294                 :            :         }
     295                 :          0 : } /* end of snic_log_q_error */

Generated by: LCOV version 1.14