Skip to content

Commit

Permalink
DellEmc: Platform 2.0 Api(chassis,fan,eeprom) for S6100 and Z9100
Browse files Browse the repository at this point in the history
  • Loading branch information
gengankarthik committed Jul 29, 2019
1 parent a5de31b commit f8eda1b
Show file tree
Hide file tree
Showing 7 changed files with 828 additions and 91 deletions.
179 changes: 110 additions & 69 deletions platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
#define FAN_TRAY_AIRFLOW 0x0116


/* FAN Z9100 */
/* FAN */
#define SMF_FAN_SPEED_ADDR 0x00F3
#define FAN_TRAY_1_SPEED 0x00F3
#define FAN_TRAY_1_FAN_2_SPEED 0x00F5
Expand All @@ -83,6 +83,11 @@
#define FAN_TRAY_5_FAN_1_SPEED 0x0103
#define FAN_TRAY_5_FAN_2_SPEED 0x0105
#define FAN_TRAY_5 4
#define FAN_1_SERIAL_CODE 0x0117
#define FAN_2_SERIAL_CODE 0x013A
#define FAN_3_SERIAL_CODE 0x015D
#define FAN_4_SERIAL_CODE 0x0180
#define FAN_5_SERIAL_CODE 0x01A3
#define FAN_601_FAULT (2 + 1)
#define IN28_INPUT (27 + 1)
#define IN404_INPUT (43 + 1)
Expand Down Expand Up @@ -1738,24 +1743,39 @@ static ssize_t show_psu(struct device *dev,

/* FAN and PSU EEPROM PPID format is:
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
static ssize_t show_psu_ppid(struct device *dev,
static ssize_t show_ppid(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
char psu_ppid[EEPROM_PPID_SIZE + 1] = {0};
char ppid[EEPROM_PPID_SIZE + 1] = {0};
char psu_mfg_date[EEPROM_MFG_DATE_SIZE + 1] = {0};
char psu_mfg_date_code[EEPROM_DATE_CODE_SIZE + 1] = {0};
char temp;
int i, reg, ret = 0, ppid_pos = 0;

switch(index) {

case 1:
// PPID starts from Country Code
/* PPID starts from Country Code*/
case 0:
reg = FAN_1_SERIAL_CODE;
break;
case 1:
reg = FAN_2_SERIAL_CODE;
break;
case 2:
reg = FAN_3_SERIAL_CODE;
break;
case 3:
reg = FAN_4_SERIAL_CODE;
break;
case 4:
reg = FAN_5_SERIAL_CODE;
break;
case 10:
reg = PSU_1_COUNTRY_CODE;
break;
case 2:
case 11:
reg = PSU_2_COUNTRY_CODE;
break;
default:
Expand All @@ -1764,89 +1784,100 @@ static ssize_t show_psu_ppid(struct device *dev,

// Get Country Code
for( i = 0; i < EEPROM_COUNTRY_CODE_SIZE; i++) {
psu_ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
psu_ppid[ppid_pos++] = '-';
ppid[ppid_pos++] = '-';

// Get Part Number
for( i = 0; i < EEPROM_PART_NO_SIZE; i++) {
psu_ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
psu_ppid[ppid_pos++] = '-';
ppid[ppid_pos++] = '-';

// Get Manufacture ID
for( i = 0; i < EEPROM_MFG_ID_SIZE; i++) {
psu_ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
psu_ppid[ppid_pos++] = '-';

// Get Manufacture date
for( i = 0; i < EEPROM_MFG_DATE_SIZE; i++) {
psu_mfg_date[i] = (char)smf_read_reg(data,reg++);
}

/* Converting 6 digit date code [yymmdd] to 3 digit[ymd]
Year Starting from 2010 [0-9] , Day : 1-9 and A-V , Month : 1-9 and A-C */
// Year Validation and Conversion
if( ( psu_mfg_date[0] == '1' ) && ( psu_mfg_date[1] >= '0' ) && ( psu_mfg_date[1] <= '9') )
{
psu_mfg_date_code[0] = psu_mfg_date[1];
}
else
{
psu_mfg_date_code[0] = ' ';
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
ppid[ppid_pos++] = '-';
if(index > 9){ //Applicable only for PSU
// Get Manufacture date
for( i = 0; i < EEPROM_MFG_DATE_SIZE; i++) {
psu_mfg_date[i] = (char)smf_read_reg(data,reg++);
}

// Month Validation and Conversion
temp = ( ( psu_mfg_date[2] - 0x30 ) * 10 ) + ( psu_mfg_date[3] - 0x30 );
if( ( temp >= 1) && ( temp < 10) )
{
psu_mfg_date_code[1] = temp + 0x30; // 0- 9
}
else if ( ( temp >= 10) && ( temp <= 12) )
{
psu_mfg_date_code[1] = temp + 0x37; // A-C
}
else
{
psu_mfg_date_code[1]= ' ';
}
/* Converting 6 digit date code [yymmdd] to 3 digit[ymd]
Year Starting from 2010 [0-9] , Day : 1-9 and A-V , Month : 1-9 and A-C */
// Year Validation and Conversion
if( ( psu_mfg_date[0] == '1' ) && ( psu_mfg_date[1] >= '0' ) && ( psu_mfg_date[1] <= '9') )
{
psu_mfg_date_code[0] = psu_mfg_date[1];
}
else
{
psu_mfg_date_code[0] = ' ';
}

// Month Validation and Conversion
temp = ( ( psu_mfg_date[2] - 0x30 ) * 10 ) + ( psu_mfg_date[3] - 0x30 );
if( ( temp >= 1) && ( temp < 10) )
{
psu_mfg_date_code[1] = temp + 0x30; // 0- 9
}
else if ( ( temp >= 10) && ( temp <= 12) )
{
psu_mfg_date_code[1] = temp + 0x37; // A-C
}
else
{
psu_mfg_date_code[1]= ' ';
}

// Date Validation and Conversion
temp = ( ( psu_mfg_date[4] - 0x30 ) * 10 ) + ( psu_mfg_date[5] - 0x30 );
if( ( temp >= 1) && ( temp < 10) )
{
psu_mfg_date_code[2] = temp + 0x30; // 0- 9
}
else if( ( temp >= 10) && ( temp <= 31) )
{
psu_mfg_date_code[2] = temp + 0x37; // A-V
}
else
{
psu_mfg_date_code[2] = ' ';
// Date Validation and Conversion
temp = ( ( psu_mfg_date[4] - 0x30 ) * 10 ) + ( psu_mfg_date[5] - 0x30 );
if( ( temp >= 1) && ( temp < 10) )
{
psu_mfg_date_code[2] = temp + 0x30; // 0- 9
}
else if( ( temp >= 10) && ( temp <= 31) )
{
psu_mfg_date_code[2] = temp + 0x37; // A-V
}
else
{
psu_mfg_date_code[2] = ' ';
}
for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
ppid[ppid_pos++] = psu_mfg_date_code[i];
}
}else{
for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
}

for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
psu_ppid[ppid_pos++] = psu_mfg_date_code[i];
}
psu_ppid[ppid_pos++] = '-';
ppid[ppid_pos++] = '-';

// Get Serial Number
for( i = 0; i < EEPROM_SERIAL_NO_SIZE; i++) {
psu_ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
psu_ppid[ppid_pos++] = '-';
ppid[ppid_pos++] = '-';

// Skipping service tag in PPID
reg += EEPROM_SERVICE_TAG_SIZE;
if(index > 9){
// Skipping PSU service tag in PPID
reg += EEPROM_SERVICE_TAG_SIZE;
}
else{
// Skipping FAN partno tag in PPID
reg += EEPROM_PART_NO_SIZE;
}

// Get Label Revision
for( i = 0; i < EEPROM_LABEL_REV_SIZE; i++) {
psu_ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}

return sprintf(buf, "%s\n",psu_ppid);
return sprintf(buf, "%s\n",ppid);
}

static umode_t smf_psu_is_visible(struct kobject *kobj,
Expand Down Expand Up @@ -1924,14 +1955,19 @@ static SENSOR_DEVICE_ATTR(fan7_airflow, S_IRUGO, show_fan_airflow, NULL, 3);
static SENSOR_DEVICE_ATTR(fan9_airflow, S_IRUGO, show_fan_airflow, NULL, 4);
static SENSOR_DEVICE_ATTR(fan11_airflow, S_IRUGO, show_psu_fan, NULL, 0);
static SENSOR_DEVICE_ATTR(fan12_airflow, S_IRUGO, show_psu_fan, NULL, 3);
static SENSOR_DEVICE_ATTR(fan1_serialno, S_IRUGO, show_ppid, NULL, 0);
static SENSOR_DEVICE_ATTR(fan3_serialno, S_IRUGO, show_ppid, NULL, 1);
static SENSOR_DEVICE_ATTR(fan5_serialno, S_IRUGO, show_ppid, NULL, 2);
static SENSOR_DEVICE_ATTR(fan7_serialno, S_IRUGO, show_ppid, NULL, 3);
static SENSOR_DEVICE_ATTR(fan9_serialno, S_IRUGO, show_ppid, NULL, 4);
/* IOM status */
static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44);
static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45);

static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1);
static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6);
static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_psu_ppid, NULL, 1);
static SENSOR_DEVICE_ATTR(psu2_serialno, S_IRUGO, show_psu_ppid, NULL, 2);
static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10);
static SENSOR_DEVICE_ATTR(psu2_serialno, S_IRUGO, show_ppid, NULL, 11);
static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10);

/* SMF Version */
Expand Down Expand Up @@ -1964,6 +2000,11 @@ static struct attribute *smf_dell_attrs[] = {
&sensor_dev_attr_psu2_presence.dev_attr.attr,
&sensor_dev_attr_psu1_serialno.dev_attr.attr,
&sensor_dev_attr_psu2_serialno.dev_attr.attr,
&sensor_dev_attr_fan1_serialno.dev_attr.attr,
&sensor_dev_attr_fan3_serialno.dev_attr.attr,
&sensor_dev_attr_fan5_serialno.dev_attr.attr,
&sensor_dev_attr_fan7_serialno.dev_attr.attr,
&sensor_dev_attr_fan9_serialno.dev_attr.attr,
&sensor_dev_attr_current_total_power.dev_attr.attr,
NULL
};
Expand All @@ -1980,7 +2021,7 @@ static const struct attribute_group *smf_groups[] = {
&smf_vsen_group,
&smf_curr_group,
&smf_tcpu_group,
&smf_dell_group,
&smf_dell_group,
NULL
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python

#############################################################################
# DELLEMC
# DELLEMC S6100
#
# Module contains an implementation of SONiC Platform Base API and
# provides the platform information
Expand All @@ -13,6 +13,7 @@
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.psu import Psu
from sonic_platform.fan import Fan
from eeprom import Eeprom
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

Expand Down Expand Up @@ -42,8 +43,10 @@ class Chassis(ChassisBase):
power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED

def __init__(self):
ChassisBase.__init__(self)

ChassisBase.__init__(self)
# Initialize EEPROM
self.sys_eeprom = Eeprom()
for i in range(MAX_S6100_FAN):
fan = Fan(i)
self._fan_list.append(fan)
Expand All @@ -52,7 +55,7 @@ def __init__(self):
psu = Psu(i)
self._psu_list.append(psu)

def get_pmc_register(self, reg_name):
def _get_pmc_register(self, reg_name):
# On successful read, returns the value read from given
# reg_name and on failure returns 'ERR'
rv = 'ERR'
Expand All @@ -71,12 +74,79 @@ def get_pmc_register(self, reg_name):
rv = rv.lstrip(" ")
return rv

def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
return self.sys_eeprom.modelstr()

def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
return True

def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return self.sys_eeprom.part_number_str()

def get_serial(self):
"""
Retrieves the serial number of the device (Service tag)
Returns:
string: Serial number of device
"""
return self.sys_eeprom.serial_str()

def get_base_mac(self):
"""
Retrieves the base MAC address for the chassis
Returns:
A string containing the MAC address in the format
'XX:XX:XX:XX:XX:XX'
"""
return self.sys_eeprom.base_mac_addr()

def get_serial_number(self):
"""
Retrieves the hardware serial number for the chassis
Returns:
A string containing the hardware serial number for this chassis.
"""
return self.sys_eeprom.serial_number_str()

def get_system_eeprom_info(self):
"""
Retrieves the full content of system EEPROM information for the chassis
Returns:
A dictionary where keys are the type code defined in
OCP ONIE TlvInfo EEPROM format and values are their corresponding
values.
"""

def get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
Returns:
A tuple (string, string) where the first element is a string
containing the cause of the previous reboot. This string must be
one of the predefined strings in this class. If the first string
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
to pass a description of the reboot cause.
"""
reset_reason = int(self.get_pmc_register('smf_reset_reason'))
power_reason = int(self.get_pmc_register('smf_poweron_reason'))

reset_reason = int(self._get_pmc_register('smf_reset_reason'))
power_reason = int(self._get_pmc_register('smf_poweron_reason'))

# Reset_Reason = 11 ==> PowerLoss
# So return the reboot reason from Last Power_Reason Dictionary
Expand All @@ -93,4 +163,3 @@ def get_reboot_cause(self):
return (self.reset_reason_dict[reset_reason], None)

return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")

Loading

0 comments on commit f8eda1b

Please sign in to comment.