1 /*
   2  * Copyright (c) 2008-2016 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_map = rmallocmap_wait(EFX_BUF_TBL_SIZE);
  51         rmfree(ssp->ss_buf_tbl_map, EFX_BUF_TBL_SIZE - 1, 1);
  52         ssp->ss_state = SFXGE_SRAM_INITIALIZED;
  53 }
  54 
  55 int
  56 sfxge_sram_buf_tbl_alloc(sfxge_t *sp, size_t n, uint32_t *idp)
  57 {
  58         sfxge_sram_t *ssp = &(sp->s_sram);
  59         unsigned long id;
  60         int rc;
  61 
  62         mutex_enter(&(ssp->ss_lock));
  63 
  64         ASSERT(ssp->ss_state != SFXGE_SRAM_UNINITIALIZED);
  65 
  66         if ((id = rmalloc(ssp->ss_buf_tbl_map, n)) == 0) {
  67                 rc = ENOSPC;
  68                 goto fail1;
  69         }
  70         *idp = (uint32_t)id - 1;
  71         mutex_exit(&(ssp->ss_lock));
  72 
  73         return (0);
  74 
  75 fail1:
  76         DTRACE_PROBE1(fail1, int, rc);
  77 
  78         mutex_exit(&(ssp->ss_lock));
  79 
  80         return (rc);
  81 }
  82 
  83 int
  84 sfxge_sram_start(sfxge_t *sp)
  85 {
  86         sfxge_sram_t *ssp = &(sp->s_sram);
  87 
  88         mutex_enter(&(ssp->ss_lock));
  89 
  90         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_INITIALIZED);
  91         ASSERT3U(ssp->ss_count, ==, 0);
  92 
  93         ssp->ss_state = SFXGE_SRAM_STARTED;
  94 
  95         mutex_exit(&(ssp->ss_lock));
  96 
  97         return (0);
  98 }
  99 
 100 int
 101 sfxge_sram_buf_tbl_set(sfxge_t *sp, uint32_t id, efsys_mem_t *esmp,
 102     size_t n)
 103 {
 104         sfxge_sram_t *ssp = &(sp->s_sram);
 105         int rc;
 106 
 107         mutex_enter(&(ssp->ss_lock));
 108 
 109         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED);
 110 
 111         if ((rc = efx_sram_buf_tbl_set(sp->s_enp, id, esmp, n)) != 0)
 112                 goto fail1;
 113 
 114         ssp->ss_count += n;
 115 
 116         mutex_exit(&(ssp->ss_lock));
 117 
 118         return (0);
 119 
 120 fail1:
 121         DTRACE_PROBE1(fail1, int, rc);
 122 
 123         mutex_exit(&(ssp->ss_lock));
 124 
 125         return (rc);
 126 }
 127 
 128 void
 129 sfxge_sram_buf_tbl_clear(sfxge_t *sp, uint32_t id, size_t n)
 130 {
 131         sfxge_sram_t *ssp = &(sp->s_sram);
 132 
 133         mutex_enter(&(ssp->ss_lock));
 134 
 135         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED);
 136 
 137         ASSERT3U(ssp->ss_count, >=, n);
 138         ssp->ss_count -= n;
 139 
 140         efx_sram_buf_tbl_clear(sp->s_enp, id, n);
 141 
 142         mutex_exit(&(ssp->ss_lock));
 143 }
 144 
 145 void
 146 sfxge_sram_stop(sfxge_t *sp)
 147 {
 148         sfxge_sram_t *ssp = &(sp->s_sram);
 149 
 150         mutex_enter(&(ssp->ss_lock));
 151 
 152         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED);
 153         ASSERT3U(ssp->ss_count, ==, 0);
 154 
 155         ssp->ss_state = SFXGE_SRAM_INITIALIZED;
 156 
 157         mutex_exit(&(ssp->ss_lock));
 158 }
 159 
 160 void
 161 sfxge_sram_buf_tbl_free(sfxge_t *sp, uint32_t id, size_t n)
 162 {
 163         sfxge_sram_t *ssp = &(sp->s_sram);
 164 
 165         mutex_enter(&(ssp->ss_lock));
 166 
 167         ASSERT(ssp->ss_state != SFXGE_SRAM_UNINITIALIZED);
 168 
 169         rmfree(ssp->ss_buf_tbl_map, n, (unsigned long)id + 1);
 170 
 171         mutex_exit(&(ssp->ss_lock));
 172 }
 173 
 174 void
 175 sfxge_sram_fini(sfxge_t *sp)
 176 {
 177         sfxge_sram_t *ssp = &(sp->s_sram);
 178 
 179         ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_INITIALIZED);
 180 
 181         rmfreemap(ssp->ss_buf_tbl_map);
 182         ssp->ss_buf_tbl_map = NULL;
 183 
 184         mutex_destroy(&(ssp->ss_lock));
 185 
 186         ssp->ss_state = SFXGE_SRAM_UNINITIALIZED;
 187 }