Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2001-2023 Intel Corporation
3 : : */
4 : :
5 : : #include "ice_common.h"
6 : :
7 : : #define GL_MNG_DEF_DEVID 0x000B611C
8 : :
9 : : /**
10 : : * ice_aq_read_nvm
11 : : * @hw: pointer to the HW struct
12 : : * @module_typeid: module pointer location in words from the NVM beginning
13 : : * @offset: byte offset from the module beginning
14 : : * @length: length of the section to be read (in bytes from the offset)
15 : : * @data: command buffer (size [bytes] = length)
16 : : * @last_command: tells if this is the last command in a series
17 : : * @read_shadow_ram: tell if this is a shadow RAM read
18 : : * @cd: pointer to command details structure or NULL
19 : : *
20 : : * Read the NVM using the admin queue commands (0x0701)
21 : : */
22 : : enum ice_status
23 : 0 : ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
24 : : void *data, bool last_command, bool read_shadow_ram,
25 : : struct ice_sq_cd *cd)
26 : : {
27 : : struct ice_aq_desc desc;
28 : : struct ice_aqc_nvm *cmd;
29 : :
30 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
31 : :
32 : : cmd = &desc.params.nvm;
33 : :
34 [ # # ]: 0 : if (offset > ICE_AQC_NVM_MAX_OFFSET)
35 : : return ICE_ERR_PARAM;
36 : :
37 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
38 : :
39 [ # # ]: 0 : if (!read_shadow_ram && module_typeid == ICE_AQC_NVM_START_POINT)
40 : 0 : cmd->cmd_flags |= ICE_AQC_NVM_FLASH_ONLY;
41 : :
42 : : /* If this is the last command in a series, set the proper flag. */
43 [ # # ]: 0 : if (last_command)
44 : 0 : cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
45 : 0 : cmd->module_typeid = CPU_TO_LE16(module_typeid);
46 : 0 : cmd->offset_low = CPU_TO_LE16(offset & 0xFFFF);
47 : 0 : cmd->offset_high = (offset >> 16) & 0xFF;
48 : 0 : cmd->length = CPU_TO_LE16(length);
49 : :
50 : 0 : return ice_aq_send_cmd(hw, &desc, data, length, cd);
51 : : }
52 : :
53 : : /**
54 : : * ice_read_flat_nvm - Read portion of NVM by flat offset
55 : : * @hw: pointer to the HW struct
56 : : * @offset: offset from beginning of NVM
57 : : * @length: (in) number of bytes to read; (out) number of bytes actually read
58 : : * @data: buffer to return data in (sized to fit the specified length)
59 : : * @read_shadow_ram: if true, read from shadow RAM instead of NVM
60 : : *
61 : : * Reads a portion of the NVM, as a flat memory space. This function correctly
62 : : * breaks read requests across Shadow RAM sectors and ensures that no single
63 : : * read request exceeds the maximum 4KB read for a single AdminQ command.
64 : : *
65 : : * Returns a status code on failure. Note that the data pointer may be
66 : : * partially updated if some reads succeed before a failure.
67 : : */
68 : : enum ice_status
69 : 0 : ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
70 : : bool read_shadow_ram)
71 : : {
72 : : enum ice_status status;
73 : 0 : u32 inlen = *length;
74 : : u32 bytes_read = 0;
75 : : bool last_cmd;
76 : :
77 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
78 : :
79 : 0 : *length = 0;
80 : :
81 : : /* Verify the length of the read if this is for the Shadow RAM */
82 [ # # # # ]: 0 : if (read_shadow_ram && ((offset + inlen) > (hw->flash.sr_words * 2u))) {
83 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "NVM error: requested data is beyond Shadow RAM limit\n");
84 : 0 : return ICE_ERR_PARAM;
85 : : }
86 : :
87 : : do {
88 : : u32 read_size, sector_offset;
89 : :
90 : : /* ice_aq_read_nvm cannot read more than 4KB at a time.
91 : : * Additionally, a read from the Shadow RAM may not cross over
92 : : * a sector boundary. Conveniently, the sector size is also
93 : : * 4KB.
94 : : */
95 : 0 : sector_offset = offset % ICE_AQ_MAX_BUF_LEN;
96 : 0 : read_size = MIN_T(u32, ICE_AQ_MAX_BUF_LEN - sector_offset,
97 : : inlen - bytes_read);
98 : :
99 : 0 : last_cmd = !(bytes_read + read_size < inlen);
100 : :
101 : : /* ice_aq_read_nvm takes the length as a u16. Our read_size is
102 : : * calculated using a u32, but the ICE_AQ_MAX_BUF_LEN maximum
103 : : * size guarantees that it will fit within the 2 bytes.
104 : : */
105 : 0 : status = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
106 : : offset, (u16)read_size,
107 : 0 : data + bytes_read, last_cmd,
108 : : read_shadow_ram, NULL);
109 [ # # ]: 0 : if (status)
110 : : break;
111 : :
112 : : bytes_read += read_size;
113 : 0 : offset += read_size;
114 [ # # ]: 0 : } while (!last_cmd);
115 : :
116 : 0 : *length = bytes_read;
117 : 0 : return status;
118 : : }
119 : :
120 : : /**
121 : : * ice_read_sr_word_aq - Reads Shadow RAM via AQ
122 : : * @hw: pointer to the HW structure
123 : : * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
124 : : * @data: word read from the Shadow RAM
125 : : *
126 : : * Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
127 : : */
128 : : static enum ice_status
129 : 0 : ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
130 : : {
131 : 0 : u32 bytes = sizeof(u16);
132 : : enum ice_status status;
133 : : __le16 data_local;
134 : :
135 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
136 : :
137 : : /* Note that ice_read_flat_nvm checks if the read is past the Shadow
138 : : * RAM size, and ensures we don't read across a Shadow RAM sector
139 : : * boundary
140 : : */
141 : 0 : status = ice_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
142 : : (_FORCE_ u8 *)&data_local, true);
143 [ # # ]: 0 : if (status)
144 : : return status;
145 : :
146 : 0 : *data = LE16_TO_CPU(data_local);
147 : 0 : return ICE_SUCCESS;
148 : : }
149 : :
150 : : /**
151 : : * ice_read_sr_buf_aq - Reads Shadow RAM buf via AQ
152 : : * @hw: pointer to the HW structure
153 : : * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
154 : : * @words: (in) number of words to read; (out) number of words actually read
155 : : * @data: words read from the Shadow RAM
156 : : *
157 : : * Reads 16 bit words (data buf) from the Shadow RAM. Ownership of the NVM is
158 : : * taken before reading the buffer and later released.
159 : : */
160 : : static enum ice_status
161 : 0 : ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
162 : : {
163 : 0 : u32 bytes = *words * 2, i;
164 : : enum ice_status status;
165 : :
166 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
167 : :
168 : : /* ice_read_flat_nvm takes into account the 4KB AdminQ and Shadow RAM
169 : : * sector restrictions necessary when reading from the NVM.
170 : : */
171 : 0 : status = ice_read_flat_nvm(hw, offset * 2, &bytes, (u8 *)data, true);
172 : :
173 : : /* Report the number of words successfully read */
174 : 0 : *words = (u16)(bytes / 2);
175 : :
176 : : /* Byte swap the words up to the amount we actually read */
177 : : for (i = 0; i < *words; i++)
178 : : data[i] = LE16_TO_CPU(((_FORCE_ __le16 *)data)[i]);
179 : :
180 : 0 : return status;
181 : : }
182 : :
183 : : /**
184 : : * ice_acquire_nvm - Generic request for acquiring the NVM ownership
185 : : * @hw: pointer to the HW structure
186 : : * @access: NVM access type (read or write)
187 : : *
188 : : * This function will request NVM ownership.
189 : : */
190 : : enum ice_status
191 : 0 : ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
192 : : {
193 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
194 : :
195 [ # # ]: 0 : if (hw->flash.blank_nvm_mode)
196 : : return ICE_SUCCESS;
197 : :
198 : 0 : return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
199 : : }
200 : :
201 : : /**
202 : : * ice_release_nvm - Generic request for releasing the NVM ownership
203 : : * @hw: pointer to the HW structure
204 : : *
205 : : * This function will release NVM ownership.
206 : : */
207 : 0 : void ice_release_nvm(struct ice_hw *hw)
208 : : {
209 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
210 : :
211 [ # # ]: 0 : if (hw->flash.blank_nvm_mode)
212 : : return;
213 : :
214 : 0 : ice_release_res(hw, ICE_NVM_RES_ID);
215 : : }
216 : :
217 : : /**
218 : : * ice_get_flash_bank_offset - Get offset into requested flash bank
219 : : * @hw: pointer to the HW structure
220 : : * @bank: whether to read from the active or inactive flash bank
221 : : * @module: the module to read from
222 : : *
223 : : * Based on the module, lookup the module offset from the beginning of the
224 : : * flash.
225 : : *
226 : : * Returns the flash offset. Note that a value of zero is invalid and must be
227 : : * treated as an error.
228 : : */
229 : 0 : static u32 ice_get_flash_bank_offset(struct ice_hw *hw, enum ice_bank_select bank, u16 module)
230 : : {
231 : : struct ice_bank_info *banks = &hw->flash.banks;
232 : : enum ice_flash_bank active_bank;
233 : : bool second_bank_active;
234 : : u32 offset, size;
235 : :
236 [ # # # # ]: 0 : switch (module) {
237 : 0 : case ICE_SR_1ST_NVM_BANK_PTR:
238 : 0 : offset = banks->nvm_ptr;
239 : 0 : size = banks->nvm_size;
240 : 0 : active_bank = banks->nvm_bank;
241 : 0 : break;
242 : 0 : case ICE_SR_1ST_OROM_BANK_PTR:
243 : 0 : offset = banks->orom_ptr;
244 : 0 : size = banks->orom_size;
245 : 0 : active_bank = banks->orom_bank;
246 : 0 : break;
247 : 0 : case ICE_SR_NETLIST_BANK_PTR:
248 : 0 : offset = banks->netlist_ptr;
249 : 0 : size = banks->netlist_size;
250 : 0 : active_bank = banks->netlist_bank;
251 : 0 : break;
252 : 0 : default:
253 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash module: 0x%04x\n", module);
254 : : return 0;
255 : : }
256 : :
257 [ # # # ]: 0 : switch (active_bank) {
258 : : case ICE_1ST_FLASH_BANK:
259 : : second_bank_active = false;
260 : : break;
261 : 0 : case ICE_2ND_FLASH_BANK:
262 : : second_bank_active = true;
263 : 0 : break;
264 : 0 : default:
265 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unexpected value for active flash bank: %u\n",
266 : : active_bank);
267 : : return 0;
268 : : }
269 : :
270 : : /* The second flash bank is stored immediately following the first
271 : : * bank. Based on whether the 1st or 2nd bank is active, and whether
272 : : * we want the active or inactive bank, calculate the desired offset.
273 : : */
274 [ # # # ]: 0 : switch (bank) {
275 : 0 : case ICE_ACTIVE_FLASH_BANK:
276 [ # # ]: 0 : return offset + (second_bank_active ? size : 0);
277 : 0 : case ICE_INACTIVE_FLASH_BANK:
278 [ # # ]: 0 : return offset + (second_bank_active ? 0 : size);
279 : : }
280 : :
281 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unexpected value for flash bank selection: %u\n", bank);
282 : : return 0;
283 : : }
284 : :
285 : : /**
286 : : * ice_read_flash_module - Read a word from one of the main NVM modules
287 : : * @hw: pointer to the HW structure
288 : : * @bank: which bank of the module to read
289 : : * @module: the module to read
290 : : * @offset: the offset into the module in bytes
291 : : * @data: storage for the word read from the flash
292 : : * @length: bytes of data to read
293 : : *
294 : : * Read data from the specified flash module. The bank parameter indicates
295 : : * whether or not to read from the active bank or the inactive bank of that
296 : : * module.
297 : : *
298 : : * The word will be read using flat NVM access, and relies on the
299 : : * hw->flash.banks data being setup by ice_determine_active_flash_banks()
300 : : * during initialization.
301 : : */
302 : : static enum ice_status
303 : 0 : ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
304 : : u32 offset, u8 *data, u32 length)
305 : : {
306 : : enum ice_status status;
307 : : u32 start;
308 : :
309 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
310 : :
311 : 0 : start = ice_get_flash_bank_offset(hw, bank, module);
312 [ # # ]: 0 : if (!start) {
313 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unable to calculate flash bank offset for module 0x%04x\n",
314 : : module);
315 : 0 : return ICE_ERR_PARAM;
316 : : }
317 : :
318 : 0 : status = ice_acquire_nvm(hw, ICE_RES_READ);
319 [ # # ]: 0 : if (status)
320 : : return status;
321 : :
322 : 0 : status = ice_read_flat_nvm(hw, start + offset, &length, data, false);
323 : :
324 : 0 : ice_release_nvm(hw);
325 : :
326 : 0 : return status;
327 : : }
328 : :
329 : : /**
330 : : * ice_read_nvm_module - Read from the active main NVM module
331 : : * @hw: pointer to the HW structure
332 : : * @bank: whether to read from active or inactive NVM module
333 : : * @offset: offset into the NVM module to read, in words
334 : : * @data: storage for returned word value
335 : : *
336 : : * Read the specified word from the active NVM module. This includes the CSS
337 : : * header at the start of the NVM module.
338 : : */
339 : : static enum ice_status
340 : : ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
341 : : {
342 : : enum ice_status status;
343 : : __le16 data_local;
344 : :
345 : 0 : status = ice_read_flash_module(hw, bank, ICE_SR_1ST_NVM_BANK_PTR, offset * sizeof(u16),
346 : : (_FORCE_ u8 *)&data_local, sizeof(u16));
347 [ # # # # : 0 : if (!status)
# # # # #
# ]
348 : 0 : *data = LE16_TO_CPU(data_local);
349 : :
350 : : return status;
351 : : }
352 : :
353 : : /**
354 : : * ice_get_nvm_css_hdr_len - Read the CSS header length from the NVM CSS header
355 : : * @hw: pointer to the HW struct
356 : : * @bank: whether to read from the active or inactive flash bank
357 : : * @hdr_len: storage for header length in words
358 : : *
359 : : * Read the CSS header length from the NVM CSS header and add the Authentication
360 : : * header size, and then convert to words.
361 : : */
362 : : static enum ice_status
363 : 0 : ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
364 : : u32 *hdr_len)
365 : : {
366 : : u16 hdr_len_l, hdr_len_h;
367 : : enum ice_status status;
368 : : u32 hdr_len_dword;
369 : :
370 : : status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_L,
371 : : &hdr_len_l);
372 [ # # ]: 0 : if (status)
373 : : return status;
374 : :
375 : : status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_H,
376 : : &hdr_len_h);
377 [ # # ]: 0 : if (status)
378 : : return status;
379 : :
380 : : /* CSS header length is in DWORD, so convert to words and add
381 : : * authentication header size
382 : : */
383 : 0 : hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
384 : 0 : *hdr_len = (hdr_len_dword * 2) + ICE_NVM_AUTH_HEADER_LEN;
385 : :
386 : 0 : return ICE_SUCCESS;
387 : : }
388 : :
389 : : /**
390 : : * ice_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank
391 : : * @hw: pointer to the HW structure
392 : : * @bank: whether to read from the active or inactive NVM module
393 : : * @offset: offset into the Shadow RAM copy to read, in words
394 : : * @data: storage for returned word value
395 : : *
396 : : * Read the specified word from the copy of the Shadow RAM found in the
397 : : * specified NVM module.
398 : : */
399 : : static enum ice_status
400 : 0 : ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
401 : : {
402 : : enum ice_status status;
403 : : u32 hdr_len;
404 : :
405 : 0 : status = ice_get_nvm_css_hdr_len(hw, bank, &hdr_len);
406 [ # # ]: 0 : if (status)
407 : : return status;
408 : :
409 : 0 : hdr_len = ROUND_UP(hdr_len, 32);
410 : :
411 : 0 : return ice_read_nvm_module(hw, bank, hdr_len + offset, data);
412 : : }
413 : :
414 : : /**
415 : : * ice_read_orom_module - Read from the active Option ROM module
416 : : * @hw: pointer to the HW structure
417 : : * @bank: whether to read from active or inactive OROM module
418 : : * @offset: offset into the OROM module to read, in words
419 : : * @data: storage for returned word value
420 : : *
421 : : * Read the specified word from the active Option ROM module of the flash.
422 : : * Note that unlike the NVM module, the CSS data is stored at the end of the
423 : : * module instead of at the beginning.
424 : : */
425 : : static enum ice_status
426 : : ice_read_orom_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
427 : : {
428 : : enum ice_status status;
429 : : __le16 data_local;
430 : :
431 : 0 : status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, offset * sizeof(u16),
432 : : (_FORCE_ u8 *)&data_local, sizeof(u16));
433 [ # # # # ]: 0 : if (!status)
434 : 0 : *data = LE16_TO_CPU(data_local);
435 : :
436 : : return status;
437 : : }
438 : :
439 : : /**
440 : : * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
441 : : * @hw: pointer to the HW structure
442 : : * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
443 : : * @data: word read from the Shadow RAM
444 : : *
445 : : * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
446 : : */
447 : 0 : enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
448 : : {
449 : : enum ice_status status;
450 : :
451 : 0 : status = ice_acquire_nvm(hw, ICE_RES_READ);
452 [ # # ]: 0 : if (!status) {
453 : 0 : status = ice_read_sr_word_aq(hw, offset, data);
454 : 0 : ice_release_nvm(hw);
455 : : }
456 : :
457 : 0 : return status;
458 : : }
459 : :
460 : : /**
461 : : * ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
462 : : * @hw: pointer to hardware structure
463 : : * @module_tlv: pointer to module TLV to return
464 : : * @module_tlv_len: pointer to module TLV length to return
465 : : * @module_type: module type requested
466 : : *
467 : : * Finds the requested sub module TLV type from the Preserved Field
468 : : * Area (PFA) and returns the TLV pointer and length. The caller can
469 : : * use these to read the variable length TLV value.
470 : : */
471 : : enum ice_status
472 : 0 : ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
473 : : u16 module_type)
474 : : {
475 : : enum ice_status status;
476 : : u16 pfa_len, pfa_ptr;
477 : : u16 next_tlv;
478 : :
479 : 0 : status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
480 [ # # ]: 0 : if (status != ICE_SUCCESS) {
481 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
482 : 0 : return status;
483 : : }
484 : 0 : status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
485 [ # # ]: 0 : if (status != ICE_SUCCESS) {
486 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
487 : 0 : return status;
488 : : }
489 : : /* Starting with first TLV after PFA length, iterate through the list
490 : : * of TLVs to find the requested one.
491 : : */
492 : 0 : next_tlv = pfa_ptr + 1;
493 [ # # ]: 0 : while (next_tlv < pfa_ptr + pfa_len) {
494 : : u16 tlv_sub_module_type;
495 : : u16 tlv_len;
496 : :
497 : : /* Read TLV type */
498 : 0 : status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
499 [ # # ]: 0 : if (status != ICE_SUCCESS) {
500 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
501 : 0 : break;
502 : : }
503 : : /* Read TLV length */
504 : 0 : status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
505 [ # # ]: 0 : if (status != ICE_SUCCESS) {
506 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
507 : : break;
508 : : }
509 [ # # ]: 0 : if (tlv_sub_module_type == module_type) {
510 [ # # ]: 0 : if (tlv_len) {
511 : 0 : *module_tlv = next_tlv;
512 : 0 : *module_tlv_len = tlv_len;
513 : 0 : return ICE_SUCCESS;
514 : : }
515 : : return ICE_ERR_INVAL_SIZE;
516 : : }
517 : : /* Check next TLV, i.e. current TLV pointer + length + 2 words
518 : : * (for current TLV's type and length)
519 : : */
520 : 0 : next_tlv = next_tlv + tlv_len + 2;
521 : : }
522 : : /* Module does not exist */
523 : : return ICE_ERR_DOES_NOT_EXIST;
524 : : }
525 : :
526 : : /**
527 : : * ice_read_pba_string - Reads part number string from NVM
528 : : * @hw: pointer to hardware structure
529 : : * @pba_num: stores the part number string from the NVM
530 : : * @pba_num_size: part number string buffer length
531 : : *
532 : : * Reads the part number string from the NVM.
533 : : */
534 : : enum ice_status
535 : 0 : ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
536 : : {
537 : : u16 pba_tlv, pba_tlv_len;
538 : : enum ice_status status;
539 : : u16 pba_word, pba_size;
540 : : u16 i;
541 : :
542 : 0 : status = ice_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
543 : : ICE_SR_PBA_BLOCK_PTR);
544 [ # # ]: 0 : if (status != ICE_SUCCESS) {
545 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block TLV.\n");
546 : 0 : return status;
547 : : }
548 : :
549 : : /* pba_size is the next word */
550 : 0 : status = ice_read_sr_word(hw, (pba_tlv + 2), &pba_size);
551 [ # # ]: 0 : if (status != ICE_SUCCESS) {
552 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Section size.\n");
553 : 0 : return status;
554 : : }
555 : :
556 [ # # ]: 0 : if (pba_tlv_len < pba_size) {
557 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Invalid PBA Block TLV size.\n");
558 : 0 : return ICE_ERR_INVAL_SIZE;
559 : : }
560 : :
561 : : /* Subtract one to get PBA word count (PBA Size word is included in
562 : : * total size)
563 : : */
564 : 0 : pba_size--;
565 [ # # ]: 0 : if (pba_num_size < (((u32)pba_size * 2) + 1)) {
566 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Buffer too small for PBA data.\n");
567 : 0 : return ICE_ERR_PARAM;
568 : : }
569 : :
570 [ # # ]: 0 : for (i = 0; i < pba_size; i++) {
571 : 0 : status = ice_read_sr_word(hw, (pba_tlv + 2 + 1) + i, &pba_word);
572 [ # # ]: 0 : if (status != ICE_SUCCESS) {
573 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block word %d.\n", i);
574 : 0 : return status;
575 : : }
576 : :
577 : 0 : pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
578 : 0 : pba_num[(i * 2) + 1] = pba_word & 0xFF;
579 : : }
580 : 0 : pba_num[(pba_size * 2)] = '\0';
581 : :
582 : 0 : return status;
583 : : }
584 : :
585 : : /**
586 : : * ice_get_nvm_srev - Read the security revision from the NVM CSS header
587 : : * @hw: pointer to the HW struct
588 : : * @bank: whether to read from the active or inactive flash bank
589 : : * @srev: storage for security revision
590 : : *
591 : : * Read the security revision out of the CSS header of the active NVM module
592 : : * bank.
593 : : */
594 : 0 : static enum ice_status ice_get_nvm_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
595 : : {
596 : : enum ice_status status;
597 : : u16 srev_l, srev_h;
598 : :
599 : : status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_SREV_L, &srev_l);
600 [ # # ]: 0 : if (status)
601 : : return status;
602 : :
603 : : status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_SREV_H, &srev_h);
604 [ # # ]: 0 : if (status)
605 : : return status;
606 : :
607 : 0 : *srev = srev_h << 16 | srev_l;
608 : :
609 : 0 : return ICE_SUCCESS;
610 : : }
611 : :
612 : : /**
613 : : * ice_get_nvm_ver_info - Read NVM version information
614 : : * @hw: pointer to the HW struct
615 : : * @bank: whether to read from the active or inactive flash bank
616 : : * @nvm: pointer to NVM info structure
617 : : *
618 : : * Read the NVM EETRACK ID and map version of the main NVM image bank, filling
619 : : * in the nvm info structure.
620 : : */
621 : : static enum ice_status
622 : 0 : ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nvm_info *nvm)
623 : : {
624 : : u16 eetrack_lo, eetrack_hi, ver;
625 : : enum ice_status status;
626 : :
627 : 0 : status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_DEV_STARTER_VER, &ver);
628 [ # # ]: 0 : if (status) {
629 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read DEV starter version.\n");
630 : 0 : return status;
631 : : }
632 : :
633 : 0 : nvm->major = (ver & ICE_NVM_VER_HI_MASK) >> ICE_NVM_VER_HI_SHIFT;
634 : 0 : nvm->minor = (ver & ICE_NVM_VER_LO_MASK) >> ICE_NVM_VER_LO_SHIFT;
635 : :
636 : 0 : status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
637 [ # # ]: 0 : if (status) {
638 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK lo.\n");
639 : 0 : return status;
640 : : }
641 : 0 : status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
642 [ # # ]: 0 : if (status) {
643 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read EETRACK hi.\n");
644 : 0 : return status;
645 : : }
646 : :
647 : 0 : nvm->eetrack = (eetrack_hi << 16) | eetrack_lo;
648 : :
649 : 0 : status = ice_get_nvm_srev(hw, bank, &nvm->srev);
650 [ # # ]: 0 : if (status)
651 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM security revision.\n");
652 : :
653 : : return ICE_SUCCESS;
654 : : }
655 : :
656 : : /**
657 : : * ice_get_inactive_nvm_ver - Read Option ROM version from the inactive bank
658 : : * @hw: pointer to the HW structure
659 : : * @nvm: storage for Option ROM version information
660 : : *
661 : : * Reads the NVM EETRACK ID, Map version, and security revision of the
662 : : * inactive NVM bank. Used to access version data for a pending update that
663 : : * has not yet been activated.
664 : : */
665 : 0 : enum ice_status ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm)
666 : : {
667 : 0 : return ice_get_nvm_ver_info(hw, ICE_INACTIVE_FLASH_BANK, nvm);
668 : : }
669 : :
670 : : /**
671 : : * ice_get_orom_srev - Read the security revision from the OROM CSS header
672 : : * @hw: pointer to the HW struct
673 : : * @bank: whether to read from active or inactive flash module
674 : : * @srev: storage for security revision
675 : : *
676 : : * Read the security revision out of the CSS header of the active OROM module
677 : : * bank.
678 : : */
679 : 0 : static enum ice_status ice_get_orom_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
680 : : {
681 : 0 : u32 orom_size_word = hw->flash.banks.orom_size / 2;
682 : : enum ice_status status;
683 : : u16 srev_l, srev_h;
684 : : u32 css_start;
685 : : u32 hdr_len;
686 : :
687 : 0 : status = ice_get_nvm_css_hdr_len(hw, bank, &hdr_len);
688 [ # # ]: 0 : if (status)
689 : : return status;
690 : :
691 [ # # ]: 0 : if (orom_size_word < hdr_len) {
692 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unexpected Option ROM Size of %u\n",
693 : : hw->flash.banks.orom_size);
694 : 0 : return ICE_ERR_CFG;
695 : : }
696 : :
697 : : /* calculate how far into the Option ROM the CSS header starts. Note
698 : : * that ice_read_orom_module takes a word offset
699 : : */
700 : 0 : css_start = orom_size_word - hdr_len;
701 : 0 : status = ice_read_orom_module(hw, bank, css_start + ICE_NVM_CSS_SREV_L, &srev_l);
702 [ # # ]: 0 : if (status)
703 : : return status;
704 : :
705 : 0 : status = ice_read_orom_module(hw, bank, css_start + ICE_NVM_CSS_SREV_H, &srev_h);
706 [ # # ]: 0 : if (status)
707 : : return status;
708 : :
709 : 0 : *srev = srev_h << 16 | srev_l;
710 : :
711 : 0 : return ICE_SUCCESS;
712 : : }
713 : :
714 : : /**
715 : : * ice_get_orom_civd_data - Get the combo version information from Option ROM
716 : : * @hw: pointer to the HW struct
717 : : * @bank: whether to read from the active or inactive flash module
718 : : * @civd: storage for the Option ROM CIVD data.
719 : : *
720 : : * Searches through the Option ROM flash contents to locate the CIVD data for
721 : : * the image.
722 : : */
723 : : static enum ice_status
724 : 0 : ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
725 : : struct ice_orom_civd_info *civd)
726 : : {
727 : : u8 *orom_data;
728 : : enum ice_status status;
729 : : u32 offset;
730 : :
731 : : /* The CIVD section is located in the Option ROM aligned to 512 bytes.
732 : : * The first 4 bytes must contain the ASCII characters "$CIV".
733 : : * A simple modulo 256 sum of all of the bytes of the structure must
734 : : * equal 0.
735 : : *
736 : : * The exact location is unknown and varies between images but is
737 : : * usually somewhere in the middle of the bank. We need to scan the
738 : : * Option ROM bank to locate it.
739 : : *
740 : : * It's significantly faster to read the entire Option ROM up front
741 : : * using the maximum page size, than to read each possible location
742 : : * with a separate firmware command.
743 : : */
744 : 0 : orom_data = (u8 *)ice_calloc(hw, hw->flash.banks.orom_size, sizeof(u8));
745 [ # # ]: 0 : if (!orom_data)
746 : : return ICE_ERR_NO_MEMORY;
747 : :
748 : 0 : status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, 0,
749 : : orom_data, hw->flash.banks.orom_size);
750 [ # # ]: 0 : if (status) {
751 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unable to read Option ROM data\n");
752 : 0 : return status;
753 : : }
754 : :
755 : : /* Scan the memory buffer to locate the CIVD data section */
756 [ # # ]: 0 : for (offset = 0; (offset + 512) <= hw->flash.banks.orom_size; offset += 512) {
757 : : struct ice_orom_civd_info *tmp;
758 : : u8 sum = 0, i;
759 : :
760 : 0 : tmp = (struct ice_orom_civd_info *)&orom_data[offset];
761 : :
762 : : /* Skip forward until we find a matching signature */
763 [ # # ]: 0 : if (memcmp("$CIV", tmp->signature, sizeof(tmp->signature)) != 0)
764 : : continue;
765 : :
766 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Found CIVD section at offset %u\n",
767 : : offset);
768 : :
769 : : /* Verify that the simple checksum is zero */
770 [ # # ]: 0 : for (i = 0; i < sizeof(*tmp); i++)
771 : 0 : sum += ((u8 *)tmp)[i];
772 : :
773 [ # # ]: 0 : if (sum) {
774 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Found CIVD data with invalid checksum of %u\n",
775 : : sum);
776 : 0 : goto err_invalid_checksum;
777 : : }
778 : :
779 : 0 : *civd = *tmp;
780 : 0 : ice_free(hw, orom_data);
781 : 0 : return ICE_SUCCESS;
782 : : }
783 : :
784 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Unable to locate CIVD data within the Option ROM\n");
785 : :
786 : 0 : err_invalid_checksum:
787 : 0 : ice_free(hw, orom_data);
788 : 0 : return ICE_ERR_NVM;
789 : : }
790 : :
791 : : /**
792 : : * ice_get_orom_ver_info - Read Option ROM version information
793 : : * @hw: pointer to the HW struct
794 : : * @bank: whether to read from the active or inactive flash module
795 : : * @orom: pointer to Option ROM info structure
796 : : *
797 : : * Read Option ROM version and security revision from the Option ROM flash
798 : : * section.
799 : : */
800 : : static enum ice_status
801 : 0 : ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_info *orom)
802 : : {
803 : : struct ice_orom_civd_info civd;
804 : : enum ice_status status;
805 : : u32 combo_ver;
806 : :
807 : 0 : status = ice_get_orom_civd_data(hw, bank, &civd);
808 [ # # ]: 0 : if (status) {
809 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to locate valid Option ROM CIVD data\n");
810 : 0 : return status;
811 : : }
812 : :
813 : 0 : combo_ver = LE32_TO_CPU(civd.combo_ver);
814 : :
815 : 0 : orom->major = (u8)((combo_ver & ICE_OROM_VER_MASK) >> ICE_OROM_VER_SHIFT);
816 : 0 : orom->patch = (u8)(combo_ver & ICE_OROM_VER_PATCH_MASK);
817 : 0 : orom->build = (u16)((combo_ver & ICE_OROM_VER_BUILD_MASK) >> ICE_OROM_VER_BUILD_SHIFT);
818 : :
819 : 0 : status = ice_get_orom_srev(hw, bank, &orom->srev);
820 [ # # ]: 0 : if (status) {
821 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read Option ROM security revision.\n");
822 : 0 : return status;
823 : : }
824 : :
825 : : return ICE_SUCCESS;
826 : : }
827 : :
828 : : /**
829 : : * ice_get_inactive_orom_ver - Read Option ROM version from the inactive bank
830 : : * @hw: pointer to the HW structure
831 : : * @orom: storage for Option ROM version information
832 : : *
833 : : * Reads the Option ROM version and security revision data for the inactive
834 : : * section of flash. Used to access version data for a pending update that has
835 : : * not yet been activated.
836 : : */
837 : 0 : enum ice_status ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom)
838 : : {
839 : 0 : return ice_get_orom_ver_info(hw, ICE_INACTIVE_FLASH_BANK, orom);
840 : : }
841 : :
842 : : /**
843 : : * ice_discover_flash_size - Discover the available flash size.
844 : : * @hw: pointer to the HW struct
845 : : *
846 : : * The device flash could be up to 16MB in size. However, it is possible that
847 : : * the actual size is smaller. Use bisection to determine the accessible size
848 : : * of flash memory.
849 : : */
850 : 0 : static enum ice_status ice_discover_flash_size(struct ice_hw *hw)
851 : : {
852 : : u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1;
853 : : enum ice_status status;
854 : :
855 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
856 : :
857 : 0 : status = ice_acquire_nvm(hw, ICE_RES_READ);
858 [ # # ]: 0 : if (status)
859 : : return status;
860 : :
861 [ # # ]: 0 : while ((max_size - min_size) > 1) {
862 : 0 : u32 offset = (max_size + min_size) / 2;
863 : 0 : u32 len = 1;
864 : : u8 data;
865 : :
866 : 0 : status = ice_read_flat_nvm(hw, offset, &len, &data, false);
867 [ # # ]: 0 : if (status == ICE_ERR_AQ_ERROR &&
868 [ # # ]: 0 : hw->adminq.sq_last_status == ICE_AQ_RC_EINVAL) {
869 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "%s: New upper bound of %u bytes\n",
870 : : __func__, offset);
871 : : status = ICE_SUCCESS;
872 : : max_size = offset;
873 [ # # ]: 0 : } else if (!status) {
874 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "%s: New lower bound of %u bytes\n",
875 : : __func__, offset);
876 : : min_size = offset;
877 : : } else {
878 : : /* an unexpected error occurred */
879 : 0 : goto err_read_flat_nvm;
880 : : }
881 : : }
882 : :
883 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Predicted flash size is %u bytes\n", max_size);
884 : :
885 : 0 : hw->flash.flash_size = max_size;
886 : :
887 : 0 : err_read_flat_nvm:
888 : 0 : ice_release_nvm(hw);
889 : :
890 : 0 : return status;
891 : : }
892 : :
893 : : /**
894 : : * ice_read_sr_pointer - Read the value of a Shadow RAM pointer word
895 : : * @hw: pointer to the HW structure
896 : : * @offset: the word offset of the Shadow RAM word to read
897 : : * @pointer: pointer value read from Shadow RAM
898 : : *
899 : : * Read the given Shadow RAM word, and convert it to a pointer value specified
900 : : * in bytes. This function assumes the specified offset is a valid pointer
901 : : * word.
902 : : *
903 : : * Each pointer word specifies whether it is stored in word size or 4KB
904 : : * sector size by using the highest bit. The reported pointer value will be in
905 : : * bytes, intended for flat NVM reads.
906 : : */
907 : : static enum ice_status
908 : 0 : ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
909 : : {
910 : : enum ice_status status;
911 : : u16 value;
912 : :
913 : 0 : status = ice_read_sr_word(hw, offset, &value);
914 [ # # ]: 0 : if (status)
915 : : return status;
916 : :
917 : : /* Determine if the pointer is in 4KB or word units */
918 [ # # ]: 0 : if (value & ICE_SR_NVM_PTR_4KB_UNITS)
919 : 0 : *pointer = (value & ~ICE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024;
920 : : else
921 : 0 : *pointer = value * 2;
922 : :
923 : : return ICE_SUCCESS;
924 : : }
925 : :
926 : : /**
927 : : * ice_read_sr_area_size - Read an area size from a Shadow RAM word
928 : : * @hw: pointer to the HW structure
929 : : * @offset: the word offset of the Shadow RAM to read
930 : : * @size: size value read from the Shadow RAM
931 : : *
932 : : * Read the given Shadow RAM word, and convert it to an area size value
933 : : * specified in bytes. This function assumes the specified offset is a valid
934 : : * area size word.
935 : : *
936 : : * Each area size word is specified in 4KB sector units. This function reports
937 : : * the size in bytes, intended for flat NVM reads.
938 : : */
939 : : static enum ice_status
940 : : ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
941 : : {
942 : : enum ice_status status;
943 : : u16 value;
944 : :
945 : 0 : status = ice_read_sr_word(hw, offset, &value);
946 [ # # # # : 0 : if (status)
# # ]
947 : : return status;
948 : :
949 : : /* Area sizes are always specified in 4KB units */
950 : 0 : *size = value * 4 * 1024;
951 : :
952 : : return ICE_SUCCESS;
953 : : }
954 : :
955 : : /**
956 : : * ice_determine_active_flash_banks - Discover active bank for each module
957 : : * @hw: pointer to the HW struct
958 : : *
959 : : * Read the Shadow RAM control word and determine which banks are active for
960 : : * the NVM, OROM, and Netlist modules. Also read and calculate the associated
961 : : * pointer and size. These values are then cached into the ice_flash_info
962 : : * structure for later use in order to calculate the correct offset to read
963 : : * from the active module.
964 : : */
965 : : static enum ice_status
966 : 0 : ice_determine_active_flash_banks(struct ice_hw *hw)
967 : : {
968 : : struct ice_bank_info *banks = &hw->flash.banks;
969 : : enum ice_status status;
970 : : u16 ctrl_word;
971 : :
972 : 0 : status = ice_read_sr_word(hw, ICE_SR_NVM_CTRL_WORD, &ctrl_word);
973 [ # # ]: 0 : if (status) {
974 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read the Shadow RAM control word\n");
975 : 0 : return status;
976 : : }
977 : :
978 : : /* Check that the control word indicates validity */
979 [ # # ]: 0 : if ((ctrl_word & ICE_SR_CTRL_WORD_1_M) >> ICE_SR_CTRL_WORD_1_S != ICE_SR_CTRL_WORD_VALID) {
980 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Shadow RAM control word is invalid\n");
981 : 0 : return ICE_ERR_CFG;
982 : : }
983 : :
984 [ # # ]: 0 : if (!(ctrl_word & ICE_SR_CTRL_WORD_NVM_BANK))
985 : 0 : banks->nvm_bank = ICE_1ST_FLASH_BANK;
986 : : else
987 : 0 : banks->nvm_bank = ICE_2ND_FLASH_BANK;
988 : :
989 [ # # ]: 0 : if (!(ctrl_word & ICE_SR_CTRL_WORD_OROM_BANK))
990 : 0 : banks->orom_bank = ICE_1ST_FLASH_BANK;
991 : : else
992 : 0 : banks->orom_bank = ICE_2ND_FLASH_BANK;
993 : :
994 [ # # ]: 0 : if (!(ctrl_word & ICE_SR_CTRL_WORD_NETLIST_BANK))
995 : 0 : banks->netlist_bank = ICE_1ST_FLASH_BANK;
996 : : else
997 : 0 : banks->netlist_bank = ICE_2ND_FLASH_BANK;
998 : :
999 : 0 : status = ice_read_sr_pointer(hw, ICE_SR_1ST_NVM_BANK_PTR, &banks->nvm_ptr);
1000 [ # # ]: 0 : if (status) {
1001 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank pointer\n");
1002 : 0 : return status;
1003 : : }
1004 : :
1005 : : status = ice_read_sr_area_size(hw, ICE_SR_NVM_BANK_SIZE, &banks->nvm_size);
1006 : : if (status) {
1007 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM bank area size\n");
1008 : 0 : return status;
1009 : : }
1010 : :
1011 : 0 : status = ice_read_sr_pointer(hw, ICE_SR_1ST_OROM_BANK_PTR, &banks->orom_ptr);
1012 [ # # ]: 0 : if (status) {
1013 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank pointer\n");
1014 : 0 : return status;
1015 : : }
1016 : :
1017 : : status = ice_read_sr_area_size(hw, ICE_SR_OROM_BANK_SIZE, &banks->orom_size);
1018 : : if (status) {
1019 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read OROM bank area size\n");
1020 : 0 : return status;
1021 : : }
1022 : :
1023 : 0 : status = ice_read_sr_pointer(hw, ICE_SR_NETLIST_BANK_PTR, &banks->netlist_ptr);
1024 [ # # ]: 0 : if (status) {
1025 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank pointer\n");
1026 : 0 : return status;
1027 : : }
1028 : :
1029 : : status = ice_read_sr_area_size(hw, ICE_SR_NETLIST_BANK_SIZE, &banks->netlist_size);
1030 : : if (status) {
1031 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to read Netlist bank area size\n");
1032 : 0 : return status;
1033 : : }
1034 : :
1035 : : return ICE_SUCCESS;
1036 : : }
1037 : :
1038 : : /**
1039 : : * ice_init_nvm - initializes NVM setting
1040 : : * @hw: pointer to the HW struct
1041 : : *
1042 : : * This function reads and populates NVM settings such as Shadow RAM size,
1043 : : * max_timeout, and blank_nvm_mode
1044 : : */
1045 : 0 : enum ice_status ice_init_nvm(struct ice_hw *hw)
1046 : : {
1047 : : struct ice_flash_info *flash = &hw->flash;
1048 : : enum ice_status status;
1049 : : u32 fla, gens_stat;
1050 : : u8 sr_size;
1051 : :
1052 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
1053 : :
1054 : : /* The SR size is stored regardless of the NVM programming mode
1055 : : * as the blank mode may be used in the factory line.
1056 : : */
1057 : 0 : gens_stat = rd32(hw, GLNVM_GENS);
1058 : 0 : sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
1059 : :
1060 : : /* Switching to words (sr_size contains power of 2) */
1061 : 0 : flash->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
1062 : :
1063 : : /* Check if we are in the normal or blank NVM programming mode */
1064 : 0 : fla = rd32(hw, GLNVM_FLA);
1065 [ # # ]: 0 : if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
1066 : 0 : flash->blank_nvm_mode = false;
1067 : : } else {
1068 : : /* Blank programming mode */
1069 : 0 : flash->blank_nvm_mode = true;
1070 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "NVM init error: unsupported blank mode.\n");
1071 : 0 : return ICE_ERR_NVM_BLANK_MODE;
1072 : : }
1073 : :
1074 : 0 : status = ice_discover_flash_size(hw);
1075 [ # # ]: 0 : if (status) {
1076 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "NVM init error: failed to discover flash size.\n");
1077 : 0 : return status;
1078 : : }
1079 : :
1080 : 0 : status = ice_determine_active_flash_banks(hw);
1081 [ # # ]: 0 : if (status) {
1082 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "Failed to determine active flash banks.\n");
1083 : 0 : return status;
1084 : : }
1085 : :
1086 : 0 : status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
1087 [ # # ]: 0 : if (status) {
1088 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");
1089 : 0 : return status;
1090 : : }
1091 : :
1092 : 0 : status = ice_get_orom_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->orom);
1093 [ # # ]: 0 : if (status)
1094 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read Option ROM info.\n");
1095 : :
1096 : : return ICE_SUCCESS;
1097 : : }
1098 : :
1099 : : /**
1100 : : * ice_read_sr_buf - Reads Shadow RAM buf and acquire lock if necessary
1101 : : * @hw: pointer to the HW structure
1102 : : * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
1103 : : * @words: (in) number of words to read; (out) number of words actually read
1104 : : * @data: words read from the Shadow RAM
1105 : : *
1106 : : * Reads 16 bit words (data buf) from the SR using the ice_read_nvm_buf_aq
1107 : : * method. The buf read is preceded by the NVM ownership take
1108 : : * and followed by the release.
1109 : : */
1110 : : enum ice_status
1111 : 0 : ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
1112 : : {
1113 : : enum ice_status status;
1114 : :
1115 : 0 : status = ice_acquire_nvm(hw, ICE_RES_READ);
1116 [ # # ]: 0 : if (!status) {
1117 : 0 : status = ice_read_sr_buf_aq(hw, offset, words, data);
1118 : 0 : ice_release_nvm(hw);
1119 : : }
1120 : :
1121 : 0 : return status;
1122 : : }
1123 : :
1124 : : /**
1125 : : * ice_nvm_validate_checksum
1126 : : * @hw: pointer to the HW struct
1127 : : *
1128 : : * Verify NVM PFA checksum validity (0x0706)
1129 : : */
1130 : 0 : enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
1131 : : {
1132 : : struct ice_aqc_nvm_checksum *cmd;
1133 : : struct ice_aq_desc desc;
1134 : : enum ice_status status;
1135 : :
1136 : 0 : status = ice_acquire_nvm(hw, ICE_RES_READ);
1137 [ # # ]: 0 : if (status)
1138 : : return status;
1139 : :
1140 : : cmd = &desc.params.nvm_checksum;
1141 : :
1142 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
1143 : 0 : cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY;
1144 : :
1145 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1146 : 0 : ice_release_nvm(hw);
1147 : :
1148 [ # # ]: 0 : if (!status)
1149 [ # # ]: 0 : if (LE16_TO_CPU(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT)
1150 : : status = ICE_ERR_NVM_CHECKSUM;
1151 : :
1152 : : return status;
1153 : : }
1154 : :
1155 : : /**
1156 : : * ice_nvm_recalculate_checksum
1157 : : * @hw: pointer to the HW struct
1158 : : *
1159 : : * Recalculate NVM PFA checksum (0x0706)
1160 : : */
1161 : 0 : enum ice_status ice_nvm_recalculate_checksum(struct ice_hw *hw)
1162 : : {
1163 : : struct ice_aqc_nvm_checksum *cmd;
1164 : : struct ice_aq_desc desc;
1165 : : enum ice_status status;
1166 : :
1167 : 0 : status = ice_acquire_nvm(hw, ICE_RES_READ);
1168 [ # # ]: 0 : if (status)
1169 : : return status;
1170 : :
1171 : : cmd = &desc.params.nvm_checksum;
1172 : :
1173 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum);
1174 : 0 : cmd->flags = ICE_AQC_NVM_CHECKSUM_RECALC;
1175 : :
1176 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1177 : :
1178 : 0 : ice_release_nvm(hw);
1179 : :
1180 : 0 : return status;
1181 : : }
1182 : :
1183 : : /**
1184 : : * ice_nvm_access_get_features - Return the NVM access features structure
1185 : : * @cmd: NVM access command to process
1186 : : * @data: storage for the driver NVM features
1187 : : *
1188 : : * Fill in the data section of the NVM access request with a copy of the NVM
1189 : : * features structure.
1190 : : */
1191 : : enum ice_status
1192 : 0 : ice_nvm_access_get_features(struct ice_nvm_access_cmd *cmd,
1193 : : union ice_nvm_access_data *data)
1194 : : {
1195 : : /* The provided data_size must be at least as large as our NVM
1196 : : * features structure. A larger size should not be treated as an
1197 : : * error, to allow future extensions to the features structure to
1198 : : * work on older drivers.
1199 : : */
1200 [ # # ]: 0 : if (cmd->data_size < sizeof(struct ice_nvm_features))
1201 : : return ICE_ERR_NO_MEMORY;
1202 : :
1203 : : /* Initialize the data buffer to zeros */
1204 : 0 : ice_memset(data, 0, cmd->data_size, ICE_NONDMA_MEM);
1205 : :
1206 : : /* Fill in the features data */
1207 : 0 : data->drv_features.major = ICE_NVM_ACCESS_MAJOR_VER;
1208 : 0 : data->drv_features.minor = ICE_NVM_ACCESS_MINOR_VER;
1209 : 0 : data->drv_features.size = sizeof(struct ice_nvm_features);
1210 : 0 : data->drv_features.features[0] = ICE_NVM_FEATURES_0_REG_ACCESS;
1211 : :
1212 : 0 : return ICE_SUCCESS;
1213 : : }
1214 : :
1215 : : /**
1216 : : * ice_nvm_access_get_module - Helper function to read module value
1217 : : * @cmd: NVM access command structure
1218 : : *
1219 : : * Reads the module value out of the NVM access config field.
1220 : : */
1221 : 0 : u32 ice_nvm_access_get_module(struct ice_nvm_access_cmd *cmd)
1222 : : {
1223 : 0 : return ((cmd->config & ICE_NVM_CFG_MODULE_M) >> ICE_NVM_CFG_MODULE_S);
1224 : : }
1225 : :
1226 : : /**
1227 : : * ice_nvm_access_get_flags - Helper function to read flags value
1228 : : * @cmd: NVM access command structure
1229 : : *
1230 : : * Reads the flags value out of the NVM access config field.
1231 : : */
1232 : 0 : u32 ice_nvm_access_get_flags(struct ice_nvm_access_cmd *cmd)
1233 : : {
1234 : 0 : return ((cmd->config & ICE_NVM_CFG_FLAGS_M) >> ICE_NVM_CFG_FLAGS_S);
1235 : : }
1236 : :
1237 : : /**
1238 : : * ice_nvm_access_get_adapter - Helper function to read adapter info
1239 : : * @cmd: NVM access command structure
1240 : : *
1241 : : * Read the adapter info value out of the NVM access config field.
1242 : : */
1243 : 0 : u32 ice_nvm_access_get_adapter(struct ice_nvm_access_cmd *cmd)
1244 : : {
1245 : 0 : return ((cmd->config & ICE_NVM_CFG_ADAPTER_INFO_M) >>
1246 : : ICE_NVM_CFG_ADAPTER_INFO_S);
1247 : : }
1248 : :
1249 : : /**
1250 : : * ice_validate_nvm_rw_reg - Check than an NVM access request is valid
1251 : : * @cmd: NVM access command structure
1252 : : *
1253 : : * Validates that an NVM access structure is request to read or write a valid
1254 : : * register offset. First validates that the module and flags are correct, and
1255 : : * then ensures that the register offset is one of the accepted registers.
1256 : : */
1257 : : static enum ice_status
1258 : 0 : ice_validate_nvm_rw_reg(struct ice_nvm_access_cmd *cmd)
1259 : : {
1260 : : u32 module, flags, offset;
1261 : : u16 i;
1262 : :
1263 : 0 : module = ice_nvm_access_get_module(cmd);
1264 : 0 : flags = ice_nvm_access_get_flags(cmd);
1265 : 0 : offset = cmd->offset;
1266 : :
1267 : : /* Make sure the module and flags indicate a read/write request */
1268 : 0 : if (module != ICE_NVM_REG_RW_MODULE ||
1269 [ # # ]: 0 : flags != ICE_NVM_REG_RW_FLAGS ||
1270 [ # # ]: 0 : cmd->data_size != FIELD_SIZEOF(union ice_nvm_access_data, regval))
1271 : : return ICE_ERR_PARAM;
1272 : :
1273 [ # # ]: 0 : switch (offset) {
1274 : : case GL_HICR:
1275 : : case GL_HICR_EN: /* Note, this register is read only */
1276 : : case GL_FWSTS:
1277 : : case GL_MNG_FWSM:
1278 : : case GLGEN_CSR_DEBUG_C:
1279 : : case GLGEN_RSTAT:
1280 : : case GLPCI_LBARCTRL:
1281 : : case GL_MNG_DEF_DEVID:
1282 : : case GLNVM_GENS:
1283 : : case GLNVM_FLA:
1284 : : case PF_FUNC_RID:
1285 : : return ICE_SUCCESS;
1286 : : default:
1287 : : break;
1288 : : }
1289 : :
1290 [ # # ]: 0 : for (i = 0; i <= GL_HIDA_MAX_INDEX; i++)
1291 [ # # ]: 0 : if (offset == (u32)GL_HIDA(i))
1292 : : return ICE_SUCCESS;
1293 : :
1294 [ # # ]: 0 : for (i = 0; i <= GL_HIBA_MAX_INDEX; i++)
1295 [ # # ]: 0 : if (offset == (u32)GL_HIBA(i))
1296 : : return ICE_SUCCESS;
1297 : :
1298 : : /* All other register offsets are not valid */
1299 : : return ICE_ERR_OUT_OF_RANGE;
1300 : : }
1301 : :
1302 : : /**
1303 : : * ice_nvm_access_read - Handle an NVM read request
1304 : : * @hw: pointer to the HW struct
1305 : : * @cmd: NVM access command to process
1306 : : * @data: storage for the register value read
1307 : : *
1308 : : * Process an NVM access request to read a register.
1309 : : */
1310 : : enum ice_status
1311 : 0 : ice_nvm_access_read(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
1312 : : union ice_nvm_access_data *data)
1313 : : {
1314 : : enum ice_status status;
1315 : :
1316 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
1317 : :
1318 : : /* Always initialize the output data, even on failure */
1319 : 0 : ice_memset(data, 0, cmd->data_size, ICE_NONDMA_MEM);
1320 : :
1321 : : /* Make sure this is a valid read/write access request */
1322 : 0 : status = ice_validate_nvm_rw_reg(cmd);
1323 [ # # ]: 0 : if (status)
1324 : : return status;
1325 : :
1326 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "NVM access: reading register %08x\n",
1327 : : cmd->offset);
1328 : :
1329 : : /* Read the register and store the contents in the data field */
1330 : 0 : data->regval = rd32(hw, cmd->offset);
1331 : :
1332 : 0 : return ICE_SUCCESS;
1333 : : }
1334 : :
1335 : : /**
1336 : : * ice_nvm_access_write - Handle an NVM write request
1337 : : * @hw: pointer to the HW struct
1338 : : * @cmd: NVM access command to process
1339 : : * @data: NVM access data to write
1340 : : *
1341 : : * Process an NVM access request to write a register.
1342 : : */
1343 : : enum ice_status
1344 : 0 : ice_nvm_access_write(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
1345 : : union ice_nvm_access_data *data)
1346 : : {
1347 : : enum ice_status status;
1348 : :
1349 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
1350 : :
1351 : : /* Make sure this is a valid read/write access request */
1352 : 0 : status = ice_validate_nvm_rw_reg(cmd);
1353 [ # # ]: 0 : if (status)
1354 : : return status;
1355 : :
1356 : : /* Reject requests to write to read-only registers */
1357 [ # # ]: 0 : switch (cmd->offset) {
1358 : : case GL_HICR_EN:
1359 : : case GLGEN_RSTAT:
1360 : : return ICE_ERR_OUT_OF_RANGE;
1361 : : default:
1362 : : break;
1363 : : }
1364 : :
1365 [ # # ]: 0 : ice_debug(hw, ICE_DBG_NVM, "NVM access: writing register %08x with value %08x\n",
1366 : : cmd->offset, data->regval);
1367 : :
1368 : : /* Write the data field to the specified register */
1369 : 0 : wr32(hw, cmd->offset, data->regval);
1370 : :
1371 : 0 : return ICE_SUCCESS;
1372 : : }
1373 : :
1374 : : /**
1375 : : * ice_handle_nvm_access - Handle an NVM access request
1376 : : * @hw: pointer to the HW struct
1377 : : * @cmd: NVM access command info
1378 : : * @data: pointer to read or return data
1379 : : *
1380 : : * Process an NVM access request. Read the command structure information and
1381 : : * determine if it is valid. If not, report an error indicating the command
1382 : : * was invalid.
1383 : : *
1384 : : * For valid commands, perform the necessary function, copying the data into
1385 : : * the provided data buffer.
1386 : : */
1387 : : enum ice_status
1388 : 0 : ice_handle_nvm_access(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
1389 : : union ice_nvm_access_data *data)
1390 : : {
1391 : : u32 module, flags, adapter_info;
1392 : :
1393 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
1394 : :
1395 : : /* Extended flags are currently reserved and must be zero */
1396 [ # # ]: 0 : if ((cmd->config & ICE_NVM_CFG_EXT_FLAGS_M) != 0)
1397 : : return ICE_ERR_PARAM;
1398 : :
1399 : : /* Adapter info must match the HW device ID */
1400 : 0 : adapter_info = ice_nvm_access_get_adapter(cmd);
1401 [ # # ]: 0 : if (adapter_info != hw->device_id)
1402 : : return ICE_ERR_PARAM;
1403 : :
1404 [ # # # ]: 0 : switch (cmd->command) {
1405 : 0 : case ICE_NVM_CMD_READ:
1406 : 0 : module = ice_nvm_access_get_module(cmd);
1407 : 0 : flags = ice_nvm_access_get_flags(cmd);
1408 : :
1409 : : /* Getting the driver's NVM features structure shares the same
1410 : : * command type as reading a register. Read the config field
1411 : : * to determine if this is a request to get features.
1412 : : */
1413 : 0 : if (module == ICE_NVM_GET_FEATURES_MODULE &&
1414 [ # # ]: 0 : flags == ICE_NVM_GET_FEATURES_FLAGS &&
1415 [ # # ]: 0 : cmd->offset == 0)
1416 : 0 : return ice_nvm_access_get_features(cmd, data);
1417 : : else
1418 : 0 : return ice_nvm_access_read(hw, cmd, data);
1419 : 0 : case ICE_NVM_CMD_WRITE:
1420 : 0 : return ice_nvm_access_write(hw, cmd, data);
1421 : : default:
1422 : : return ICE_ERR_PARAM;
1423 : : }
1424 : : }
|