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 #include <sys/stream.h> 35 #include <sys/dlpi.h> 36 37 #include "sfxge.h" 38 39 void 40 sfxge_sram_init(sfxge_t *sp) 41 { 42 sfxge_sram_t *ssp = &(sp->s_sram); 43 dev_info_t *dip = sp->s_dip; 44 char name[MAXNAMELEN]; 45 46 ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_UNINITIALIZED); 47 48 mutex_init(&(ssp->ss_lock), NULL, MUTEX_DRIVER, NULL); 49 50 /* 51 * Create a VMEM arena for the buffer table 52 * Note that these are not in the DDI/DKI. 53 * See "man rmalloc" for a possible alternative 54 */ 55 (void) snprintf(name, MAXNAMELEN - 1, "%s%d_sram", ddi_driver_name(dip), 56 ddi_get_instance(dip)); 57 ssp->ss_buf_tbl = vmem_create(name, (void *)1, EFX_BUF_TBL_SIZE, 1, 58 NULL, NULL, NULL, 1, VM_SLEEP | VMC_IDENTIFIER); 59 60 ssp->ss_state = SFXGE_SRAM_INITIALIZED; 61 } 62 63 int 64 sfxge_sram_buf_tbl_alloc(sfxge_t *sp, size_t n, uint32_t *idp) 65 { 66 sfxge_sram_t *ssp = &(sp->s_sram); 67 void *base; 68 int rc; 69 70 mutex_enter(&(ssp->ss_lock)); 71 72 ASSERT(ssp->ss_state != SFXGE_SRAM_UNINITIALIZED); 73 74 if ((base = vmem_alloc(ssp->ss_buf_tbl, n, VM_NOSLEEP)) == NULL) { 75 rc = ENOSPC; 76 goto fail1; 77 } 78 79 *idp = (uint32_t)((uintptr_t)base - 1); 80 81 mutex_exit(&(ssp->ss_lock)); 82 83 return (0); 84 85 fail1: 86 DTRACE_PROBE1(fail1, int, rc); 87 88 mutex_exit(&(ssp->ss_lock)); 89 90 return (rc); 91 } 92 93 int 94 sfxge_sram_start(sfxge_t *sp) 95 { 96 sfxge_sram_t *ssp = &(sp->s_sram); 97 98 mutex_enter(&(ssp->ss_lock)); 99 100 ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_INITIALIZED); 101 ASSERT3U(ssp->ss_count, ==, 0); 102 103 ssp->ss_state = SFXGE_SRAM_STARTED; 104 105 mutex_exit(&(ssp->ss_lock)); 106 107 return (0); 108 } 109 110 int 111 sfxge_sram_buf_tbl_set(sfxge_t *sp, uint32_t id, efsys_mem_t *esmp, 112 size_t n) 113 { 114 sfxge_sram_t *ssp = &(sp->s_sram); 115 int rc; 116 117 mutex_enter(&(ssp->ss_lock)); 118 119 ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED); 120 121 if ((rc = efx_sram_buf_tbl_set(sp->s_enp, id, esmp, n)) != 0) 122 goto fail1; 123 124 ssp->ss_count += n; 125 126 mutex_exit(&(ssp->ss_lock)); 127 128 return (0); 129 130 fail1: 131 DTRACE_PROBE1(fail1, int, rc); 132 133 mutex_exit(&(ssp->ss_lock)); 134 135 return (rc); 136 } 137 138 void 139 sfxge_sram_buf_tbl_clear(sfxge_t *sp, uint32_t id, size_t n) 140 { 141 sfxge_sram_t *ssp = &(sp->s_sram); 142 143 mutex_enter(&(ssp->ss_lock)); 144 145 ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED); 146 147 ASSERT3U(ssp->ss_count, >=, n); 148 ssp->ss_count -= n; 149 150 efx_sram_buf_tbl_clear(sp->s_enp, id, n); 151 152 mutex_exit(&(ssp->ss_lock)); 153 } 154 155 void 156 sfxge_sram_stop(sfxge_t *sp) 157 { 158 sfxge_sram_t *ssp = &(sp->s_sram); 159 160 mutex_enter(&(ssp->ss_lock)); 161 162 ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_STARTED); 163 ASSERT3U(ssp->ss_count, ==, 0); 164 165 ssp->ss_state = SFXGE_SRAM_INITIALIZED; 166 167 mutex_exit(&(ssp->ss_lock)); 168 } 169 170 void 171 sfxge_sram_buf_tbl_free(sfxge_t *sp, uint32_t id, size_t n) 172 { 173 sfxge_sram_t *ssp = &(sp->s_sram); 174 void *base; 175 176 mutex_enter(&(ssp->ss_lock)); 177 178 ASSERT(ssp->ss_state != SFXGE_SRAM_UNINITIALIZED); 179 180 base = (void *)((uintptr_t)id + 1); 181 vmem_free(ssp->ss_buf_tbl, base, n); 182 183 mutex_exit(&(ssp->ss_lock)); 184 } 185 186 void 187 sfxge_sram_fini(sfxge_t *sp) 188 { 189 sfxge_sram_t *ssp = &(sp->s_sram); 190 191 ASSERT3U(ssp->ss_state, ==, SFXGE_SRAM_INITIALIZED); 192 193 /* Destroy the VMEM arena */ 194 vmem_destroy(ssp->ss_buf_tbl); 195 ssp->ss_buf_tbl = NULL; 196 197 mutex_destroy(&(ssp->ss_lock)); 198 199 ssp->ss_state = SFXGE_SRAM_UNINITIALIZED; 200 }