1 /*
   2  * Copyright (c) 2008-2015 Solarflare Communications Inc.
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions are met:
   7  *
   8  * 1. Redistributions of source code must retain the above copyright notice,
   9  *    this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright notice,
  11  *    this list of conditions and the following disclaimer in the documentation
  12  *    and/or other materials provided with the distribution.
  13  *
  14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25  *
  26  * The views and conclusions contained in the software and documentation are
  27  * those of the authors and should not be interpreted as representing official
  28  * policies, either expressed or implied, of the FreeBSD Project.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/ddi.h>
  33 #include <sys/sunddi.h>
  34 
  35 #include "sfxge.h"
  36 
  37 void
  38 sfxge_sram_init(sfxge_t *sp)
  39 {
  40         sfxge_sram_t *ssp = &(sp->s_sram);
  41         dev_info_t *dip = sp->s_dip;
  42         char name[MAXNAMELEN];
  43 
  44         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_UNINITIALIZED);
  45 
  46         mutex_init(&(ssp->ss_lock), NULL, MUTEX_DRIVER, NULL);
  47 
  48         (void) snprintf(name, MAXNAMELEN - 1, "%s%d_sram", ddi_driver_name(dip),
  49             ddi_get_instance(dip));
  50         ssp->ss_buf_tbl_ids = id_space_create(name, 1, EFX_BUF_TBL_SIZE);
  51         ssp->ss_state = SFXGE_SRAM_INITIALIZED;
  52 }
  53 
  54 int
  55 sfxge_sram_buf_tbl_alloc(sfxge_t *sp, size_t n, uint32_t *idp)
  56 {
  57         sfxge_sram_t *ssp = &(sp->s_sram);
  58         id_t id;
  59         int rc;
  60 
  61         mutex_enter(&(ssp->ss_lock));
  62 
  63         ASSERT(ssp->ss_state != SFXGE_SRAM_UNINITIALIZED);
  64 
  65         if ((id = id_alloc_nosleep(ssp->ss_buf_tbl_ids)) < 0) {
  66                 rc = ENOSPC;
  67                 goto fail1;
  68         }
  69         *idp = (uint32_t)id;
  70         mutex_exit(&(ssp->ss_lock));
  71 
  72         return (0);
  73 
  74 fail1:
  75         DTRACE_PROBE1(fail1, int, rc);
  76 
  77         mutex_exit(&(ssp->ss_lock));
  78 
  79         return (rc);
  80 }
  81 
  82 int
  83 sfxge_sram_start(sfxge_t *sp)
  84 {
  85         sfxge_sram_t *ssp = &(sp->s_sram);
  86 
  87         mutex_enter(&(ssp->ss_lock));
  88 
  89         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_INITIALIZED);
  90         ASSERT3U(ssp->ss_count, ==, 0);
  91 
  92         ssp->ss_state = SFXGE_SRAM_STARTED;
  93 
  94         mutex_exit(&(ssp->ss_lock));
  95 
  96         return (0);
  97 }
  98 
  99 int
 100 sfxge_sram_buf_tbl_set(sfxge_t *sp, uint32_t id, efsys_mem_t *esmp,
 101     size_t n)
 102 {
 103         sfxge_sram_t *ssp = &(sp->s_sram);
 104         int rc;
 105 
 106         mutex_enter(&(ssp->ss_lock));
 107 
 108         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED);
 109 
 110         if ((rc = efx_sram_buf_tbl_set(sp->s_enp, id, esmp, n)) != 0)
 111                 goto fail1;
 112 
 113         ssp->ss_count += n;
 114 
 115         mutex_exit(&(ssp->ss_lock));
 116 
 117         return (0);
 118 
 119 fail1:
 120         DTRACE_PROBE1(fail1, int, rc);
 121 
 122         mutex_exit(&(ssp->ss_lock));
 123 
 124         return (rc);
 125 }
 126 
 127 void
 128 sfxge_sram_buf_tbl_clear(sfxge_t *sp, uint32_t id, size_t n)
 129 {
 130         sfxge_sram_t *ssp = &(sp->s_sram);
 131 
 132         mutex_enter(&(ssp->ss_lock));
 133 
 134         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED);
 135 
 136         ASSERT3U(ssp->ss_count, >=, n);
 137         ssp->ss_count -= n;
 138 
 139         efx_sram_buf_tbl_clear(sp->s_enp, id, n);
 140 
 141         mutex_exit(&(ssp->ss_lock));
 142 }
 143 
 144 void
 145 sfxge_sram_stop(sfxge_t *sp)
 146 {
 147         sfxge_sram_t *ssp = &(sp->s_sram);
 148 
 149         mutex_enter(&(ssp->ss_lock));
 150 
 151         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED);
 152         ASSERT3U(ssp->ss_count, ==, 0);
 153 
 154         ssp->ss_state = SFXGE_SRAM_INITIALIZED;
 155 
 156         mutex_exit(&(ssp->ss_lock));
 157 }
 158 
 159 void
 160 sfxge_sram_buf_tbl_free(sfxge_t *sp, uint32_t id, size_t n)
 161 {
 162         sfxge_sram_t *ssp = &(sp->s_sram);
 163 
 164         mutex_enter(&(ssp->ss_lock));
 165 
 166         ASSERT(ssp->ss_state != SFXGE_SRAM_UNINITIALIZED);
 167 
 168         id_free(ssp->ss_buf_tbl_ids, (id_t)id);
 169 
 170         mutex_exit(&(ssp->ss_lock));
 171 }
 172 
 173 void
 174 sfxge_sram_fini(sfxge_t *sp)
 175 {
 176         sfxge_sram_t *ssp = &(sp->s_sram);
 177 
 178         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_INITIALIZED);
 179 
 180         id_space_destroy(ssp->ss_buf_tbl_ids);
 181         ssp->ss_buf_tbl_ids = NULL;
 182 
 183         mutex_destroy(&(ssp->ss_lock));
 184 
 185         ssp->ss_state = SFXGE_SRAM_UNINITIALIZED;
 186 }