Skip to content

Commit

Permalink
[Mellanox] [201911] Fix issue: set fan led in certain order causes in…
Browse files Browse the repository at this point in the history
…correct physical fan led color (#6019)

* Fix issue: fan led colo status

* Fix LGTM warning

* Support fan led management for non-swapable fan
  • Loading branch information
Junchao-Mellanox authored Nov 26, 2020
1 parent 33a6e56 commit 37eb088
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 8 deletions.
51 changes: 43 additions & 8 deletions platform/mellanox/mlnx-platform-api/sonic_platform/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

try:
from sonic_platform_base.fan_base import FanBase

from .led import SharedLed, ComponentFaultyIndicator
from .utils import read_int_from_file, read_str_from_file, write_file
except ImportError as e:
raise ImportError (str(e) + "- required module not found")
Expand All @@ -33,6 +35,8 @@
# 1. don't have fanX_status and should be treated as always present
platform_with_unplugable_fan = ['x86_64-mlnx_msn2010-r0', 'x86_64-mlnx_msn2100-r0']

VIRTUAL_DRAWER_INDEX = 0


class Fan(FanBase):
"""Platform-specific Fan class"""
Expand All @@ -41,6 +45,10 @@ class Fan(FanBase):
min_cooling_level = 2
MIN_VALID_COOLING_LEVEL = 1
MAX_VALID_COOLING_LEVEL = 10

# Fan drawer leds
fan_drawer_leds = {}

# PSU fan speed vector
PSU_FAN_SPEED = ['0x3c', '0x3c', '0x3c', '0x3c', '0x3c',
'0x3c', '0x3c', '0x46', '0x50', '0x5a', '0x64']
Expand Down Expand Up @@ -71,11 +79,31 @@ def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, pl
self.psu_i2c_command_path = os.path.join(CONFIG_PATH, 'fan_command')

self.fan_status_path = "fan{}_fault".format(self.index)
self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index)
self.fan_red_led_path = "led_fan{}_red".format(self.drawer_index)
self.fan_orange_led_path = "led_fan{}_orange".format(self.drawer_index)
self.fan_pwm_path = "pwm1"
self.fan_led_cap_path = "led_fan{}_capability".format(self.drawer_index)

if not self.is_psu_fan: # We don't support PSU led management in 201911
if not self.always_presence:
if self.drawer_index not in Fan.fan_drawer_leds:
shared_led = SharedLed()
Fan.fan_drawer_leds[self.drawer_index] = shared_led
else:
shared_led = Fan.fan_drawer_leds[self.drawer_index]
self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index)
self.fan_red_led_path = "led_fan{}_red".format(self.drawer_index)
self.fan_orange_led_path = "led_fan{}_orange".format(self.drawer_index)
self.fan_led_cap_path = "led_fan{}_capability".format(self.drawer_index)
else: # For 2010/2100, all fans share one LED
if VIRTUAL_DRAWER_INDEX not in Fan.fan_drawer_leds:
shared_led = SharedLed()
Fan.fan_drawer_leds[VIRTUAL_DRAWER_INDEX] = shared_led
else:
shared_led = Fan.fan_drawer_leds[VIRTUAL_DRAWER_INDEX]
self.fan_green_led_path = "led_fan_green"
self.fan_red_led_path = "led_fan_red"
self.fan_orange_led_path = "led_fan_orange"
self.fan_led_cap_path = "led_fan_capability"

self.fault_indicator = ComponentFaultyIndicator(shared_led)

if has_fan_dir:
self.fan_dir = FAN_DIR
else:
Expand Down Expand Up @@ -250,6 +278,16 @@ def _get_led_capability(self):
return cap_list

def set_status_led(self, color):
if self.is_psu_fan:
return False
self.fault_indicator.set_status(color)
if not self.always_presence:
target_color = Fan.fan_drawer_leds[self.drawer_index].get_status()
else:
target_color = Fan.fan_drawer_leds[VIRTUAL_DRAWER_INDEX].get_status()
return self._set_status_led(target_color)

def _set_status_led(self, color):
"""
Set led to expected color
Expand All @@ -264,9 +302,6 @@ def set_status_led(self, color):
if led_cap_list is None:
return False

if self.is_psu_fan:
# PSU fan led status is not able to set
return False
status = False
try:
if color == 'green':
Expand Down
51 changes: 51 additions & 0 deletions platform/mellanox/mlnx-platform-api/sonic_platform/led.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
class Led(object):
STATUS_LED_COLOR_GREEN = 'green'
STATUS_LED_COLOR_GREEN_BLINK = 'green_blink'
STATUS_LED_COLOR_RED = 'red'
STATUS_LED_COLOR_RED_BLINK = 'red_blink'
STATUS_LED_COLOR_ORANGE = 'orange'
STATUS_LED_COLOR_ORANGE_BLINK = 'orange_blink'
STATUS_LED_COLOR_OFF = 'off'


class SharedLed(object):
LED_PRIORITY = {
Led.STATUS_LED_COLOR_RED: 0,
Led.STATUS_LED_COLOR_GREEN: 1
}

def __init__(self):
self._virtual_leds = []
self._target_color = Led.STATUS_LED_COLOR_GREEN

def add_virtual_leds(self, led):
self._virtual_leds.append(led)

def update_status_led(self):
target_color = Led.STATUS_LED_COLOR_GREEN
for virtual_led in self._virtual_leds:
if SharedLed.LED_PRIORITY[virtual_led.get_led_color()] < SharedLed.LED_PRIORITY[target_color]:
target_color = virtual_led.get_led_color()

self._target_color = target_color
return True

def get_status(self):
return self._target_color


class ComponentFaultyIndicator(object):
def __init__(self, shared_led):
self._color = Led.STATUS_LED_COLOR_GREEN
self._shared_led = shared_led
self._shared_led.add_virtual_leds(self)

def set_status(self, color):
self._color = color
return self._shared_led.update_status_led()

def get_led_color(self):
return self._color

def get_status(self):
return self._shared_led.get_status()

0 comments on commit 37eb088

Please sign in to comment.