@@ -293,7 +293,40 @@ static int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num)
293
293
return 0 ;
294
294
}
295
295
296
- static int mlx5_eeprom_page (int offset )
296
+ static int mlx5_query_module_id (struct mlx5_core_dev * dev , int module_num ,
297
+ u8 * module_id )
298
+ {
299
+ u32 in [MLX5_ST_SZ_DW (mcia_reg )] = {};
300
+ u32 out [MLX5_ST_SZ_DW (mcia_reg )];
301
+ int err , status ;
302
+ u8 * ptr ;
303
+
304
+ MLX5_SET (mcia_reg , in , i2c_device_address , MLX5_I2C_ADDR_LOW );
305
+ MLX5_SET (mcia_reg , in , module , module_num );
306
+ MLX5_SET (mcia_reg , in , device_address , 0 );
307
+ MLX5_SET (mcia_reg , in , page_number , 0 );
308
+ MLX5_SET (mcia_reg , in , size , 1 );
309
+ MLX5_SET (mcia_reg , in , l , 0 );
310
+
311
+ err = mlx5_core_access_reg (dev , in , sizeof (in ), out ,
312
+ sizeof (out ), MLX5_REG_MCIA , 0 , 0 );
313
+ if (err )
314
+ return err ;
315
+
316
+ status = MLX5_GET (mcia_reg , out , status );
317
+ if (status ) {
318
+ mlx5_core_err (dev , "query_mcia_reg failed: status: 0x%x\n" ,
319
+ status );
320
+ return - EIO ;
321
+ }
322
+ ptr = MLX5_ADDR_OF (mcia_reg , out , dword_0 );
323
+
324
+ * module_id = ptr [0 ];
325
+
326
+ return 0 ;
327
+ }
328
+
329
+ static int mlx5_qsfp_eeprom_page (u16 offset )
297
330
{
298
331
if (offset < MLX5_EEPROM_PAGE_LENGTH )
299
332
/* Addresses between 0-255 - page 00 */
@@ -307,7 +340,7 @@ static int mlx5_eeprom_page(int offset)
307
340
MLX5_EEPROM_HIGH_PAGE_LENGTH );
308
341
}
309
342
310
- static int mlx5_eeprom_high_page_offset (int page_num )
343
+ static int mlx5_qsfp_eeprom_high_page_offset (int page_num )
311
344
{
312
345
if (!page_num ) /* Page 0 always start from low page */
313
346
return 0 ;
@@ -316,35 +349,62 @@ static int mlx5_eeprom_high_page_offset(int page_num)
316
349
return page_num * MLX5_EEPROM_HIGH_PAGE_LENGTH ;
317
350
}
318
351
352
+ static void mlx5_qsfp_eeprom_params_set (u16 * i2c_addr , int * page_num , u16 * offset )
353
+ {
354
+ * i2c_addr = MLX5_I2C_ADDR_LOW ;
355
+ * page_num = mlx5_qsfp_eeprom_page (* offset );
356
+ * offset -= mlx5_qsfp_eeprom_high_page_offset (* page_num );
357
+ }
358
+
359
+ static void mlx5_sfp_eeprom_params_set (u16 * i2c_addr , int * page_num , u16 * offset )
360
+ {
361
+ * i2c_addr = MLX5_I2C_ADDR_LOW ;
362
+ * page_num = 0 ;
363
+
364
+ if (* offset < MLX5_EEPROM_PAGE_LENGTH )
365
+ return ;
366
+
367
+ * i2c_addr = MLX5_I2C_ADDR_HIGH ;
368
+ * offset -= MLX5_EEPROM_PAGE_LENGTH ;
369
+ }
370
+
319
371
int mlx5_query_module_eeprom (struct mlx5_core_dev * dev ,
320
372
u16 offset , u16 size , u8 * data )
321
373
{
322
- int module_num , page_num , status , err ;
374
+ int module_num , status , err , page_num = 0 ;
375
+ u32 in [MLX5_ST_SZ_DW (mcia_reg )] = {};
323
376
u32 out [MLX5_ST_SZ_DW (mcia_reg )];
324
- u32 in [ MLX5_ST_SZ_DW ( mcia_reg )] ;
325
- u16 i2c_addr ;
326
- void * ptr = MLX5_ADDR_OF ( mcia_reg , out , dword_0 ) ;
377
+ u16 i2c_addr = 0 ;
378
+ u8 module_id ;
379
+ void * ptr ;
327
380
328
381
err = mlx5_query_module_num (dev , & module_num );
329
382
if (err )
330
383
return err ;
331
384
332
- memset (in , 0 , sizeof (in ));
333
- size = min_t (int , size , MLX5_EEPROM_MAX_BYTES );
334
-
335
- /* Get the page number related to the given offset */
336
- page_num = mlx5_eeprom_page (offset );
385
+ err = mlx5_query_module_id (dev , module_num , & module_id );
386
+ if (err )
387
+ return err ;
337
388
338
- /* Set the right offset according to the page number,
339
- * For page_num > 0, relative offset is always >= 128 (high page).
340
- */
341
- offset -= mlx5_eeprom_high_page_offset (page_num );
389
+ switch (module_id ) {
390
+ case MLX5_MODULE_ID_SFP :
391
+ mlx5_sfp_eeprom_params_set (& i2c_addr , & page_num , & offset );
392
+ break ;
393
+ case MLX5_MODULE_ID_QSFP :
394
+ case MLX5_MODULE_ID_QSFP_PLUS :
395
+ case MLX5_MODULE_ID_QSFP28 :
396
+ mlx5_qsfp_eeprom_params_set (& i2c_addr , & page_num , & offset );
397
+ break ;
398
+ default :
399
+ mlx5_core_err (dev , "Module ID not recognized: 0x%x\n" , module_id );
400
+ return - EINVAL ;
401
+ }
342
402
343
403
if (offset + size > MLX5_EEPROM_PAGE_LENGTH )
344
404
/* Cross pages read, read until offset 256 in low page */
345
405
size -= offset + size - MLX5_EEPROM_PAGE_LENGTH ;
346
406
347
- i2c_addr = MLX5_I2C_ADDR_LOW ;
407
+ size = min_t ( int , size , MLX5_EEPROM_MAX_BYTES ) ;
348
408
349
409
MLX5_SET (mcia_reg , in , l , 0 );
350
410
MLX5_SET (mcia_reg , in , module , module_num );
@@ -365,6 +425,7 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
365
425
return - EIO ;
366
426
}
367
427
428
+ ptr = MLX5_ADDR_OF (mcia_reg , out , dword_0 );
368
429
memcpy (data , ptr , size );
369
430
370
431
return size ;
0 commit comments