[devices]: Add GPIO interrupt enable for Z9100/S6100 and transceiver-plug-inout-event for Z9100 (#2025)
This commit is contained in:
parent
22edc33896
commit
c4154eb9a9
@ -4,7 +4,10 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
|
import select
|
||||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError("%s - required module not found" % str(e))
|
raise ImportError("%s - required module not found" % str(e))
|
||||||
@ -337,3 +340,70 @@ class SfpUtil(SfpUtilBase):
|
|||||||
reg_file.close()
|
reg_file.close()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_register(self, reg_file):
|
||||||
|
retval = 'ERR'
|
||||||
|
|
||||||
|
if (not os.path.isfile(reg_file)):
|
||||||
|
print reg_file, 'not found !'
|
||||||
|
return retval
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(reg_file, 'r') as fd:
|
||||||
|
retval = fd.read()
|
||||||
|
except Exception as error:
|
||||||
|
logging.error("Unable to open ", reg_file, "file !")
|
||||||
|
|
||||||
|
retval = retval.rstrip('\r\n')
|
||||||
|
retval = retval.lstrip(" ")
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def get_transceiver_change_event(self, timeout=0):
|
||||||
|
epoll = select.epoll()
|
||||||
|
port_dict = {}
|
||||||
|
try:
|
||||||
|
# We get notified when there is an SCI interrupt from GPIO SUS6
|
||||||
|
fd = open("/sys/devices/platform/dell_ich.0/sci_int_gpio_sus6", "r")
|
||||||
|
epoll.register(fd.fileno(), select.EPOLLIN)
|
||||||
|
events = epoll.poll(timeout=timeout if timeout != 0 else -1)
|
||||||
|
if events:
|
||||||
|
# Read the QSFP ABS interrupt & status registers
|
||||||
|
cpld2_abs_int = self.get_register("/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int")
|
||||||
|
cpld2_abs_sta = self.get_register("/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta")
|
||||||
|
cpld3_abs_int = self.get_register("/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int")
|
||||||
|
cpld3_abs_sta = self.get_register("/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta")
|
||||||
|
cpld4_abs_int = self.get_register("/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int")
|
||||||
|
cpld4_abs_sta = self.get_register("/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta")
|
||||||
|
|
||||||
|
if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or \
|
||||||
|
cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or \
|
||||||
|
cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR' ):
|
||||||
|
return False, {}
|
||||||
|
|
||||||
|
cpld2_abs_int = int(cpld2_abs_int, 16)
|
||||||
|
cpld2_abs_sta = int(cpld2_abs_sta, 16)
|
||||||
|
cpld3_abs_int = int(cpld3_abs_int, 16)
|
||||||
|
cpld3_abs_sta = int(cpld3_abs_sta, 16)
|
||||||
|
cpld4_abs_int = int(cpld4_abs_int, 16)
|
||||||
|
cpld4_abs_sta = int(cpld4_abs_sta, 16)
|
||||||
|
|
||||||
|
# Make it contiguous (discard reserved bits)
|
||||||
|
interrupt_reg = (cpld2_abs_int & 0xfff) | ((cpld3_abs_int & 0x3ff) << 12) | ((cpld4_abs_int & 0x3ff) << 22)
|
||||||
|
status_reg = (cpld2_abs_sta & 0xfff) | ((cpld3_abs_sta & 0x3ff) << 12) | ((cpld4_abs_sta & 0x3ff) << 22)
|
||||||
|
|
||||||
|
port=self.port_start
|
||||||
|
while port <= self.port_end:
|
||||||
|
if interrupt_reg & (1<<port)):
|
||||||
|
if status_reg & (1<<port)):
|
||||||
|
# status reg 1 => optics is removed
|
||||||
|
port_dict[port] = '0'
|
||||||
|
else:
|
||||||
|
# status reg 0 => optics is inserted
|
||||||
|
port_dict[port] = '1'
|
||||||
|
port += 1
|
||||||
|
return True, port_dict
|
||||||
|
finally:
|
||||||
|
fd.close()
|
||||||
|
epoll.close()
|
||||||
|
|
||||||
|
return False, {}
|
||||||
|
1042
platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c
Normal file
1042
platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,9 +14,11 @@ COMMON_DIR := common
|
|||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
(for mod in $(MODULE_DIRS); do \
|
(for mod in $(MODULE_DIRS); do \
|
||||||
if [ $$mod = "s6100" ]; then \
|
if [ $$mod = "s6100" ]; then \
|
||||||
cp $(COMMON_DIR)/*.c $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \
|
cp $(COMMON_DIR)/dell_pmc.c $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \
|
||||||
|
cp $(COMMON_DIR)/dell_ich.c $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \
|
||||||
elif [ $$mod = "z9100" ]; then \
|
elif [ $$mod = "z9100" ]; then \
|
||||||
cp $(COMMON_DIR)/*.c $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \
|
cp $(COMMON_DIR)/dell_pmc.c $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \
|
||||||
|
cp $(COMMON_DIR)/dell_ich.c $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \
|
||||||
fi; \
|
fi; \
|
||||||
echo "making man page alias $$mod -> $$mod APIs";\
|
echo "making man page alias $$mod -> $$mod APIs";\
|
||||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
||||||
@ -37,8 +39,10 @@ override_dh_clean:
|
|||||||
(for mod in $(MODULE_DIRS); do \
|
(for mod in $(MODULE_DIRS); do \
|
||||||
if [ $$mod = "s6100" ]; then \
|
if [ $$mod = "s6100" ]; then \
|
||||||
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \
|
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \
|
||||||
|
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \
|
||||||
elif [ $$mod = "z9100" ]; then \
|
elif [ $$mod = "z9100" ]; then \
|
||||||
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \
|
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \
|
||||||
|
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \
|
||||||
fi; \
|
fi; \
|
||||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
|
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
|
||||||
done)
|
done)
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
obj-m := dell_s6100_iom_cpld.o dell_s6100_lpc.o
|
obj-m := dell_s6100_iom_cpld.o dell_s6100_lpc.o dell_ich.o
|
||||||
|
|
||||||
|
@ -26,6 +26,21 @@
|
|||||||
#define QSFP_MOD_PRS_REG0 0x16
|
#define QSFP_MOD_PRS_REG0 0x16
|
||||||
#define QSFP_MOD_PRS_REG1 0x17
|
#define QSFP_MOD_PRS_REG1 0x17
|
||||||
|
|
||||||
|
//qsfp interrupt registers
|
||||||
|
#define QSFP_INT_STA_REG0 0x14
|
||||||
|
#define QSFP_INT_STA_REG1 0x15
|
||||||
|
#define QSFP_ABS_STA_REG0 0x16
|
||||||
|
#define QSFP_ABS_STA_REG1 0x17
|
||||||
|
#define QSFP_TRIG_MOD 0x20
|
||||||
|
#define QSFP_INT_COMBINE 0x21
|
||||||
|
#define QSFP_INT0 0x22
|
||||||
|
#define QSFP_INT1 0x23
|
||||||
|
#define QSFP_ABS_INT0 0x24
|
||||||
|
#define QSFP_ABS_INT1 0x25
|
||||||
|
#define QSFP_INT_MASK0 0x26
|
||||||
|
#define QSFP_INT_MASK1 0x27
|
||||||
|
#define QSFP_ABS_MASK0 0x28
|
||||||
|
#define QSFP_ABS_MASK1 0x29
|
||||||
|
|
||||||
struct cpld_data {
|
struct cpld_data {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
@ -182,16 +197,219 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int_sta(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_STA_REG0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_STA_REG1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_abs_sta(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_STA_REG0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_STA_REG1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_trig_mod(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_TRIG_MOD);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u8)ret & 0xff;
|
||||||
|
return sprintf(buf,"0x%02x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t set_trig_mod(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long devdata;
|
||||||
|
int err;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtoul(buf, 16, &devdata);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_TRIG_MOD,(u8)(devdata & 0xff));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int_combine(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_COMBINE);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u8)ret & 0xff;
|
||||||
|
return sprintf(buf,"0x%02x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_abs_int(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_INT0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_INT1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int_mask(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_MASK0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_MASK1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t set_int_mask(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long devdata;
|
||||||
|
int err;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtoul(buf, 16, &devdata);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_MASK0,(u8)(devdata & 0xff));
|
||||||
|
dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_INT_MASK1,(u8)((devdata >> 8) & 0xff));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_abs_mask(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_MASK0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_MASK1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t set_abs_mask(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long devdata;
|
||||||
|
int err;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtoul(buf, 16, &devdata);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_MASK0,(u8)(devdata & 0xff));
|
||||||
|
dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_ABS_MASK1,(u8)((devdata >> 8) & 0xff));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL);
|
static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL);
|
||||||
static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL);
|
static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL);
|
||||||
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode);
|
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode);
|
||||||
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset);
|
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset);
|
||||||
|
static DEVICE_ATTR(qsfp_int_sta, S_IRUGO, get_int_sta, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_abs_sta, S_IRUGO, get_abs_sta, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_trig_mod, S_IRUGO | S_IWUSR, get_trig_mod, set_trig_mod);
|
||||||
|
static DEVICE_ATTR(qsfp_int_combine, S_IRUGO, get_int_combine, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_int, S_IRUGO, get_int, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_abs_int, S_IRUGO, get_abs_int, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_int_mask, S_IRUGO | S_IWUSR, get_int_mask, set_int_mask);
|
||||||
|
static DEVICE_ATTR(qsfp_abs_mask, S_IRUGO | S_IWUSR, get_abs_mask, set_abs_mask);
|
||||||
|
|
||||||
static struct attribute *i2c_cpld_attrs[] = {
|
static struct attribute *i2c_cpld_attrs[] = {
|
||||||
&dev_attr_qsfp_lpmode.attr,
|
&dev_attr_qsfp_lpmode.attr,
|
||||||
&dev_attr_qsfp_reset.attr,
|
&dev_attr_qsfp_reset.attr,
|
||||||
&dev_attr_qsfp_modprs.attr,
|
&dev_attr_qsfp_modprs.attr,
|
||||||
&dev_attr_iom_cpld_vers.attr,
|
&dev_attr_iom_cpld_vers.attr,
|
||||||
|
&dev_attr_qsfp_int_sta.attr,
|
||||||
|
&dev_attr_qsfp_abs_sta.attr,
|
||||||
|
&dev_attr_qsfp_trig_mod.attr,
|
||||||
|
&dev_attr_qsfp_int_combine.attr,
|
||||||
|
&dev_attr_qsfp_int.attr,
|
||||||
|
&dev_attr_qsfp_abs_int.attr,
|
||||||
|
&dev_attr_qsfp_int_mask.attr,
|
||||||
|
&dev_attr_qsfp_abs_mask.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,11 +171,32 @@ switch_board_qsfp_lpmode() {
|
|||||||
echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode
|
echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Enable/Disable xcvr presence interrupts
|
||||||
|
xcvr_presence_interrupts() {
|
||||||
|
case $1 in
|
||||||
|
"enable")
|
||||||
|
for ((i=14;i<=17;i++));
|
||||||
|
do
|
||||||
|
echo 0x0 > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"disable")
|
||||||
|
for ((i=14;i<=17;i++));
|
||||||
|
do
|
||||||
|
echo 0xffff > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
*) echo "s6100_platform: xcvr_presence_interrupts: invalid command !"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
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 dell_ich
|
||||||
modprobe dell_s6100_iom_cpld
|
modprobe dell_s6100_iom_cpld
|
||||||
modprobe dell_s6100_lpc
|
modprobe dell_s6100_lpc
|
||||||
|
|
||||||
@ -187,7 +208,9 @@ if [[ "$1" == "init" ]]; then
|
|||||||
switch_board_sfp "new_device"
|
switch_board_sfp "new_device"
|
||||||
switch_board_qsfp "new_device"
|
switch_board_qsfp "new_device"
|
||||||
switch_board_qsfp_lpmode "disable"
|
switch_board_qsfp_lpmode "disable"
|
||||||
|
xcvr_presence_interrupts "enable"
|
||||||
elif [[ "$1" == "deinit" ]]; then
|
elif [[ "$1" == "deinit" ]]; then
|
||||||
|
xcvr_presence_interrupts "disable"
|
||||||
switch_board_sfp "delete_device"
|
switch_board_sfp "delete_device"
|
||||||
switch_board_cpld "delete_device"
|
switch_board_cpld "delete_device"
|
||||||
switch_board_mux "delete_device"
|
switch_board_mux "delete_device"
|
||||||
@ -200,6 +223,7 @@ elif [[ "$1" == "deinit" ]]; then
|
|||||||
modprobe -r dell_s6100_iom_cpld
|
modprobe -r dell_s6100_iom_cpld
|
||||||
modprobe -r i2c-mux-pca954x
|
modprobe -r i2c-mux-pca954x
|
||||||
modprobe -r i2c-dev
|
modprobe -r i2c-dev
|
||||||
|
modprobe -r dell_ich
|
||||||
else
|
else
|
||||||
echo "s6100_platform : Invalid option !"
|
echo "s6100_platform : Invalid option !"
|
||||||
fi
|
fi
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
obj-m := dell_mailbox.o dell_z9100_cpld.o
|
obj-m := dell_mailbox.o dell_z9100_cpld.o dell_ich.o
|
||||||
|
|
||||||
|
@ -32,6 +32,21 @@
|
|||||||
#define QSFP_MOD_PRS_REG0 0x16
|
#define QSFP_MOD_PRS_REG0 0x16
|
||||||
#define QSFP_MOD_PRS_REG1 0x17
|
#define QSFP_MOD_PRS_REG1 0x17
|
||||||
|
|
||||||
|
//qsfp interrupt registers
|
||||||
|
#define QSFP_INT_STA_REG0 0x14
|
||||||
|
#define QSFP_INT_STA_REG1 0x15
|
||||||
|
#define QSFP_ABS_STA_REG0 0x16
|
||||||
|
#define QSFP_ABS_STA_REG1 0x17
|
||||||
|
#define QSFP_TRIG_MOD 0x20
|
||||||
|
#define QSFP_INT_COMBINE 0x21
|
||||||
|
#define QSFP_INT0 0x22
|
||||||
|
#define QSFP_INT1 0x23
|
||||||
|
#define QSFP_ABS_INT0 0x24
|
||||||
|
#define QSFP_ABS_INT1 0x25
|
||||||
|
#define QSFP_INT_MASK0 0x26
|
||||||
|
#define QSFP_INT_MASK1 0x27
|
||||||
|
#define QSFP_ABS_MASK0 0x28
|
||||||
|
#define QSFP_ABS_MASK1 0x29
|
||||||
|
|
||||||
struct cpld_data {
|
struct cpld_data {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
@ -189,16 +204,219 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int_sta(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT_STA_REG0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT_STA_REG1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_abs_sta(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_ABS_STA_REG0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_ABS_STA_REG1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_trig_mod(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_TRIG_MOD);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u8)ret & 0xff;
|
||||||
|
return sprintf(buf,"0x%02x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t set_trig_mod(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long devdata;
|
||||||
|
int err;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtoul(buf, 16, &devdata);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
dell_z9100_iom_cpld_write(data,QSFP_TRIG_MOD,(u8)(devdata & 0xff));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int_combine(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT_COMBINE);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u8)ret & 0xff;
|
||||||
|
return sprintf(buf,"0x%02x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_abs_int(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_ABS_INT0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_ABS_INT1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_int_mask(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT_MASK0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_INT_MASK1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t set_int_mask(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long devdata;
|
||||||
|
int err;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtoul(buf, 16, &devdata);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
dell_z9100_iom_cpld_write(data,QSFP_INT_MASK0,(u8)(devdata & 0xff));
|
||||||
|
dell_z9100_iom_cpld_write(data,QSFP_INT_MASK1,(u8)((devdata >> 8) & 0xff));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t get_abs_mask(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16 devdata=0;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_ABS_MASK0);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata = (u16)ret & 0xff;
|
||||||
|
|
||||||
|
ret = dell_z9100_iom_cpld_read(data,QSFP_ABS_MASK1);
|
||||||
|
if(ret < 0)
|
||||||
|
return sprintf(buf, "read error");
|
||||||
|
devdata |= (u16)(ret & 0xff) << 8;
|
||||||
|
|
||||||
|
return sprintf(buf,"0x%04x\n",devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t set_abs_mask(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long devdata;
|
||||||
|
int err;
|
||||||
|
struct cpld_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtoul(buf, 16, &devdata);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
dell_z9100_iom_cpld_write(data,QSFP_ABS_MASK0,(u8)(devdata & 0xff));
|
||||||
|
dell_z9100_iom_cpld_write(data,QSFP_ABS_MASK1,(u8)((devdata >> 8) & 0xff));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL);
|
static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL);
|
||||||
static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL);
|
static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL);
|
||||||
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode);
|
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode);
|
||||||
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset);
|
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset);
|
||||||
|
static DEVICE_ATTR(qsfp_int_sta, S_IRUGO, get_int_sta, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_abs_sta, S_IRUGO, get_abs_sta, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_trig_mod, S_IRUGO | S_IWUSR, get_trig_mod, set_trig_mod);
|
||||||
|
static DEVICE_ATTR(qsfp_int_combine, S_IRUGO, get_int_combine, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_int, S_IRUGO, get_int, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_abs_int, S_IRUGO, get_abs_int, NULL);
|
||||||
|
static DEVICE_ATTR(qsfp_int_mask, S_IRUGO | S_IWUSR, get_int_mask, set_int_mask);
|
||||||
|
static DEVICE_ATTR(qsfp_abs_mask, S_IRUGO | S_IWUSR, get_abs_mask, set_abs_mask);
|
||||||
|
|
||||||
static struct attribute *i2c_cpld_attrs[] = {
|
static struct attribute *i2c_cpld_attrs[] = {
|
||||||
&dev_attr_qsfp_lpmode.attr,
|
&dev_attr_qsfp_lpmode.attr,
|
||||||
&dev_attr_qsfp_reset.attr,
|
&dev_attr_qsfp_reset.attr,
|
||||||
&dev_attr_qsfp_modprs.attr,
|
&dev_attr_qsfp_modprs.attr,
|
||||||
&dev_attr_iom_cpld_vers.attr,
|
&dev_attr_iom_cpld_vers.attr,
|
||||||
|
&dev_attr_qsfp_int_sta.attr,
|
||||||
|
&dev_attr_qsfp_abs_sta.attr,
|
||||||
|
&dev_attr_qsfp_trig_mod.attr,
|
||||||
|
&dev_attr_qsfp_int_combine.attr,
|
||||||
|
&dev_attr_qsfp_int.attr,
|
||||||
|
&dev_attr_qsfp_abs_int.attr,
|
||||||
|
&dev_attr_qsfp_int_mask.attr,
|
||||||
|
&dev_attr_qsfp_abs_mask.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -136,11 +136,32 @@ switch_board_qsfp() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Enable/Disable xcvr presence interrupts
|
||||||
|
xcvr_presence_interrupts() {
|
||||||
|
case $1 in
|
||||||
|
"enable")
|
||||||
|
for ((i=14;i<=16;i++));
|
||||||
|
do
|
||||||
|
echo 0x0 > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"disable")
|
||||||
|
for ((i=14;i<=16;i++));
|
||||||
|
do
|
||||||
|
echo 0xffff > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
*) echo "z9100_platform: xcvr_presence_interrupts: invalid command !"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
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 dell_ich
|
||||||
modprobe dell_mailbox
|
modprobe dell_mailbox
|
||||||
modprobe dell_z9100_cpld
|
modprobe dell_z9100_cpld
|
||||||
|
|
||||||
@ -151,7 +172,9 @@ if [[ "$1" == "init" ]]; then
|
|||||||
switch_board_qsfp_mux "new_device"
|
switch_board_qsfp_mux "new_device"
|
||||||
switch_board_sfp "new_device"
|
switch_board_sfp "new_device"
|
||||||
switch_board_qsfp "new_device"
|
switch_board_qsfp "new_device"
|
||||||
|
xcvr_presence_interrupts "enable"
|
||||||
elif [[ "$1" == "deinit" ]]; then
|
elif [[ "$1" == "deinit" ]]; then
|
||||||
|
xcvr_presence_interrupts "disable"
|
||||||
switch_board_sfp "delete_device"
|
switch_board_sfp "delete_device"
|
||||||
switch_board_cpld "delete_device"
|
switch_board_cpld "delete_device"
|
||||||
switch_board_mux "delete_device"
|
switch_board_mux "delete_device"
|
||||||
@ -164,6 +187,7 @@ elif [[ "$1" == "deinit" ]]; then
|
|||||||
modprobe -r dell_mailbox
|
modprobe -r dell_mailbox
|
||||||
modprobe -r i2c-mux-pca954x
|
modprobe -r i2c-mux-pca954x
|
||||||
modprobe -r i2c-dev
|
modprobe -r i2c-dev
|
||||||
|
modprobe -r dell_ich
|
||||||
else
|
else
|
||||||
echo "z9100_platform : Invalid option !"
|
echo "z9100_platform : Invalid option !"
|
||||||
fi
|
fi
|
||||||
|
Reference in New Issue
Block a user