24
24
25
25
try :
26
26
import os
27
+ import time
27
28
from sonic_platform_base .psu_base import PsuBase
28
29
from sonic_py_common .logger import Logger
30
+ from .device_data import DeviceDataManager
29
31
from .led import PsuLed , SharedLed , ComponentFaultyIndicator
30
32
from . import utils
31
33
from .vpd_parser import VpdParser
@@ -411,6 +413,7 @@ def get_voltage_high_threshold(self):
411
413
capability = utils .read_str_from_file (self .psu_voltage_capability )
412
414
if 'max' in capability :
413
415
max_voltage = utils .read_int_from_file (self .psu_voltage_max , log_func = logger .log_info )
416
+ max_voltage = InvalidPsuVolWA .run (self , max_voltage , self .psu_voltage_max )
414
417
return float (max_voltage ) / 1000
415
418
416
419
return None
@@ -431,6 +434,7 @@ def get_voltage_low_threshold(self):
431
434
capability = utils .read_str_from_file (self .psu_voltage_capability )
432
435
if 'min' in capability :
433
436
min_voltage = utils .read_int_from_file (self .psu_voltage_min , log_func = logger .log_info )
437
+ min_voltage = InvalidPsuVolWA .run (self , min_voltage , self .psu_voltage_min )
434
438
return float (min_voltage ) / 1000
435
439
436
440
return None
@@ -448,3 +452,69 @@ def get_maximum_supplied_power(self):
448
452
return float (power_max ) / 1000000
449
453
else :
450
454
return None
455
+
456
+
457
+ class InvalidPsuVolWA :
458
+ """This class is created as a workaround for a known hardware issue that the PSU voltage threshold could be a
459
+ invalid value 127998. Once we read a voltage threshold value equal to 127998, we should do following:
460
+ 1. Check the PSU vendor, it should be Delta
461
+ 2. Generate a temp sensor configuration file which contains a few set commands. Those set commands are the WA provided by low level team.
462
+ 3. Call "sensors -s -c <tmp_conf_file>"
463
+ 4. Wait for it to take effect
464
+
465
+ This issue is found on 3700, 3700c, 3800, 4600c
466
+ """
467
+
468
+ INVALID_VOLTAGE_VALUE = 127998
469
+ EXPECT_VENDOR_NAME = 'DELTA'
470
+ EXPECT_CAPACITY = '1100'
471
+ EXPECT_PLATFORMS = ['x86_64-mlnx_msn3700-r0' , 'x86_64-mlnx_msn3700c-r0' , 'x86_64-mlnx_msn3800-r0' , 'x86_64-mlnx_msn4600c-r0' ]
472
+ MFR_FIELD = 'MFR_NAME'
473
+ CAPACITY_FIELD = 'CAPACITY'
474
+ WAIT_TIME = 5
475
+
476
+ @classmethod
477
+ def run (cls , psu , threshold_value , threshold_file ):
478
+ if threshold_value != cls .INVALID_VOLTAGE_VALUE :
479
+ # If the threshold value is not an invalid value, just return
480
+ return threshold_value
481
+
482
+ platform_name = DeviceDataManager .get_platform_name ()
483
+ # Apply the WA to specified platforms
484
+ if platform_name not in cls .EXPECT_PLATFORMS :
485
+ # It is unlikely to go to this branch, so we log a warning here
486
+ logger .log_warning ('PSU {} threshold file {} value {}, but platform is {}' .format (psu .index , threshold_file , threshold_value , platform_name ))
487
+ return threshold_value
488
+
489
+ # Check PSU vendor, make sure it is DELTA
490
+ vendor_name = psu .vpd_parser .get_entry_value (cls .MFR_FIELD )
491
+ if vendor_name != 'N/A' and vendor_name != cls .EXPECT_VENDOR_NAME :
492
+ # It is unlikely to go to this branch, so we log a warning here
493
+ logger .log_warning ('PSU {} threshold file {} value {}, but its vendor is {}' .format (psu .index , threshold_file , threshold_value , vendor_name ))
494
+ return threshold_value
495
+
496
+ # Check PSU version, make sure it is 1100
497
+ capacity = psu .vpd_parser .get_entry_value (cls .CAPACITY_FIELD )
498
+ if capacity != 'N/A' and capacity != cls .EXPECT_CAPACITY :
499
+ logger .log_warning ('PSU {} threshold file {} value {}, but its capacity is {}' .format (psu .index , threshold_file , threshold_value , capacity ))
500
+ return threshold_value
501
+
502
+ # Run a sensor -s command to triger hardware to get the real threashold value
503
+ utils .run_command ('sensor -s' )
504
+
505
+ # Wait for the threshold value change
506
+ return cls .wait_set_done (threshold_file )
507
+
508
+ @classmethod
509
+ def wait_set_done (cls , threshold_file ):
510
+ wait_time = cls .WAIT_TIME
511
+ while wait_time > 0 :
512
+ value = utils .read_int_from_file (threshold_file , log_func = logger .log_info )
513
+ if value != cls .INVALID_VOLTAGE_VALUE :
514
+ return value
515
+
516
+ wait_time -= 1
517
+ time .sleep (1 )
518
+
519
+ logger .log_error ('sensor -s does not recover PSU threshold sensor after {} seconds' .format (cls .WAIT_TIME ))
520
+ return None
0 commit comments