1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Solarflare Communications Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 #include <sys/stream.h> 31 #include <sys/dlpi.h> 32 33 #include "sfxge.h" 34 35 int 36 sfxge_nvram_rw(sfxge_t *sp, sfxge_nvram_ioc_t *snip, efx_nvram_type_t type, 37 boolean_t write) 38 { 39 int (*op)(efx_nic_t *, efx_nvram_type_t, unsigned int, caddr_t, size_t); 40 efx_nic_t *enp = sp->s_enp; 41 size_t chunk_size; 42 off_t off; 43 int rc; 44 45 op = (write) ? efx_nvram_write_chunk : efx_nvram_read_chunk; 46 47 if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0) 48 goto fail1; 49 50 off = 0; 51 while (snip->sni_size) { 52 size_t len = MIN(chunk_size, snip->sni_size); 53 caddr_t buf = (caddr_t)(&snip->sni_data[off]); 54 55 if ((rc = op(enp, type, snip->sni_offset + off, buf, len)) != 0) 56 goto fail2; 57 58 snip->sni_size -= len; 59 off += len; 60 } 61 62 efx_nvram_rw_finish(enp, type); 63 return (0); 64 65 fail2: 66 DTRACE_PROBE(fail2); 67 efx_nvram_rw_finish(enp, type); 68 fail1: 69 DTRACE_PROBE1(fail1, int, rc); 70 return (rc); 71 } 72 73 74 int 75 sfxge_nvram_erase(sfxge_t *sp, sfxge_nvram_ioc_t *snip, efx_nvram_type_t type) 76 { 77 efx_nic_t *enp = sp->s_enp; 78 size_t chunk_size; 79 int rc; 80 81 if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0) 82 goto fail1; 83 84 if ((rc = efx_nvram_erase(enp, type)) != 0) 85 goto fail2; 86 87 efx_nvram_rw_finish(enp, type); 88 return (0); 89 90 fail2: 91 DTRACE_PROBE(fail2); 92 efx_nvram_rw_finish(enp, type); 93 fail1: 94 DTRACE_PROBE1(fail1, int, rc); 95 return (rc); 96 } 97 98 int 99 sfxge_nvram_ioctl(sfxge_t *sp, sfxge_nvram_ioc_t *snip) 100 { 101 efx_nic_t *enp = sp->s_enp; 102 efx_nvram_type_t type; 103 int rc; 104 105 if (snip->sni_type == SFXGE_NVRAM_TYPE_MC_GOLDEN && 106 (snip->sni_op == SFXGE_NVRAM_OP_WRITE || 107 snip->sni_op == SFXGE_NVRAM_OP_ERASE || 108 snip->sni_op == SFXGE_NVRAM_OP_SET_VER)) { 109 rc = ENOTSUP; 110 goto fail4; 111 } 112 113 switch (snip->sni_type) { 114 case SFXGE_NVRAM_TYPE_BOOTROM: 115 type = EFX_NVRAM_BOOTROM; 116 break; 117 case SFXGE_NVRAM_TYPE_BOOTROM_CFG: 118 type = EFX_NVRAM_BOOTROM_CFG; 119 break; 120 case SFXGE_NVRAM_TYPE_MC: 121 type = EFX_NVRAM_MC_FIRMWARE; 122 break; 123 case SFXGE_NVRAM_TYPE_MC_GOLDEN: 124 type = EFX_NVRAM_MC_GOLDEN; 125 break; 126 case SFXGE_NVRAM_TYPE_PHY: 127 type = EFX_NVRAM_PHY; 128 break; 129 case SFXGE_NVRAM_TYPE_NULL_PHY: 130 type = EFX_NVRAM_NULLPHY; 131 break; 132 case SFXGE_NVRAM_TYPE_FPGA: /* PTP timestamping FPGA */ 133 type = EFX_NVRAM_FPGA; 134 break; 135 default: 136 rc = EINVAL; 137 goto fail1; 138 } 139 140 if (snip->sni_size > sizeof (snip->sni_data)) { 141 rc = ENOSPC; 142 goto fail2; 143 } 144 145 switch (snip->sni_op) { 146 case SFXGE_NVRAM_OP_SIZE: 147 { 148 size_t size; 149 if ((rc = efx_nvram_size(enp, type, &size)) != 0) 150 goto fail3; 151 snip->sni_size = size; 152 break; 153 } 154 case SFXGE_NVRAM_OP_READ: 155 if ((rc = sfxge_nvram_rw(sp, snip, type, B_FALSE)) != 0) 156 goto fail3; 157 break; 158 case SFXGE_NVRAM_OP_WRITE: 159 if ((rc = sfxge_nvram_rw(sp, snip, type, B_TRUE)) != 0) 160 goto fail3; 161 break; 162 case SFXGE_NVRAM_OP_ERASE: 163 if ((rc = sfxge_nvram_erase(sp, snip, type)) != 0) 164 goto fail3; 165 break; 166 case SFXGE_NVRAM_OP_GET_VER: 167 if ((rc = efx_nvram_get_version(enp, type, &snip->sni_subtype, 168 &snip->sni_version[0])) != 0) 169 goto fail3; 170 break; 171 case SFXGE_NVRAM_OP_SET_VER: 172 if ((rc = efx_nvram_set_version(enp, type, 173 &snip->sni_version[0])) != 0) 174 goto fail3; 175 break; 176 default: 177 rc = ENOTSUP; 178 goto fail4; 179 } 180 181 return (0); 182 183 fail4: 184 DTRACE_PROBE(fail4); 185 fail3: 186 DTRACE_PROBE(fail3); 187 fail2: 188 DTRACE_PROBE(fail2); 189 fail1: 190 DTRACE_PROBE1(fail1, int, rc); 191 192 return (rc); 193 }