sfxge_nvram.c revision 284555
1239671Srwatson/*- 2239671Srwatson * Copyright (c) 2010-2015 Solarflare Communications, Inc. 3244899Srwatson * All rights reserved. 4239671Srwatson * 5239671Srwatson * This software was developed in part by OKTET Labs Ltd. under contract for 6244899Srwatson * Solarflare Communications, Inc. 7244899Srwatson * 8244899Srwatson * Redistribution and use in source and binary forms, with or without 9244899Srwatson * modification, are permitted provided that the following conditions 10239671Srwatson * are met: 11239671Srwatson * 1. Redistributions of source code must retain the above copyright 12239671Srwatson * notice, this list of conditions and the following disclaimer. 13239671Srwatson * 2. Redistributions in binary form must reproduce the above copyright 14239671Srwatson * notice, this list of conditions and the following disclaimer in the 15239671Srwatson * documentation and/or other materials provided with the distribution. 16239671Srwatson * 17239671Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18239671Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19239671Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20239671Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21239671Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22239671Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23239671Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24239671Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25239671Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26239671Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27239671Srwatson * SUCH DAMAGE. 28239671Srwatson */ 29239671Srwatson 30239671Srwatson#include <sys/cdefs.h> 31239671Srwatson__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/sfxge_nvram.c 284555 2015-06-18 15:46:39Z arybchik $"); 32239671Srwatson 33239671Srwatson 34239671Srwatson#include <sys/types.h> 35244899Srwatson#include <sys/malloc.h> 36239671Srwatson 37239671Srwatson#include "common/efx.h" 38239671Srwatson#include "sfxge.h" 39239671Srwatson 40239671Srwatson/* These data make no real sense, they are here just to make sfupdate happy. 41239671Srwatson * Any code that would rely on it is broken. 42239671Srwatson */ 43239671Srwatsonstatic const uint8_t fake_dynamic_cfg_nvram[] = { 44239671Srwatson 0x7a, 0xda, 0x10, 0xef, 0x0c, 0x00, 0x00, 0x00, 45239671Srwatson 0x00, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 46239671Srwatson 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 47239671Srwatson 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x52, 48245330Srwatson 0x56, 0x01, 0xc3, 0x78, 0x01, 0x00, 0x03, 0x10, 49239671Srwatson 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x52, 50239671Srwatson 0x56, 0x01, 0xc3, 0x78, 0x57, 0x1a, 0x10, 0xef, 51239671Srwatson 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 52239671Srwatson 0x02, 0x0b, 0x64, 0x7d, 0xee, 0xee, 0xee, 0xee 53239671Srwatson}; 54239671Srwatson 55239671Srwatsonstatic int 56239671Srwatsonsfxge_nvram_rw(struct sfxge_softc *sc, sfxge_ioc_t *ip, efx_nvram_type_t type, 57239671Srwatson boolean_t write) 58239671Srwatson{ 59244942Srwatson efx_nic_t *enp = sc->enp; 60244899Srwatson size_t total_size = ip->u.nvram.size; 61244899Srwatson size_t chunk_size; 62244942Srwatson off_t off; 63244899Srwatson int rc = 0; 64239671Srwatson uint8_t *buf; 65239671Srwatson 66239671Srwatson if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) { 67239671Srwatson if (write) 68239671Srwatson return (0); 69239671Srwatson rc = copyout(fake_dynamic_cfg_nvram, ip->u.nvram.data, 70239671Srwatson MIN(total_size, sizeof(fake_dynamic_cfg_nvram))); 71239671Srwatson return (rc); 72239671Srwatson } 73245330Srwatson 74239671Srwatson if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0) 75239671Srwatson goto fail1; 76239671Srwatson 77239671Srwatson buf = malloc(chunk_size, M_TEMP, M_WAITOK); 78239671Srwatson if (buf == NULL) { 79239671Srwatson rc = ENOMEM; 80239671Srwatson goto fail2; 81239671Srwatson } 82239671Srwatson 83239671Srwatson off = 0; 84239671Srwatson while (total_size) { 85239671Srwatson size_t len = MIN(chunk_size, total_size); 86239671Srwatson 87239671Srwatson if (write) { 88239671Srwatson rc = copyin(ip->u.nvram.data + off, buf, len); 89239671Srwatson if (rc != 0) 90239671Srwatson goto fail3; 91239671Srwatson rc = efx_nvram_write_chunk(enp, type, 92239671Srwatson ip->u.nvram.offset + off, buf, len); 93239671Srwatson if (rc != 0) 94239671Srwatson goto fail3; 95239671Srwatson } else { 96239671Srwatson rc = efx_nvram_read_chunk(enp, type, 97239671Srwatson ip->u.nvram.offset + off, buf, len); 98239671Srwatson if (rc != 0) 99239671Srwatson goto fail3; 100239671Srwatson rc = copyout(buf, ip->u.nvram.data + off, len); 101239671Srwatson if (rc != 0) 102239671Srwatson goto fail3; 103239671Srwatson } 104239671Srwatson 105239671Srwatson total_size -= len; 106239671Srwatson off += len; 107239671Srwatson } 108239671Srwatson 109239671Srwatsonfail3: 110239671Srwatson free(buf, M_TEMP); 111239671Srwatsonfail2: 112239671Srwatson efx_nvram_rw_finish(enp, type); 113239671Srwatsonfail1: 114239671Srwatson return (rc); 115239671Srwatson} 116239671Srwatson 117239671Srwatson 118239671Srwatsonstatic int 119239671Srwatsonsfxge_nvram_erase(struct sfxge_softc *sc, efx_nvram_type_t type) 120239671Srwatson{ 121239671Srwatson efx_nic_t *enp = sc->enp; 122239671Srwatson size_t chunk_size; 123239671Srwatson int rc = 0; 124261274Sbrooks 125261274Sbrooks if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) 126261274Sbrooks return (0); 127261274Sbrooks 128261274Sbrooks if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0) 129261274Sbrooks return (rc); 130261274Sbrooks 131261274Sbrooks rc = efx_nvram_erase(enp, type); 132239671Srwatson 133239671Srwatson efx_nvram_rw_finish(enp, type); 134270058Sbz return (rc); 135270058Sbz} 136270058Sbz 137270058Sbzint 138270058Sbzsfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip) 139270058Sbz{ 140270058Sbz static const efx_nvram_type_t nvram_types[] = { 141270058Sbz [SFXGE_NVRAM_TYPE_BOOTROM] = EFX_NVRAM_BOOTROM, 142270058Sbz [SFXGE_NVRAM_TYPE_BOOTROM_CFG] = EFX_NVRAM_BOOTROM_CFG, 143270058Sbz [SFXGE_NVRAM_TYPE_MC] = EFX_NVRAM_MC_FIRMWARE, 144270058Sbz [SFXGE_NVRAM_TYPE_MC_GOLDEN] = EFX_NVRAM_MC_GOLDEN, 145270058Sbz [SFXGE_NVRAM_TYPE_PHY] = EFX_NVRAM_PHY, 146270058Sbz [SFXGE_NVRAM_TYPE_NULL_PHY] = EFX_NVRAM_NULLPHY, 147270058Sbz [SFXGE_NVRAM_TYPE_FPGA] = EFX_NVRAM_FPGA, 148270058Sbz [SFXGE_NVRAM_TYPE_FCFW] = EFX_NVRAM_FCFW, 149270058Sbz [SFXGE_NVRAM_TYPE_CPLD] = EFX_NVRAM_CPLD, 150270058Sbz [SFXGE_NVRAM_TYPE_FPGA_BACKUP] = EFX_NVRAM_FPGA_BACKUP, 151270058Sbz [SFXGE_NVRAM_TYPE_DYNAMIC_CFG] = EFX_NVRAM_DYNAMIC_CFG, 152270058Sbz }; 153270058Sbz 154270058Sbz efx_nic_t *enp = sc->enp; 155270058Sbz efx_nvram_type_t type; 156270058Sbz int rc = 0; 157270058Sbz 158270058Sbz if (ip->u.nvram.type > SFXGE_NVRAM_TYPE_DYNAMIC_CFG) 159270058Sbz return (EINVAL); 160270058Sbz type = nvram_types[ip->u.nvram.type]; 161270058Sbz if (type == EFX_NVRAM_MC_GOLDEN && 162270058Sbz (ip->u.nvram.op == SFXGE_NVRAM_OP_WRITE || 163270058Sbz ip->u.nvram.op == SFXGE_NVRAM_OP_ERASE || 164270058Sbz ip->u.nvram.op == SFXGE_NVRAM_OP_SET_VER)) 165270058Sbz return (EOPNOTSUPP); 166270058Sbz 167270058Sbz switch (ip->u.nvram.op) { 168270058Sbz case SFXGE_NVRAM_OP_SIZE: 169270058Sbz { 170270058Sbz size_t size; 171270058Sbz 172270058Sbz if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) { 173270058Sbz ip->u.nvram.size = sizeof(fake_dynamic_cfg_nvram); 174239671Srwatson } else { 175239671Srwatson if ((rc = efx_nvram_size(enp, type, &size)) != 0) 176239671Srwatson return (rc); 177239671Srwatson ip->u.nvram.size = size; 178239671Srwatson } 179239671Srwatson break; 180239671Srwatson } 181239671Srwatson case SFXGE_NVRAM_OP_READ: 182239671Srwatson rc = sfxge_nvram_rw(sc, ip, type, B_FALSE); 183239671Srwatson break; 184245330Srwatson case SFXGE_NVRAM_OP_WRITE: 185270058Sbz rc = sfxge_nvram_rw(sc, ip, type, B_TRUE); 186245330Srwatson break; 187270058Sbz case SFXGE_NVRAM_OP_ERASE: 188245330Srwatson rc = sfxge_nvram_erase(sc, type); 189245330Srwatson break; 190239671Srwatson case SFXGE_NVRAM_OP_GET_VER: 191239671Srwatson rc = efx_nvram_get_version(enp, type, &ip->u.nvram.subtype, 192239671Srwatson &ip->u.nvram.version[0]); 193239671Srwatson break; 194239671Srwatson case SFXGE_NVRAM_OP_SET_VER: 195239671Srwatson rc = efx_nvram_set_version(enp, type, &ip->u.nvram.version[0]); 196239671Srwatson break; 197239671Srwatson default: 198239671Srwatson rc = EOPNOTSUPP; 199239671Srwatson break; 200245329Srwatson } 201245330Srwatson 202245330Srwatson return (rc); 203245330Srwatson} 204245330Srwatson