This source file includes following definitions.
- ice_aq_read_nvm
- ice_check_sr_access_params
- ice_read_sr_aq
- ice_read_sr_word_aq
- ice_read_sr_buf_aq
- ice_acquire_nvm
- ice_release_nvm
- ice_read_sr_word
- ice_init_nvm
- ice_read_sr_buf
- ice_nvm_validate_checksum
1
2
3
4 #include "ice_common.h"
5
6
7
8
9
10
11
12
13
14
15
16
17
18 static enum ice_status
19 ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
20 void *data, bool last_command, struct ice_sq_cd *cd)
21 {
22 struct ice_aq_desc desc;
23 struct ice_aqc_nvm *cmd;
24
25 cmd = &desc.params.nvm;
26
27
28 if (offset & 0xFF000000)
29 return ICE_ERR_PARAM;
30
31 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
32
33
34 if (last_command)
35 cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
36 cmd->module_typeid = cpu_to_le16(module_typeid);
37 cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
38 cmd->offset_high = (offset >> 16) & 0xFF;
39 cmd->length = cpu_to_le16(length);
40
41 return ice_aq_send_cmd(hw, &desc, data, length, cd);
42 }
43
44
45
46
47
48
49
50 static enum ice_status
51 ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words)
52 {
53 if ((offset + words) > hw->nvm.sr_words) {
54 ice_debug(hw, ICE_DBG_NVM,
55 "NVM error: offset beyond SR lmt.\n");
56 return ICE_ERR_PARAM;
57 }
58
59 if (words > ICE_SR_SECTOR_SIZE_IN_WORDS) {
60
61 ice_debug(hw, ICE_DBG_NVM,
62 "NVM error: tried to access %d words, limit is %d.\n",
63 words, ICE_SR_SECTOR_SIZE_IN_WORDS);
64 return ICE_ERR_PARAM;
65 }
66
67 if (((offset + (words - 1)) / ICE_SR_SECTOR_SIZE_IN_WORDS) !=
68 (offset / ICE_SR_SECTOR_SIZE_IN_WORDS)) {
69
70 ice_debug(hw, ICE_DBG_NVM,
71 "NVM error: cannot spread over two sectors.\n");
72 return ICE_ERR_PARAM;
73 }
74
75 return 0;
76 }
77
78
79
80
81
82
83
84
85
86
87
88 static enum ice_status
89 ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, u16 *data,
90 bool last_command)
91 {
92 enum ice_status status;
93
94 status = ice_check_sr_access_params(hw, offset, words);
95
96
97
98
99
100 if (!status)
101 status = ice_aq_read_nvm(hw, 0, 2 * offset, 2 * words, data,
102 last_command, NULL);
103
104 return status;
105 }
106
107
108
109
110
111
112
113
114
115 static enum ice_status
116 ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
117 {
118 enum ice_status status;
119
120 status = ice_read_sr_aq(hw, offset, 1, data, true);
121 if (!status)
122 *data = le16_to_cpu(*(__force __le16 *)data);
123
124 return status;
125 }
126
127
128
129
130
131
132
133
134
135
136
137
138 static enum ice_status
139 ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
140 {
141 enum ice_status status;
142 bool last_cmd = false;
143 u16 words_read = 0;
144 u16 i = 0;
145
146 do {
147 u16 read_size, off_w;
148
149
150
151
152
153 off_w = offset % ICE_SR_SECTOR_SIZE_IN_WORDS;
154 read_size = off_w ?
155 min_t(u16, *words,
156 (ICE_SR_SECTOR_SIZE_IN_WORDS - off_w)) :
157 min_t(u16, (*words - words_read),
158 ICE_SR_SECTOR_SIZE_IN_WORDS);
159
160
161 if ((words_read + read_size) >= *words)
162 last_cmd = true;
163
164 status = ice_read_sr_aq(hw, offset, read_size,
165 data + words_read, last_cmd);
166 if (status)
167 goto read_nvm_buf_aq_exit;
168
169
170
171
172 words_read += read_size;
173 offset += read_size;
174 } while (words_read < *words);
175
176 for (i = 0; i < *words; i++)
177 data[i] = le16_to_cpu(((__force __le16 *)data)[i]);
178
179 read_nvm_buf_aq_exit:
180 *words = words_read;
181 return status;
182 }
183
184
185
186
187
188
189
190
191 static enum ice_status
192 ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
193 {
194 if (hw->nvm.blank_nvm_mode)
195 return 0;
196
197 return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
198 }
199
200
201
202
203
204
205
206 static void ice_release_nvm(struct ice_hw *hw)
207 {
208 if (hw->nvm.blank_nvm_mode)
209 return;
210
211 ice_release_res(hw, ICE_NVM_RES_ID);
212 }
213
214
215
216
217
218
219
220
221
222 static enum ice_status
223 ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
224 {
225 enum ice_status status;
226
227 status = ice_acquire_nvm(hw, ICE_RES_READ);
228 if (!status) {
229 status = ice_read_sr_word_aq(hw, offset, data);
230 ice_release_nvm(hw);
231 }
232
233 return status;
234 }
235
236
237
238
239
240
241
242
243 enum ice_status ice_init_nvm(struct ice_hw *hw)
244 {
245 struct ice_nvm_info *nvm = &hw->nvm;
246 u16 eetrack_lo, eetrack_hi;
247 enum ice_status status = 0;
248 u32 fla, gens_stat;
249 u8 sr_size;
250
251
252
253
254 gens_stat = rd32(hw, GLNVM_GENS);
255 sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
256
257
258 nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
259
260
261 fla = rd32(hw, GLNVM_FLA);
262 if (fla & GLNVM_FLA_LOCKED_M) {
263 nvm->blank_nvm_mode = false;
264 } else {
265 nvm->blank_nvm_mode = true;
266 status = ICE_ERR_NVM_BLANK_MODE;
267 ice_debug(hw, ICE_DBG_NVM,
268 "NVM init error: unsupported blank mode.\n");
269 return status;
270 }
271
272 status = ice_read_sr_word(hw, ICE_SR_NVM_DEV_STARTER_VER, &hw->nvm.ver);
273 if (status) {
274 ice_debug(hw, ICE_DBG_INIT,
275 "Failed to read DEV starter version.\n");
276 return status;
277 }
278
279 status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
280 if (status) {
281 ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK lo.\n");
282 return status;
283 }
284 status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
285 if (status) {
286 ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK hi.\n");
287 return status;
288 }
289
290 hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
291
292 return status;
293 }
294
295
296
297
298
299
300
301
302
303
304
305
306 enum ice_status
307 ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
308 {
309 enum ice_status status;
310
311 status = ice_acquire_nvm(hw, ICE_RES_READ);
312 if (!status) {
313 status = ice_read_sr_buf_aq(hw, offset, words, data);
314 ice_release_nvm(hw);
315 }
316
317 return status;
318 }
319
320
321
322
323
324
325
326 enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
327 {
328 struct ice_aqc_nvm_checksum *cmd;
329 struct ice_aq_desc desc;
330 enum ice_status status;
331
332 status = ice_acquire_nvm(hw, ICE_RES_READ);
333 if (status)
334 return status;
335
336 cmd = &desc.params.nvm_checksum;
337
338 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
339 cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY;
340
341 status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
342 ice_release_nvm(hw);
343
344 if (!status)
345 if (le16_to_cpu(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT)
346 status = ICE_ERR_NVM_CHECKSUM;
347
348 return status;
349 }