[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:
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
import select
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
except ImportError as e:
|
||||
raise ImportError("%s - required module not found" % str(e))
|
||||
@ -337,3 +340,70 @@ class SfpUtil(SfpUtilBase):
|
||||
reg_file.close()
|
||||
|
||||
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:
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
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 \
|
||||
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; \
|
||||
echo "making man page alias $$mod -> $$mod APIs";\
|
||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
||||
@ -37,8 +39,10 @@ override_dh_clean:
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
if [ $$mod = "s6100" ]; then \
|
||||
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 \
|
||||
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \
|
||||
rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \
|
||||
fi; \
|
||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
|
||||
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_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 i2c_client *client;
|
||||
@ -182,16 +197,219 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c
|
||||
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(qsfp_modprs, S_IRUGO,get_modprs, NULL);
|
||||
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_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[] = {
|
||||
&dev_attr_qsfp_lpmode.attr,
|
||||
&dev_attr_qsfp_reset.attr,
|
||||
&dev_attr_qsfp_modprs.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,
|
||||
};
|
||||
|
||||
|
@ -171,11 +171,32 @@ switch_board_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
|
||||
|
||||
if [[ "$1" == "init" ]]; then
|
||||
modprobe i2c-dev
|
||||
modprobe i2c-mux-pca954x force_deselect_on_exit=1
|
||||
modprobe dell_ich
|
||||
modprobe dell_s6100_iom_cpld
|
||||
modprobe dell_s6100_lpc
|
||||
|
||||
@ -187,7 +208,9 @@ if [[ "$1" == "init" ]]; then
|
||||
switch_board_sfp "new_device"
|
||||
switch_board_qsfp "new_device"
|
||||
switch_board_qsfp_lpmode "disable"
|
||||
xcvr_presence_interrupts "enable"
|
||||
elif [[ "$1" == "deinit" ]]; then
|
||||
xcvr_presence_interrupts "disable"
|
||||
switch_board_sfp "delete_device"
|
||||
switch_board_cpld "delete_device"
|
||||
switch_board_mux "delete_device"
|
||||
@ -200,6 +223,7 @@ elif [[ "$1" == "deinit" ]]; then
|
||||
modprobe -r dell_s6100_iom_cpld
|
||||
modprobe -r i2c-mux-pca954x
|
||||
modprobe -r i2c-dev
|
||||
modprobe -r dell_ich
|
||||
else
|
||||
echo "s6100_platform : Invalid option !"
|
||||
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_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 i2c_client *client;
|
||||
@ -189,16 +204,219 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c
|
||||
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(qsfp_modprs, S_IRUGO,get_modprs, NULL);
|
||||
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_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[] = {
|
||||
&dev_attr_qsfp_lpmode.attr,
|
||||
&dev_attr_qsfp_reset.attr,
|
||||
&dev_attr_qsfp_modprs.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,
|
||||
};
|
||||
|
||||
|
@ -136,11 +136,32 @@ switch_board_qsfp() {
|
||||
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
|
||||
|
||||
if [[ "$1" == "init" ]]; then
|
||||
modprobe i2c-dev
|
||||
modprobe i2c-mux-pca954x force_deselect_on_exit=1
|
||||
modprobe dell_ich
|
||||
modprobe dell_mailbox
|
||||
modprobe dell_z9100_cpld
|
||||
|
||||
@ -151,7 +172,9 @@ if [[ "$1" == "init" ]]; then
|
||||
switch_board_qsfp_mux "new_device"
|
||||
switch_board_sfp "new_device"
|
||||
switch_board_qsfp "new_device"
|
||||
xcvr_presence_interrupts "enable"
|
||||
elif [[ "$1" == "deinit" ]]; then
|
||||
xcvr_presence_interrupts "disable"
|
||||
switch_board_sfp "delete_device"
|
||||
switch_board_cpld "delete_device"
|
||||
switch_board_mux "delete_device"
|
||||
@ -164,6 +187,7 @@ elif [[ "$1" == "deinit" ]]; then
|
||||
modprobe -r dell_mailbox
|
||||
modprobe -r i2c-mux-pca954x
|
||||
modprobe -r i2c-dev
|
||||
modprobe -r dell_ich
|
||||
else
|
||||
echo "z9100_platform : Invalid option !"
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user