[DellEMC S5232f] Updates and bug fixes for platform (#5887)
* Fix platform sensors * Fix issues reported in fpga driver * Update fixes for API 2.0 platform code
This commit is contained in:
parent
fd9bd40188
commit
89d9471654
@ -1,4 +1,3 @@
|
|||||||
{
|
{
|
||||||
"skip_ledd": true,
|
"skip_ledd": true
|
||||||
"skip_thermalctld": true
|
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,6 @@ struct fpgapci_dev {
|
|||||||
unsigned int irq_first;
|
unsigned int irq_first;
|
||||||
unsigned int irq_length;
|
unsigned int irq_length;
|
||||||
unsigned int irq_assigned;
|
unsigned int irq_assigned;
|
||||||
unsigned int xcvr_intr_count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int use_irq = 1;
|
static int use_irq = 1;
|
||||||
@ -227,13 +226,6 @@ enum {
|
|||||||
#define I2C_PCI_BUS_NUM_12 12
|
#define I2C_PCI_BUS_NUM_12 12
|
||||||
#define I2C_PCI_BUS_NUM_16 16
|
#define I2C_PCI_BUS_NUM_16 16
|
||||||
|
|
||||||
#define IRQ_LTCH_STS 0x20
|
|
||||||
#define PRSNT_LTCH_STS 0x10
|
|
||||||
|
|
||||||
#define PORT_CTRL_OFFSET 0x4000
|
|
||||||
#define PORT_STS_OFFSET 0x4004
|
|
||||||
#define PORT_IRQ_STS_OFFSET 0x4008
|
|
||||||
#define PORT_IRQ_EN_OFFSET 0x400C
|
|
||||||
#define MB_BRD_REV_TYPE 0x0008
|
#define MB_BRD_REV_TYPE 0x0008
|
||||||
#define MB_BRD_REV_MASK 0x00f0
|
#define MB_BRD_REV_MASK 0x00f0
|
||||||
#define MB_BRD_REV_00 0x0000
|
#define MB_BRD_REV_00 0x0000
|
||||||
@ -292,8 +284,6 @@ enum {
|
|||||||
#define MSI_VECTOR_REV_00 16
|
#define MSI_VECTOR_REV_00 16
|
||||||
#define MSI_VECTOR_REV_01 32
|
#define MSI_VECTOR_REV_01 32
|
||||||
|
|
||||||
#define FPGA_MSI_VECTOR_ID_4 4
|
|
||||||
#define FPGA_MSI_VECTOR_ID_5 5
|
|
||||||
#define FPGA_MSI_VECTOR_ID_8 8
|
#define FPGA_MSI_VECTOR_ID_8 8
|
||||||
#define FPGA_MSI_VECTOR_ID_9 9
|
#define FPGA_MSI_VECTOR_ID_9 9
|
||||||
#define FPGA_MSI_VECTOR_ID_10 10
|
#define FPGA_MSI_VECTOR_ID_10 10
|
||||||
@ -516,72 +506,6 @@ static int fpgai2c_poll(struct fpgalogic_i2c *i2c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf)
|
|
||||||
{
|
|
||||||
int ind = 0, port_status=0, port_irq_status=0;
|
|
||||||
struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev);
|
|
||||||
PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count);
|
|
||||||
for(ind=0;ind<64;ind++)
|
|
||||||
{
|
|
||||||
port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16));
|
|
||||||
port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16));
|
|
||||||
PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status);
|
|
||||||
}
|
|
||||||
return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count);
|
|
||||||
}
|
|
||||||
static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL);
|
|
||||||
|
|
||||||
static struct attribute *port_attrs[] = {
|
|
||||||
&dev_attr_port_msi.attr,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct attribute_group port_attr_grp = {
|
|
||||||
.attrs = port_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static irqreturn_t fpgaport_1_32_isr(int irq, void *dev)
|
|
||||||
{
|
|
||||||
struct pci_dev *pdev = dev;
|
|
||||||
struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev);
|
|
||||||
int ind = 0, port_status=0, port_irq_status=0;
|
|
||||||
for(ind=0;ind<32;ind++)
|
|
||||||
{
|
|
||||||
port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16));
|
|
||||||
if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS))
|
|
||||||
{
|
|
||||||
PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status);
|
|
||||||
//write on clear
|
|
||||||
iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fpgapci->xcvr_intr_count++;
|
|
||||||
PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count);
|
|
||||||
sysfs_notify(&pdev->dev.kobj, NULL, "port_msi");
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t fpgaport_33_64_isr(int irq, void *dev)
|
|
||||||
{
|
|
||||||
struct pci_dev *pdev = dev;
|
|
||||||
struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev);
|
|
||||||
int ind = 0, port_status=0, port_irq_status=0;
|
|
||||||
for(ind=32;ind<64;ind++)
|
|
||||||
{
|
|
||||||
port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16));
|
|
||||||
if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS))
|
|
||||||
{
|
|
||||||
PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status);
|
|
||||||
iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fpgapci->xcvr_intr_count++;
|
|
||||||
PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count);
|
|
||||||
sysfs_notify(&pdev->dev.kobj, NULL, "port_msi");
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fpgai2c_process(struct fpgalogic_i2c *i2c)
|
static void fpgai2c_process(struct fpgalogic_i2c *i2c)
|
||||||
{
|
{
|
||||||
struct i2c_msg *msg = i2c->msg;
|
struct i2c_msg *msg = i2c->msg;
|
||||||
@ -806,12 +730,12 @@ static int fpgai2c_init(struct fpgalogic_i2c *i2c)
|
|||||||
fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8);
|
fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8);
|
||||||
|
|
||||||
/* Init the device */
|
/* Init the device */
|
||||||
fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK);
|
|
||||||
if (!use_irq)
|
if (!use_irq)
|
||||||
fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN);
|
fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN);
|
||||||
else
|
else
|
||||||
fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN);
|
fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN);
|
||||||
|
|
||||||
|
fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK);
|
||||||
fpgai2c_dump(i2c);
|
fpgai2c_dump(i2c);
|
||||||
|
|
||||||
/* Initialize interrupt handlers if not already done */
|
/* Initialize interrupt handlers if not already done */
|
||||||
@ -906,7 +830,8 @@ static int i2c_pci_init (void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk("Wrong board_rev_type 0x%x\n", board_rev_type);
|
printk("unknown board_rev_type 0x%x\n", board_rev_type);
|
||||||
|
num_bus = I2C_PCI_BUS_NUM_8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,20 +1031,6 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id)
|
|||||||
* alternatively function will be called from free_irq as well
|
* alternatively function will be called from free_irq as well
|
||||||
* with flag IRQF_SHARED */
|
* with flag IRQF_SHARED */
|
||||||
switch(irq_num_id) {
|
switch(irq_num_id) {
|
||||||
/* Currently we only support test vector 2 for FPGA Logic I2C channel
|
|
||||||
* controller 1-7 interrupt*/
|
|
||||||
case FPGA_MSI_VECTOR_ID_4:
|
|
||||||
err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME,
|
|
||||||
FPGA_PCI_NAME, dev);
|
|
||||||
PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id);
|
|
||||||
fpgapci->irq_assigned++;
|
|
||||||
break;
|
|
||||||
case FPGA_MSI_VECTOR_ID_5:
|
|
||||||
err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME,
|
|
||||||
FPGA_PCI_NAME, dev);
|
|
||||||
PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id);
|
|
||||||
fpgapci->irq_assigned++;
|
|
||||||
break;
|
|
||||||
case FPGA_MSI_VECTOR_ID_8:
|
case FPGA_MSI_VECTOR_ID_8:
|
||||||
err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME,
|
err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME,
|
||||||
FPGA_PCI_NAME, &fpgalogic_i2c[0]);
|
FPGA_PCI_NAME, &fpgalogic_i2c[0]);
|
||||||
@ -1166,18 +1077,6 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id)
|
|||||||
((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) {
|
((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) {
|
||||||
/* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */
|
/* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */
|
||||||
switch (irq_num_id) {
|
switch (irq_num_id) {
|
||||||
case FPGA_MSI_VECTOR_ID_4:
|
|
||||||
err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME,
|
|
||||||
FPGA_PCI_NAME, dev);
|
|
||||||
PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id);
|
|
||||||
fpgapci->irq_assigned++;
|
|
||||||
break;
|
|
||||||
case FPGA_MSI_VECTOR_ID_5:
|
|
||||||
err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME,
|
|
||||||
FPGA_PCI_NAME, dev);
|
|
||||||
PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id);
|
|
||||||
fpgapci->irq_assigned++;
|
|
||||||
break;
|
|
||||||
case FPGA_MSI_VECTOR_ID_8:
|
case FPGA_MSI_VECTOR_ID_8:
|
||||||
err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME,
|
err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME,
|
||||||
FPGA_PCI_NAME, &fpgalogic_i2c[0]);
|
FPGA_PCI_NAME, &fpgalogic_i2c[0]);
|
||||||
@ -1491,7 +1390,6 @@ error_no_msi:
|
|||||||
static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
struct fpgapci_dev *fpgapci = 0;
|
struct fpgapci_dev *fpgapci = 0;
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n",
|
PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n",
|
||||||
@ -1508,10 +1406,6 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||||||
fpgapci->pci_dev = dev;
|
fpgapci->pci_dev = dev;
|
||||||
dev_set_drvdata(&dev->dev, (void*)fpgapci);
|
dev_set_drvdata(&dev->dev, (void*)fpgapci);
|
||||||
|
|
||||||
status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp);
|
|
||||||
if (status) {
|
|
||||||
printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
fpgapci->upstream = find_upstream_dev (dev);
|
fpgapci->upstream = find_upstream_dev (dev);
|
||||||
|
|
||||||
@ -1519,7 +1413,9 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||||||
goto error_no_device;
|
goto error_no_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printk("%s:MSI-irq disabled \n", __FUNCTION__);
|
||||||
if (use_irq) {
|
if (use_irq) {
|
||||||
|
printk("%s:MSI-irq enabled\n", __FUNCTION__);
|
||||||
if(fpgapci_configure_msi(fpgapci,dev)) {
|
if(fpgapci_configure_msi(fpgapci,dev)) {
|
||||||
goto error_cannot_configure;
|
goto error_cannot_configure;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
|
|
||||||
S5232F_MAX_FAN_TRAYS = 4
|
S5232F_MAX_FAN_TRAYS = 4
|
||||||
S5232F_MAX_PSUS = 2
|
S5232F_MAX_PSUS = 2
|
||||||
@ -85,7 +84,7 @@ def get_psu_airflow(psu_id):
|
|||||||
if line.startswith('FRU Device Description') and fru_id in line.split(':')[1]:
|
if line.startswith('FRU Device Description') and fru_id in line.split(':')[1]:
|
||||||
found_fru = True
|
found_fru = True
|
||||||
if found_fru and line.startswith(' Board Product '):
|
if found_fru and line.startswith(' Board Product '):
|
||||||
return ' B2F' if 'PS/IO' in line else ' F2B'
|
return 'Intake' if 'PS/IO' in line else 'Exhaust'
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
# Fetch FRU on given offset
|
# Fetch FRU on given offset
|
||||||
@ -98,7 +97,7 @@ def fetch_raw_fru(dev_id, offset):
|
|||||||
|
|
||||||
|
|
||||||
def get_fan_airflow(fan_id):
|
def get_fan_airflow(fan_id):
|
||||||
Airflow_Direction = [' F2B', ' B2F']
|
Airflow_Direction = ['Exhaust', 'Intake']
|
||||||
return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)]
|
return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)]
|
||||||
|
|
||||||
# Print the information for temperature sensors
|
# Print the information for temperature sensors
|
||||||
@ -119,6 +118,7 @@ def print_temperature_sensors():
|
|||||||
print(' CPU Temp: ',
|
print(' CPU Temp: ',
|
||||||
get_pmc_register('CPU_temp'))
|
get_pmc_register('CPU_temp'))
|
||||||
|
|
||||||
|
subprocess.getstatusoutput('echo 0 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us')
|
||||||
ipmi_sensor_dump()
|
ipmi_sensor_dump()
|
||||||
|
|
||||||
print_temperature_sensors()
|
print_temperature_sensors()
|
||||||
@ -329,3 +329,5 @@ for psu in range(1, S5232F_MAX_PSUS + 1):
|
|||||||
|
|
||||||
print('\n Total Power: ',
|
print('\n Total Power: ',
|
||||||
get_pmc_register('PSU_Total_watt'))
|
get_pmc_register('PSU_Total_watt'))
|
||||||
|
|
||||||
|
subprocess.getstatusoutput('echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us')
|
||||||
|
@ -145,15 +145,6 @@ platform_firmware_versions() {
|
|||||||
r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'`
|
r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'`
|
||||||
echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE
|
echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE
|
||||||
|
|
||||||
#Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1)
|
|
||||||
r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'`
|
|
||||||
r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'`
|
|
||||||
echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE
|
|
||||||
|
|
||||||
#Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1)
|
|
||||||
r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'`
|
|
||||||
r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'`
|
|
||||||
echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
install_python_api_package() {
|
install_python_api_package() {
|
||||||
@ -176,16 +167,47 @@ remove_python_api_package() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_reboot_cause() {
|
||||||
|
REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason"
|
||||||
|
resource="/sys/bus/pci/devices/0000:04:00.0/resource0"
|
||||||
|
|
||||||
|
mkdir -p $(dirname $REBOOT_REASON_FILE)
|
||||||
|
|
||||||
|
# Handle First Boot into software version with reboot cause determination support
|
||||||
|
if [[ ! -e $REBOOT_REASON_FILE ]]; then
|
||||||
|
echo "0" > $REBOOT_REASON_FILE
|
||||||
|
else
|
||||||
|
/usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE
|
||||||
|
fi
|
||||||
|
/usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource
|
||||||
|
}
|
||||||
|
|
||||||
|
get_reboot_cause() {
|
||||||
|
REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason"
|
||||||
|
resource="/sys/bus/pci/devices/0000:04:00.0/resource0"
|
||||||
|
|
||||||
|
mkdir -p $(dirname $REBOOT_REASON_FILE)
|
||||||
|
|
||||||
|
# Handle First Boot into software version with reboot cause determination support
|
||||||
|
if [[ ! -e $REBOOT_REASON_FILE ]]; then
|
||||||
|
echo "0" > $REBOOT_REASON_FILE
|
||||||
|
else
|
||||||
|
/usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE
|
||||||
|
fi
|
||||||
|
/usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource
|
||||||
|
}
|
||||||
|
|
||||||
init_devnum
|
init_devnum
|
||||||
|
|
||||||
if [ "$1" == "init" ]; then
|
if [ "$1" == "init" ]; then
|
||||||
modprobe i2c-dev
|
modprobe i2c-dev
|
||||||
modprobe i2c-mux-pca954x force_deselect_on_exit=1
|
modprobe i2c-mux-pca954x force_deselect_on_exit=1
|
||||||
modprobe ipmi_devintf
|
modprobe ipmi_devintf
|
||||||
modprobe ipmi_si
|
modprobe ipmi_si kipmid_max_busy_us=1000
|
||||||
modprobe i2c_ocores
|
modprobe i2c_ocores
|
||||||
modprobe dell_s5232f_fpga_ocores
|
modprobe dell_s5232f_fpga_ocores
|
||||||
sys_eeprom "new_device"
|
sys_eeprom "new_device"
|
||||||
|
get_reboot_cause
|
||||||
switch_board_qsfp_mux "new_device"
|
switch_board_qsfp_mux "new_device"
|
||||||
switch_board_qsfp "new_device"
|
switch_board_qsfp "new_device"
|
||||||
switch_board_sfp "new_device"
|
switch_board_sfp "new_device"
|
||||||
@ -194,6 +216,7 @@ if [ "$1" == "init" ]; then
|
|||||||
install_python_api_package
|
install_python_api_package
|
||||||
/usr/bin/qsfp_irq_enable.py
|
/usr/bin/qsfp_irq_enable.py
|
||||||
platform_firmware_versions
|
platform_firmware_versions
|
||||||
|
echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us
|
||||||
|
|
||||||
elif [ "$1" == "deinit" ]; then
|
elif [ "$1" == "deinit" ]; then
|
||||||
sys_eeprom "delete_device"
|
sys_eeprom "delete_device"
|
||||||
@ -203,6 +226,8 @@ elif [ "$1" == "deinit" ]; then
|
|||||||
modprobe -r i2c-mux-pca954x
|
modprobe -r i2c-mux-pca954x
|
||||||
modprobe -r i2c-dev
|
modprobe -r i2c-dev
|
||||||
remove_python_api_package
|
remove_python_api_package
|
||||||
|
modprobe -r ipmi_devintf
|
||||||
|
modprobe -r ipmi_si
|
||||||
else
|
else
|
||||||
echo "s5232f_platform : Invalid option !"
|
echo "s5232f_platform : Invalid option !"
|
||||||
fi
|
fi
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer"]
|
||||||
|
from sonic_platform import *
|
||||||
|
@ -12,18 +12,19 @@ from __future__ import division
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
from sonic_platform_base.chassis_base import ChassisBase
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
from sonic_platform.sfp import Sfp
|
from sonic_platform.sfp import Sfp
|
||||||
from sonic_platform.eeprom import Eeprom
|
from sonic_platform.eeprom import Eeprom
|
||||||
from sonic_platform.component import Component
|
from sonic_platform.component import Component
|
||||||
from sonic_platform.psu import Psu
|
from sonic_platform.psu import Psu
|
||||||
from sonic_platform.thermal import Thermal
|
from sonic_platform.thermal import Thermal
|
||||||
|
from sonic_platform.fan_drawer import FanDrawer
|
||||||
from sonic_platform.watchdog import Watchdog
|
from sonic_platform.watchdog import Watchdog
|
||||||
from sonic_platform.fan import Fan
|
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs
|
MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,2 SLAVE CPLDs
|
||||||
MAX_S5232F_FANTRAY =4
|
MAX_S5232F_FANTRAY =4
|
||||||
MAX_S5232F_FAN = 2
|
MAX_S5232F_FAN = 2
|
||||||
MAX_S5232F_PSU = 2
|
MAX_S5232F_PSU = 2
|
||||||
@ -61,17 +62,20 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
self._eeprom = Eeprom()
|
self._eeprom = Eeprom()
|
||||||
self._watchdog = Watchdog()
|
self._watchdog = Watchdog()
|
||||||
|
for i in range(MAX_S5232F_FANTRAY):
|
||||||
|
fandrawer = FanDrawer(i)
|
||||||
|
self._fan_drawer_list.append(fandrawer)
|
||||||
|
self._fan_list.extend(fandrawer._fan_list)
|
||||||
|
|
||||||
self._num_sfps = self.PORT_END
|
self._num_sfps = self.PORT_END
|
||||||
self._num_fans = MAX_S5232F_FANTRAY * MAX_S5232F_FAN
|
self._num_fans = MAX_S5232F_FANTRAY * MAX_S5232F_FAN
|
||||||
self._fan_list = [Fan(i, j) for i in range(MAX_S5232F_FANTRAY) \
|
|
||||||
for j in range(MAX_S5232F_FAN)]
|
|
||||||
self._psu_list = [Psu(i) for i in range(MAX_S5232F_PSU)]
|
self._psu_list = [Psu(i) for i in range(MAX_S5232F_PSU)]
|
||||||
self._thermal_list = [Thermal(i) for i in range(MAX_S5232F_THERMAL)]
|
self._thermal_list = [Thermal(i) for i in range(MAX_S5232F_THERMAL)]
|
||||||
self._component_list = [Component(i) for i in range(MAX_S5232F_COMPONENT)]
|
self._component_list = [Component(i) for i in range(MAX_S5232F_COMPONENT)]
|
||||||
|
|
||||||
for port_num in range(self.PORT_START, self.PORTS_IN_BLOCK):
|
for port_num in range(self.PORT_START, self.PORTS_IN_BLOCK):
|
||||||
# sfp get uses zero-indexing, but port numbers start from 1
|
# sfp get uses zero-indexing, but port numbers start from 1
|
||||||
presence = self.get_sfp(port_num).get_presence()
|
presence = self.get_sfp(port_num-1).get_presence()
|
||||||
self._global_port_pres_dict[port_num] = '1' if presence else '0'
|
self._global_port_pres_dict[port_num] = '1' if presence else '0'
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
@ -88,33 +92,30 @@ class Chassis(ChassisBase):
|
|||||||
Returns a nested dictionary containing all devices which have
|
Returns a nested dictionary containing all devices which have
|
||||||
experienced a change at chassis level
|
experienced a change at chassis level
|
||||||
"""
|
"""
|
||||||
|
start_ms = time.time() * 1000
|
||||||
port_dict = {}
|
port_dict = {}
|
||||||
change_dict = {}
|
change_dict = {}
|
||||||
change_dict['sfp'] = port_dict
|
change_dict['sfp'] = port_dict
|
||||||
elapsed_time_ms = 0
|
|
||||||
sleep_time_ms = 500
|
|
||||||
sleep_time = sleep_time_ms / 1000
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
time.sleep(0.5)
|
||||||
for port_num in range(self.PORT_START, (self.PORT_END + 1)):
|
for port_num in range(self.PORT_START, (self.PORT_END + 1)):
|
||||||
presence = self.get_sfp(port_num).get_presence()
|
presence = self.get_sfp(port_num-1).get_presence()
|
||||||
if(presence and self._global_port_pres_dict[port_num] == '0'):
|
if(presence and self._global_port_pres_dict[port_num] == '0'):
|
||||||
self._global_port_pres_dict[port_num] = '1'
|
self._global_port_pres_dict[port_num] = '1'
|
||||||
port_dict[port_num] = '1'
|
port_dict[port_num] = '1'
|
||||||
elif(not presence and
|
elif(not presence and
|
||||||
self._global_port_pres_dict[port_num] == '1'):
|
self._global_port_pres_dict[port_num] == '1'):
|
||||||
self._global_port_pres_dict[port_num] = '0'
|
self._global_port_pres_dict[port_num] = '0'
|
||||||
port_dict[port_num] = '0'
|
port_dict[port_num] = '0'
|
||||||
|
|
||||||
if(len(port_dict) > 0):
|
if(len(port_dict) > 0):
|
||||||
return True, change_dict
|
return True, change_dict
|
||||||
if timeout != 0:
|
|
||||||
elapsed_time_ms += sleep_time_ms
|
if timeout:
|
||||||
if elapsed_time_ms > timeout:
|
now_ms = time.time() * 1000
|
||||||
break
|
if (now_ms - start_ms >= timeout):
|
||||||
|
return True, change_dict
|
||||||
|
|
||||||
sleep(sleep_time)
|
|
||||||
return True, change_dict
|
|
||||||
|
|
||||||
def get_sfp(self, index):
|
def get_sfp(self, index):
|
||||||
"""
|
"""
|
||||||
@ -133,7 +134,7 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# The index will start from 0
|
# The index will start from 0
|
||||||
sfp = self._sfp_list[index-1]
|
sfp = self._sfp_list[index]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
sys.stderr.write("SFP index {} out of range (0-{})\n".format(
|
sys.stderr.write("SFP index {} out of range (0-{})\n".format(
|
||||||
index, len(self._sfp_list)-1))
|
index, len(self._sfp_list)-1))
|
||||||
@ -222,3 +223,40 @@ class Chassis(ChassisBase):
|
|||||||
An integer represences the number of SFPs on the chassis.
|
An integer represences the number of SFPs on the chassis.
|
||||||
"""
|
"""
|
||||||
return self._num_sfps
|
return self._num_sfps
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(self.REBOOT_CAUSE_PATH) as fd:
|
||||||
|
reboot_cause = int(fd.read(), 16)
|
||||||
|
except EnvironmentError:
|
||||||
|
return (self.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
|
||||||
|
if reboot_cause & 0x1:
|
||||||
|
return (self.REBOOT_CAUSE_POWER_LOSS, None)
|
||||||
|
elif reboot_cause & 0x2:
|
||||||
|
return (self.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
elif reboot_cause & 0x4:
|
||||||
|
return (self.REBOOT_CAUSE_HARDWARE_OTHER, "PSU Shutdown")
|
||||||
|
elif reboot_cause & 0x8:
|
||||||
|
return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None)
|
||||||
|
elif reboot_cause & 0x10:
|
||||||
|
return (self.REBOOT_CAUSE_WATCHDOG, None)
|
||||||
|
elif reboot_cause & 0x20:
|
||||||
|
return (self.REBOOT_CAUSE_HARDWARE_OTHER, "BMC Shutdown")
|
||||||
|
elif reboot_cause & 0x40:
|
||||||
|
return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Hot-Swap Shutdown")
|
||||||
|
elif reboot_cause & 0x80:
|
||||||
|
return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Shutdown")
|
||||||
|
elif reboot_cause & 0x100:
|
||||||
|
return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Cold Reboot")
|
||||||
|
else:
|
||||||
|
return (self.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class Component(ComponentBase):
|
|||||||
['Slave CPLD 2',
|
['Slave CPLD 2',
|
||||||
'Used for managing SFP28/QSFP28 port transceivers (SFP28 25-48, QSFP28 5-8)',
|
'Used for managing SFP28/QSFP28 port transceivers (SFP28 25-48, QSFP28 5-8)',
|
||||||
get_cpld2_version
|
get_cpld2_version
|
||||||
],
|
]
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -52,12 +52,7 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
+ ord(eeprom[tlv_index + 1])]
|
+ ord(eeprom[tlv_index + 1])]
|
||||||
code = "0x%02X" % (ord(tlv[0]))
|
code = "0x%02X" % (ord(tlv[0]))
|
||||||
|
|
||||||
if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT:
|
name, value = self.decoder(None, tlv)
|
||||||
value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) |
|
|
||||||
(ord(tlv[4]) << 8) | ord(tlv[5]))
|
|
||||||
value += str(tlv[6:6 + ord(tlv[1])])
|
|
||||||
else:
|
|
||||||
name, value = self.decoder(None, tlv)
|
|
||||||
|
|
||||||
self.eeprom_tlv_dict[code] = value
|
self.eeprom_tlv_dict[code] = value
|
||||||
if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32:
|
if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32:
|
||||||
|
@ -24,16 +24,16 @@ PSU_FAN_DIRECTION_OFFSET = 47
|
|||||||
class Fan(FanBase):
|
class Fan(FanBase):
|
||||||
"""DellEMC Platform-specific Fan class"""
|
"""DellEMC Platform-specific Fan class"""
|
||||||
# { FAN-ID: { Sensor-Name: Sensor-ID } }
|
# { FAN-ID: { Sensor-Name: Sensor-ID } }
|
||||||
FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x51, "State": 0x64, "Speed": 0x24},
|
FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x53, "State": 0x57, "Speed": 0x24},
|
||||||
2: {"Prsnt": 0x51, "State": 0x60, "Speed": 0x20},
|
2: {"Prsnt": 0x53, "State": 0x5b, "Speed": 0x20},
|
||||||
3: {"Prsnt": 0x52, "State": 0x65, "Speed": 0x25},
|
3: {"Prsnt": 0x54, "State": 0x58, "Speed": 0x25},
|
||||||
4: {"Prsnt": 0x52, "State": 0x61, "Speed": 0x21},
|
4: {"Prsnt": 0x54, "State": 0x5c, "Speed": 0x21},
|
||||||
5: {"Prsnt": 0x53, "State": 0x66, "Speed": 0x26},
|
5: {"Prsnt": 0x55, "State": 0x59, "Speed": 0x26},
|
||||||
6: {"Prsnt": 0x53, "State": 0x62, "Speed": 0x22},
|
6: {"Prsnt": 0x55, "State": 0x5d, "Speed": 0x22},
|
||||||
7: {"Prsnt": 0x54, "State": 0x67, "Speed": 0x27},
|
7: {"Prsnt": 0x56, "State": 0x5a, "Speed": 0x27},
|
||||||
8: {"Prsnt": 0x54, "State": 0x63, "Speed": 0x23} }
|
8: {"Prsnt": 0x56, "State": 0x5e, "Speed": 0x23} }
|
||||||
PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x46, "Speed": 0x2e},
|
PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x31, "Speed": 0x28},
|
||||||
2: {"State": 0x47, "Speed": 0x2f} }
|
2: {"State": 0x32, "Speed": 0x29} }
|
||||||
|
|
||||||
# { FANTRAY-ID: FRU-ID }
|
# { FANTRAY-ID: FRU-ID }
|
||||||
FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 }
|
FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 }
|
||||||
@ -129,7 +129,7 @@ class Fan(FanBase):
|
|||||||
status = False
|
status = False
|
||||||
is_valid, state = self.state_sensor.get_reading()
|
is_valid, state = self.state_sensor.get_reading()
|
||||||
if is_valid:
|
if is_valid:
|
||||||
if (state == 0x00):
|
if not state > 1:
|
||||||
status = True
|
status = True
|
||||||
return status
|
return status
|
||||||
|
|
||||||
@ -146,11 +146,11 @@ class Fan(FanBase):
|
|||||||
- Reverse/Intake : Air flows from Fan side to Port side.
|
- Reverse/Intake : Air flows from Fan side to Port side.
|
||||||
"""
|
"""
|
||||||
direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE]
|
direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE]
|
||||||
fan_status = self.get_status()
|
fan_status = self.get_presence()
|
||||||
if not fan_status:
|
if not fan_status:
|
||||||
return 'NA'
|
return 'NA'
|
||||||
is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset)
|
is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset)
|
||||||
if is_valid:
|
if is_valid and fan_direction[0] < len(direction):
|
||||||
return direction[fan_direction[0]]
|
return direction[fan_direction[0]]
|
||||||
else:
|
else:
|
||||||
return 'NA'
|
return 'NA'
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# DellEMC S5232F
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the Fan-Drawers' information available in the platform.
|
||||||
|
#
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_platform_base.fan_drawer_base import FanDrawerBase
|
||||||
|
from sonic_platform.fan import Fan
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
S5232F_FANS_PER_FANTRAY = 2
|
||||||
|
|
||||||
|
|
||||||
|
class FanDrawer(FanDrawerBase):
|
||||||
|
"""DellEMC Platform-specific Fan class"""
|
||||||
|
|
||||||
|
def __init__(self, fantray_index):
|
||||||
|
|
||||||
|
FanDrawerBase.__init__(self)
|
||||||
|
# FanTray is 1-based in DellEMC platforms
|
||||||
|
self.fantrayindex = fantray_index + 1
|
||||||
|
for i in range(S5232F_FANS_PER_FANTRAY):
|
||||||
|
self._fan_list.append(Fan(fantray_index, i))
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the fan drawer name
|
||||||
|
Returns:
|
||||||
|
string: The name of the device
|
||||||
|
"""
|
||||||
|
return "FanTray{}".format(self.fantrayindex)
|
@ -105,7 +105,7 @@ class Thermal(ThermalBase):
|
|||||||
Celsius up to nearest thousandth of one degree Celsius,
|
Celsius up to nearest thousandth of one degree Celsius,
|
||||||
e.g. 30.125
|
e.g. 30.125
|
||||||
"""
|
"""
|
||||||
is_valid, high_threshold = self.sensor.get_threshold("UpperNonRecoverable")
|
is_valid, high_threshold = self.sensor.get_threshold("UpperCritical")
|
||||||
if not is_valid:
|
if not is_valid:
|
||||||
high_threshold = 0
|
high_threshold = 0
|
||||||
|
|
||||||
@ -126,6 +126,21 @@ class Thermal(ThermalBase):
|
|||||||
|
|
||||||
return float(low_threshold)
|
return float(low_threshold)
|
||||||
|
|
||||||
|
def get_high_critical_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the high critical threshold temperature of thermal
|
||||||
|
Returns:
|
||||||
|
A float number, the high critical threshold temperature of
|
||||||
|
thermal in Celsius up to nearest thousandth of one degree
|
||||||
|
Celsius, e.g. 30.125
|
||||||
|
"""
|
||||||
|
is_valid, high_crit_threshold = self.sensor.get_threshold("UpperNonRecoverable")
|
||||||
|
if not is_valid:
|
||||||
|
high_crit_threshold = 0
|
||||||
|
|
||||||
|
return float(high_crit_threshold)
|
||||||
|
|
||||||
|
|
||||||
def set_high_threshold(self, temperature):
|
def set_high_threshold(self, temperature):
|
||||||
"""
|
"""
|
||||||
Sets the high threshold temperature of thermal
|
Sets the high threshold temperature of thermal
|
||||||
|
Loading…
Reference in New Issue
Block a user