@@ -211,6 +211,74 @@ static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
211
211
return ret_code ;
212
212
}
213
213
214
+ /**
215
+ * i40e_read_nvm_aq - Read Shadow RAM.
216
+ * @hw: pointer to the HW structure.
217
+ * @module_pointer: module pointer location in words from the NVM beginning
218
+ * @offset: offset in words from module start
219
+ * @words: number of words to write
220
+ * @data: buffer with words to write to the Shadow RAM
221
+ * @last_command: tells the AdminQ that this is the last command
222
+ *
223
+ * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
224
+ **/
225
+ static i40e_status i40e_read_nvm_aq (struct i40e_hw * hw , u8 module_pointer ,
226
+ u32 offset , u16 words , void * data ,
227
+ bool last_command )
228
+ {
229
+ i40e_status ret_code = I40E_ERR_NVM ;
230
+ struct i40e_asq_cmd_details cmd_details ;
231
+
232
+ memset (& cmd_details , 0 , sizeof (cmd_details ));
233
+
234
+ /* Here we are checking the SR limit only for the flat memory model.
235
+ * We cannot do it for the module-based model, as we did not acquire
236
+ * the NVM resource yet (we cannot get the module pointer value).
237
+ * Firmware will check the module-based model.
238
+ */
239
+ if ((offset + words ) > hw -> nvm .sr_size )
240
+ i40e_debug (hw , I40E_DEBUG_NVM ,
241
+ "NVM write error: offset %d beyond Shadow RAM limit %d\n" ,
242
+ (offset + words ), hw -> nvm .sr_size );
243
+ else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS )
244
+ /* We can write only up to 4KB (one sector), in one AQ write */
245
+ i40e_debug (hw , I40E_DEBUG_NVM ,
246
+ "NVM write fail error: tried to write %d words, limit is %d.\n" ,
247
+ words , I40E_SR_SECTOR_SIZE_IN_WORDS );
248
+ else if (((offset + (words - 1 )) / I40E_SR_SECTOR_SIZE_IN_WORDS )
249
+ != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS ))
250
+ /* A single write cannot spread over two sectors */
251
+ i40e_debug (hw , I40E_DEBUG_NVM ,
252
+ "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n" ,
253
+ offset , words );
254
+ else
255
+ ret_code = i40e_aq_read_nvm (hw , module_pointer ,
256
+ 2 * offset , /*bytes*/
257
+ 2 * words , /*bytes*/
258
+ data , last_command , & cmd_details );
259
+
260
+ return ret_code ;
261
+ }
262
+
263
+ /**
264
+ * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
265
+ * @hw: pointer to the HW structure
266
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
267
+ * @data: word read from the Shadow RAM
268
+ *
269
+ * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
270
+ **/
271
+ static i40e_status i40e_read_nvm_word_aq (struct i40e_hw * hw , u16 offset ,
272
+ u16 * data )
273
+ {
274
+ i40e_status ret_code = I40E_ERR_TIMEOUT ;
275
+
276
+ ret_code = i40e_read_nvm_aq (hw , 0x0 , offset , 1 , data , true);
277
+ * data = le16_to_cpu (* (__le16 * )data );
278
+
279
+ return ret_code ;
280
+ }
281
+
214
282
/**
215
283
* i40e_read_nvm_word - Reads Shadow RAM
216
284
* @hw: pointer to the HW structure
@@ -222,6 +290,8 @@ static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
222
290
i40e_status i40e_read_nvm_word (struct i40e_hw * hw , u16 offset ,
223
291
u16 * data )
224
292
{
293
+ if (hw -> mac .type == I40E_MAC_X722 )
294
+ return i40e_read_nvm_word_aq (hw , offset , data );
225
295
return i40e_read_nvm_word_srctl (hw , offset , data );
226
296
}
227
297
@@ -256,6 +326,63 @@ static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
256
326
return ret_code ;
257
327
}
258
328
329
+ /**
330
+ * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
331
+ * @hw: pointer to the HW structure
332
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
333
+ * @words: (in) number of words to read; (out) number of words actually read
334
+ * @data: words read from the Shadow RAM
335
+ *
336
+ * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
337
+ * method. The buffer read is preceded by the NVM ownership take
338
+ * and followed by the release.
339
+ **/
340
+ static i40e_status i40e_read_nvm_buffer_aq (struct i40e_hw * hw , u16 offset ,
341
+ u16 * words , u16 * data )
342
+ {
343
+ i40e_status ret_code ;
344
+ u16 read_size = * words ;
345
+ bool last_cmd = false;
346
+ u16 words_read = 0 ;
347
+ u16 i = 0 ;
348
+
349
+ do {
350
+ /* Calculate number of bytes we should read in this step.
351
+ * FVL AQ do not allow to read more than one page at a time or
352
+ * to cross page boundaries.
353
+ */
354
+ if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS )
355
+ read_size = min (* words ,
356
+ (u16 )(I40E_SR_SECTOR_SIZE_IN_WORDS -
357
+ (offset % I40E_SR_SECTOR_SIZE_IN_WORDS )));
358
+ else
359
+ read_size = min ((* words - words_read ),
360
+ I40E_SR_SECTOR_SIZE_IN_WORDS );
361
+
362
+ /* Check if this is last command, if so set proper flag */
363
+ if ((words_read + read_size ) >= * words )
364
+ last_cmd = true;
365
+
366
+ ret_code = i40e_read_nvm_aq (hw , 0x0 , offset , read_size ,
367
+ data + words_read , last_cmd );
368
+ if (ret_code )
369
+ goto read_nvm_buffer_aq_exit ;
370
+
371
+ /* Increment counter for words already read and move offset to
372
+ * new read location
373
+ */
374
+ words_read += read_size ;
375
+ offset += read_size ;
376
+ } while (words_read < * words );
377
+
378
+ for (i = 0 ; i < * words ; i ++ )
379
+ data [i ] = le16_to_cpu (((__le16 * )data )[i ]);
380
+
381
+ read_nvm_buffer_aq_exit :
382
+ * words = words_read ;
383
+ return ret_code ;
384
+ }
385
+
259
386
/**
260
387
* i40e_read_nvm_buffer - Reads Shadow RAM buffer
261
388
* @hw: pointer to the HW structure
@@ -270,6 +397,8 @@ static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
270
397
i40e_status i40e_read_nvm_buffer (struct i40e_hw * hw , u16 offset ,
271
398
u16 * words , u16 * data )
272
399
{
400
+ if (hw -> mac .type == I40E_MAC_X722 )
401
+ return i40e_read_nvm_buffer_aq (hw , offset , words , data );
273
402
return i40e_read_nvm_buffer_srctl (hw , offset , words , data );
274
403
}
275
404
0 commit comments