forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Platform Driver Developement Framework (PDDF) (sonic-net#4756)
This change introduces PDDF which is described here: sonic-net/SONiC#536 Most of the platform bring up effort goes in developing the platform device drivers, SONiC platform APIs and validating them. Typically each platform vendor writes their own drivers and platform APIs which is very tailor made to that platform. This involves writing code, building, installing it on the target platform devices and testing. Many of the details of the platform are hard coded into these drivers, from the HW spec. They go through this cycle repetitively till everything works fine, and is validated before upstreaming the code. PDDF aims to make this platform driver and platform APIs development process much simpler by providing a data driven development framework. This is enabled by: JSON descriptor files for platform data Generic data-driven drivers for various devices Generic SONiC platform APIs Vendor specific extensions for customisation and extensibility Signed-off-by: Fuzail Khan <[email protected]>
- Loading branch information
1 parent
a1de279
commit c94265d
Showing
112 changed files
with
18,064 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#!/usr/bin/env python | ||
|
||
try: | ||
import os | ||
import sys | ||
import json | ||
sys.path.append('/usr/share/sonic/platform/plugins') | ||
import pddfparse | ||
#from sonic_eeprom import eeprom_base | ||
from sonic_eeprom import eeprom_tlvinfo | ||
except ImportError, e: | ||
raise ImportError (str(e) + "- required module not found") | ||
|
||
|
||
class board(eeprom_tlvinfo.TlvInfoDecoder): | ||
_TLV_INFO_MAX_LEN = 256 | ||
def __init__(self, name, path, cpld_root, ro): | ||
global pddf_obj | ||
global plugin_data | ||
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: | ||
plugin_data = json.load(pd) | ||
|
||
pddf_obj = pddfparse.PddfParse() | ||
# system EEPROM always has device name EEPROM1 | ||
self.eeprom_path = pddf_obj.get_path("EEPROM1", "eeprom") | ||
super(board, self).__init__(self.eeprom_path, 0, '', True) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
#!/usr/bin/env python | ||
|
||
|
||
# Sample pddf_fanutil file | ||
# All the supported FAN SysFS aattributes are | ||
#- fan<idx>_present | ||
#- fan<idx>_direction | ||
#- fan<idx>_input | ||
#- fan<idx>_pwm | ||
#- fan<idx>_fault | ||
# where idx is in the range [1-12] | ||
# | ||
|
||
|
||
import os.path | ||
import sys | ||
sys.path.append('/usr/share/sonic/platform/plugins') | ||
import pddfparse | ||
import json | ||
|
||
try: | ||
from sonic_fan.fan_base import FanBase | ||
except ImportError as e: | ||
raise ImportError (str(e) + "- required module not found") | ||
|
||
class FanUtil(FanBase): | ||
"""PDDF generic FAN util class""" | ||
|
||
def __init__(self): | ||
FanBase.__init__(self) | ||
global pddf_obj | ||
global plugin_data | ||
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: | ||
plugin_data = json.load(pd) | ||
|
||
pddf_obj = pddfparse.PddfParse() | ||
self.platform = pddf_obj.get_platform() | ||
|
||
self.num_fans = (self.platform['num_fantrays'] * self.platform['num_fans_pertray'] ) | ||
|
||
def get_num_fans(self): | ||
return self.num_fans | ||
|
||
def get_presence(self, idx): | ||
# 1 based fan index | ||
if idx<1 or idx>self.num_fans: | ||
print "Invalid fan index %d\n"%idx | ||
return False | ||
|
||
attr_name = "fan"+ str(idx) +"_present" | ||
output = pddf_obj.get_attr_name_output("FAN-CTRL", attr_name) | ||
if not output: | ||
return False | ||
|
||
mode = output['mode'] | ||
presence = output['status'].rstrip() | ||
|
||
vmap = plugin_data['FAN']['present'][mode]['valmap'] | ||
|
||
if presence in vmap: | ||
status = vmap[presence] | ||
else: | ||
status = False | ||
|
||
return status | ||
|
||
def get_status(self, idx): | ||
# 1 based fan index | ||
if idx<1 or idx>self.num_fans: | ||
print "Invalid fan index %d\n"%idx | ||
return False | ||
|
||
speed = self.get_speed(idx) | ||
status = True if (speed != 0) else False | ||
return status | ||
|
||
def get_direction(self, idx): | ||
# 1 based fan index | ||
if idx<1 or idx>self.num_fans: | ||
print "Invalid fan index %d\n"%idx | ||
return None | ||
|
||
attr = "fan" + str(idx) + "_direction" | ||
output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) | ||
if not output: | ||
return None | ||
|
||
mode = output['mode'] | ||
val = output['status'] | ||
|
||
val = val.rstrip() | ||
vmap = plugin_data['FAN']['direction'][mode]['valmap'] | ||
|
||
|
||
if val in vmap: | ||
direction = vmap[val] | ||
else: | ||
direction = val | ||
|
||
return direction | ||
|
||
def get_directions(self): | ||
num_fan = self.get_num_fan(); | ||
|
||
for i in range(1, num_fan+1): | ||
attr = "fan" + str(i) + "_direction" | ||
output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) | ||
if not output: | ||
return None | ||
|
||
mode = output['mode'] | ||
val = output['status'] | ||
|
||
val = val.rstrip() | ||
vmap = plugin_data['FAN']['direction'][mode]['valmap'] | ||
|
||
direction = vmap[str(val)] | ||
|
||
print "FAN-%d direction is %s"%(i, direction) | ||
|
||
return 0 | ||
|
||
def get_speed(self, idx): | ||
# 1 based fan index | ||
if idx<1 or idx>self.num_fans: | ||
print "Invalid fan index %d\n"%idx | ||
return 0 | ||
|
||
attr = "fan" + str(idx) + "_input" | ||
output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) | ||
if not output: | ||
return 0 | ||
|
||
#mode = output['mode'] | ||
val = output['status'].rstrip() | ||
|
||
if val.isalpha(): | ||
return 0 | ||
else: | ||
rpm_speed = int(float(val)) | ||
|
||
return rpm_speed | ||
|
||
def get_speeds(self): | ||
num_fan = self.get_num_fan(); | ||
ret = "FAN_INDEX\t\tRPM\n" | ||
|
||
for i in range(1, num_fan+1): | ||
attr1 = "fan" + str(i) + "_input" | ||
output = pddf_obj.get_attr_name_output("FAN-CTRL", attr1) | ||
if not output: | ||
return "" | ||
|
||
#mode = output['mode'] | ||
val = output['status'].rstrip() | ||
|
||
if val.isalpha(): | ||
frpm = 0 | ||
else: | ||
frpm = int(val) | ||
|
||
ret += "FAN-%d\t\t\t%d\n"%(i, frpm) | ||
|
||
return ret | ||
|
||
def set_speed(self, val): | ||
if val<0 or val>100: | ||
print "Error: Invalid speed %d. Please provide a valid speed percentage"%val | ||
return False | ||
|
||
num_fan = self.num_fans | ||
if 'duty_cycle_to_pwm' not in plugin_data['FAN']: | ||
print "Setting fan speed is not allowed !" | ||
return False | ||
else: | ||
duty_cycle_to_pwm = eval(plugin_data['FAN']['duty_cycle_to_pwm']) | ||
pwm = duty_cycle_to_pwm(val) | ||
print "New Speed: %d%% - PWM value to be set is %d\n"%(val,pwm) | ||
|
||
for i in range(1, num_fan+1): | ||
attr = "fan" + str(i) + "_pwm" | ||
node = pddf_obj.get_path("FAN-CTRL", attr) | ||
if node is None: | ||
return False | ||
try: | ||
with open(node, 'w') as f: | ||
f.write(str(pwm)) | ||
except IOError: | ||
return False | ||
|
||
return True | ||
|
||
def dump_sysfs(self): | ||
return pddf_obj.cli_dump_dsysfs('fan') | ||
|
||
def get_change_event(self): | ||
""" | ||
TODO: This function need to be implemented | ||
when decide to support monitoring FAN(fand) | ||
on this platform. | ||
""" | ||
raise NotImplementedError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#!/usr/bin/env python | ||
|
||
import sys | ||
sys.path.append('/usr/share/sonic/platform/plugins') | ||
import pddfparse | ||
|
||
class LedUtil: | ||
color_map = { | ||
"STATUS_LED_COLOR_GREEN" : "on", | ||
"STATUS_LED_COLOR_RED" : "faulty", | ||
"STATUS_LED_COLOR_OFF" : "off" | ||
} | ||
|
||
def __init__(self): | ||
global pddf_obj | ||
pddf_obj = pddfparse.PddfParse() | ||
self.path="pddf/devices/led" | ||
self.cur_state_path="pddf/devices/led/cur_state" | ||
|
||
def set_status_led(self, led_device_name, color, color_state="SOLID"): | ||
if (not led_device_name in pddf_obj.data.keys()): | ||
status="ERROR: " + led_device_name + " is not configured" | ||
return (status) | ||
|
||
if (not color in self.color_map.keys()): | ||
status="ERROR: Invalid color" | ||
return (status) | ||
|
||
index=pddf_obj.data[led_device_name]['dev_attr']['index'] | ||
pddf_obj.create_attr('device_name', led_device_name, self.path) | ||
pddf_obj.create_attr('index', index, self.path) | ||
pddf_obj.create_attr('color', self.color_map[color], self.cur_state_path) | ||
pddf_obj.create_attr('color_state', color_state, self.cur_state_path) | ||
pddf_obj.create_attr('dev_ops', 'set_status', self.path) | ||
return ("Executed") | ||
|
||
def get_status_led(self, led_device_name): | ||
if (not led_device_name in pddf_obj.data.keys()): | ||
status="ERROR: " + led_device_name + " is not configured" | ||
return (status) | ||
|
||
index=pddf_obj.data[led_device_name]['dev_attr']['index'] | ||
pddf_obj.create_attr('device_name', led_device_name, self.path) | ||
pddf_obj.create_attr('index', index, self.path) | ||
pddf_obj.create_attr('dev_ops', 'get_status', self.path) | ||
color_f="/sys/kernel/" + self.cur_state_path +"/color" | ||
color_state_f="/sys/kernel/" + self.cur_state_path +"/color_state" | ||
|
||
try: | ||
with open(color_f, 'r') as f: | ||
color = f.read().strip("\r\n") | ||
with open(color_state_f, 'r') as f: | ||
color_state = f.read().strip("\r\n") | ||
except IOError: | ||
status="ERROR :" + color_f + " open failed" | ||
return (status) | ||
status = "%s-%s:\t%s %s\n"%(led_device_name, index, color, color_state) | ||
return (status) |
Oops, something went wrong.