Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DellEMC S6100 : Platform2.0 API implementation for PSU #3132

Merged
merged 1 commit into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 132 additions & 1 deletion platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
#define PSU_1_OUTPUT_CURRENT 0x0244
#define PSU_1_INPUT_POWER 0x0246
#define PSU_1_OUTPUT_POWER 0x0248
#define PSU_1_FAN_SPEED 0x023B
#define PSU_1_COUNTRY_CODE 0x024A

/* PSU2 */
#define PSU_2_MAX_POWER 0x026D
Expand All @@ -127,6 +127,7 @@
#define PSU_2_OUTPUT_CURRENT 0x027D
#define PSU_2_INPUT_POWER 0x027F
#define PSU_2_OUTPUT_POWER 0x0281
#define PSU_2_COUNTRY_CODE 0x0283

/* TEMP */
#define TEMP_SENSOR_1 0x0014
Expand All @@ -151,6 +152,20 @@
#define CPU_7_MONITOR_STATUS 0x02E8
#define CPU_8_MONITOR_STATUS 0x02E9

/* EEPROM PPID */
/* FAN and PSU EEPROM PPID format is:
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
#define EEPROM_COUNTRY_CODE_SIZE 2
#define EEPROM_PART_NO_SIZE 6
#define EEPROM_MFG_ID_SIZE 5
#define EEPROM_MFG_DATE_SIZE 8
#define EEPROM_DATE_CODE_SIZE 3
#define EEPROM_SERIAL_NO_SIZE 4
#define EEPROM_SERVICE_TAG_SIZE 7
#define EEPROM_LABEL_REV_SIZE 3
#define EEPROM_PPID_SIZE 28



unsigned long *mmio;
static struct kobject *dell_kobj;
Expand Down Expand Up @@ -1721,6 +1736,118 @@ static ssize_t show_psu(struct device *dev,
return sprintf(buf, "%u\n", pow);
}

/* 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,
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 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
reg = PSU_1_COUNTRY_CODE;
break;
case 2:
reg = PSU_2_COUNTRY_CODE;
break;
default:
return ret;
}

// Get Country Code
for( i = 0; i < EEPROM_COUNTRY_CODE_SIZE; i++) {
psu_ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
psu_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++);
}
psu_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] = ' ';
}

// 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] = ' ';
}

for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
psu_ppid[ppid_pos++] = psu_mfg_date_code[i];
}
psu_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++);
}
psu_ppid[ppid_pos++] = '-';

// Skipping service tag in PPID
reg += EEPROM_SERVICE_TAG_SIZE;

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

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

static umode_t smf_psu_is_visible(struct kobject *kobj,
struct attribute *a, int n)
Expand Down Expand Up @@ -1803,6 +1930,8 @@ 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(current_total_power, S_IRUGO, show_psu, NULL, 10);

/* SMF Version */
Expand Down Expand Up @@ -1833,6 +1962,8 @@ static struct attribute *smf_dell_attrs[] = {
&sensor_dev_attr_iom_presence.dev_attr.attr,
&sensor_dev_attr_psu1_presence.dev_attr.attr,
&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_current_total_power.dev_attr.attr,
NULL
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@
try:
import os
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.psu import Psu
from sonic_platform.fan import Fan
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

MAX_S6100_FAN = 4
MAX_S6100_PSU = 2


class Chassis(ChassisBase):
"""
Expand All @@ -39,19 +44,28 @@ class Chassis(ChassisBase):
def __init__(self):
ChassisBase.__init__(self)

for i in range(MAX_S6100_FAN):
fan = Fan(i)
self._fan_list.append(fan)

for i in range(MAX_S6100_PSU):
psu = Psu(i)
self._psu_list.append(psu)

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'
mb_reg_file = self.MAILBOX_DIR+'/'+reg_name
mb_reg_file = self.MAILBOX_DIR + '/' + reg_name

if (not os.path.isfile(mb_reg_file)):
print mb_reg_file, 'not found !'
return rv

try:
with open(mb_reg_file, 'r') as fd:
rv = fd.read()
except Exception as error:
logging.error("Unable to open ", mb_reg_file, "file !")
rv = 'ERR'

rv = rv.rstrip('\r\n')
rv = rv.lstrip(" ")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python

########################################################################
# DellEMC
#
# Module contains an implementation of SONiC Platform Base API and
# provides the Fans' information which are available in the platform
#
########################################################################


try:
import os
from sonic_platform_base.fan_base import FanBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")


MAX_S6100_PSU_FAN_SPEED = 18000
MAX_S6100_FAN_SPEED = 16000


class Fan(FanBase):
"""DellEMC Platform-specific FAN class"""

HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/"
HWMON_NODE = os.listdir(HWMON_DIR)[0]
MAILBOX_DIR = HWMON_DIR + HWMON_NODE

def __init__(self, fan_index, psu_fan=False):
self.is_psu_fan = psu_fan
if not self.is_psu_fan:
# Fan is 1-based in DellEMC platforms
self.index = fan_index + 1
self.get_fan_speed_reg = "fan{}_input".format(2*self.index - 1)
self.max_fan_speed = MAX_S6100_FAN_SPEED
else:
# PSU Fan index starts from 11
self.index = fan_index + 10
self.get_fan_speed_reg = "fan{}_input".format(self.index)
self.max_fan_speed = MAX_S6100_PSU_FAN_SPEED

Loading