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 }