2424
2525try :
2626 import os
27+ import time
2728 from sonic_platform_base .psu_base import PsuBase
2829 from sonic_py_common .logger import Logger
30+ from .device_data import DeviceDataManager
2931 from .led import PsuLed , SharedLed , ComponentFaultyIndicator
3032 from . import utils
3133 from .vpd_parser import VpdParser
@@ -411,6 +413,7 @@ def get_voltage_high_threshold(self):
411413 capability = utils .read_str_from_file (self .psu_voltage_capability )
412414 if 'max' in capability :
413415 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 )
414417 return float (max_voltage ) / 1000
415418
416419 return None
@@ -431,6 +434,7 @@ def get_voltage_low_threshold(self):
431434 capability = utils .read_str_from_file (self .psu_voltage_capability )
432435 if 'min' in capability :
433436 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 )
434438 return float (min_voltage ) / 1000
435439
436440 return None
@@ -448,3 +452,69 @@ def get_maximum_supplied_power(self):
448452 return float (power_max ) / 1000000
449453 else :
450454 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