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

Seastone dx010 xcvrd event support #2487

Closed
wants to merge 4 commits into from
Closed
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
40 changes: 39 additions & 1 deletion device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

try:
import time
import os
import select
from sonic_sfp.sfputilbase import SfpUtilBase
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
Expand Down Expand Up @@ -201,4 +203,40 @@ def reset(self, port_num):
return True

def get_transceiver_change_event(self, timeout=0):
raise NotImplementedError
epoll = select.epoll()
port_dict = {}
timeout_sec = timeout/1000
modabs_interrupt_path = '/sys/devices/platform/dx010_cpld/qsfp_modprs_irq'

with open(modabs_interrupt_path, 'r') as port_changes:
port_changes.read()
try:
# We get notified when there is an SCI interrupt from GPIO SUS6
fd = open("/sys/devices/platform/slx-ich.0/sci_int_gpio_sus6", "r")
fd.read()

epoll.register(fd.fileno(), select.EPOLLIN & select.EPOLLET)
events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1)
if events:
found_flag = 0
# Read the QSFP ABS interrupt & status registers
with open(modabs_interrupt_path, 'r') as port_changes:
changes = int(port_changes.read(), 16)
for port_num in self.qsfp_ports:
change = (changes >> port_num-1) & 1
if change == 1:
port_dict[str(port_num)] = str(
int(self.get_presence(port_num)))
found_flag = 1

if not found_flag:
return False, {}

return True, port_dict

finally:
fd.close()
epoll.close()

return False, {}

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ start)
modprobe dx010_wdt
modprobe leds-dx010
modprobe lm75
modprobe slx_gpio_ich

found=0
for devnum in 0 1; do
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o
obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o slx_gpio_ich.o
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@
#define INT2229 0x3d6
#define INT3032 0x3d7

#define ABS_INT0108 0x260
#define ABS_INT0910 0x261
#define ABS_INT1118 0x2E0
#define ABS_INT1921 0x2E1
#define ABS_INT2229 0x3E0
#define ABS_INT3032 0x3E1

#define ABS_INT_MSK0108 0x262
#define ABS_INT_MSK0910 0x263
#define ABS_INT_MSK1118 0x2E2
#define ABS_INT_MSK1921 0x2E3
#define ABS_INT_MSK2229 0x3E2
#define ABS_INT_MSK3032 0x3E3

#define CPLD4_INT0 0x313
#define CPLD4_INT0_MSK 0x315

#define LENGTH_PORT_CPLD 34
#define PORT_BANK1_START 1
Expand Down Expand Up @@ -322,12 +338,136 @@ static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr,
return sprintf(buf,"0x%8.8lx\n", irq & 0xffffffff);
}

static ssize_t get_modprs_irq(struct device *dev, struct device_attribute *devattr,
char *buf)
{
unsigned long prs_int = 0;

mutex_lock(&cpld_data->cpld_lock);

/* Clear interrupt source */
inb(CPLD4_INT0);

prs_int =
(inb(ABS_INT3032) & 0x07) << (24+5) |
inb(ABS_INT2229) << (24-3) |
(inb(ABS_INT1921) & 0x07) << (16 + 2) |
inb(ABS_INT1118) << (16-6) |
(inb(ABS_INT0910) & 0x03 ) << 8 |
inb(ABS_INT0108);

mutex_unlock(&cpld_data->cpld_lock);

return sprintf(buf,"0x%8.8lx\n", prs_int & 0xffffffff);
}

static ssize_t get_modprs_msk(struct device *dev, struct device_attribute *devattr,
char *buf)
{
unsigned long prs_int_msk = 0;

mutex_lock(&cpld_data->cpld_lock);

prs_int_msk =
(inb(ABS_INT_MSK3032) & 0x07) << (24+5) |
inb(ABS_INT_MSK2229) << (24-3) |
(inb(ABS_INT_MSK1921) & 0x07) << (16 + 2) |
inb(ABS_INT_MSK1118) << (16-6) |
(inb(ABS_INT_MSK0910) & 0x03 ) << 8 |
inb(ABS_INT_MSK0108);

mutex_unlock(&cpld_data->cpld_lock);

return sprintf(buf,"0x%8.8lx\n", prs_int_msk & 0xffffffff);
}

static ssize_t set_modprs_msk(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
unsigned long prs_int_msk;
int err;

mutex_lock(&cpld_data->cpld_lock);

err = kstrtoul(buf, 16, &prs_int_msk);
if (err)
{
mutex_unlock(&cpld_data->cpld_lock);
return err;
}

outb( (prs_int_msk >> 0) & 0xFF, ABS_INT_MSK0108);
outb( (prs_int_msk >> 8) & 0x03, ABS_INT_MSK0910);
outb( (prs_int_msk >> 10) & 0xFF, ABS_INT_MSK1118);
outb( (prs_int_msk >> 18) & 0x07, ABS_INT_MSK1921);
outb( (prs_int_msk >> 21) & 0xFF, ABS_INT_MSK2229);
outb( (prs_int_msk >> 29) & 0x07, ABS_INT_MSK3032);

mutex_unlock(&cpld_data->cpld_lock);

return count;
}

static ssize_t get_cpld4_int0(struct device *dev, struct device_attribute *devattr,
char *buf)
{
unsigned char int0 = 0;

mutex_lock(&cpld_data->cpld_lock);

int0 = inb(CPLD4_INT0);

mutex_unlock(&cpld_data->cpld_lock);

return sprintf(buf,"0x%2.2x\n", int0 & 0xff);
}

static ssize_t get_cpld4_int0_msk(struct device *dev, struct device_attribute *devattr,
char *buf)
{
unsigned char int0_msk = 0;

mutex_lock(&cpld_data->cpld_lock);

int0_msk = inb(CPLD4_INT0_MSK);

mutex_unlock(&cpld_data->cpld_lock);

return sprintf(buf,"0x%2.2x\n", int0_msk & 0xff);
}

static ssize_t set_cpld4_int0_msk(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
unsigned long int0_msk;
int err;

mutex_lock(&cpld_data->cpld_lock);

err = kstrtoul(buf, 16, &int0_msk);
if (err)
{
mutex_unlock(&cpld_data->cpld_lock);
return err;
}

outb(int0_msk & 0x3f, CPLD4_INT0_MSK);

mutex_unlock(&cpld_data->cpld_lock);

return count;
}

static DEVICE_ATTR_RW(getreg);
static DEVICE_ATTR_WO(setreg);
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset);
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode);
static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL);
static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL);
static DEVICE_ATTR(qsfp_modprs_irq, S_IRUGO, get_modprs_irq, NULL);
static DEVICE_ATTR(qsfp_modprs_msk, S_IRUGO | S_IWUSR, get_modprs_msk, set_modprs_msk);
static DEVICE_ATTR(cpld4_int0, S_IRUGO, get_cpld4_int0, NULL);
static DEVICE_ATTR(cpld4_int0_msk, S_IRUGO | S_IWUSR, get_cpld4_int0_msk, set_cpld4_int0_msk);

static struct attribute *dx010_lpc_attrs[] = {
&dev_attr_getreg.attr,
Expand All @@ -336,6 +476,10 @@ static struct attribute *dx010_lpc_attrs[] = {
&dev_attr_qsfp_lpmode.attr,
&dev_attr_qsfp_modprs.attr,
&dev_attr_qsfp_modirq.attr,
&dev_attr_qsfp_modprs_irq.attr,
&dev_attr_qsfp_modprs_msk.attr,
&dev_attr_cpld4_int0.attr,
&dev_attr_cpld4_int0_msk.attr,
NULL,
};

Expand Down Expand Up @@ -568,7 +712,7 @@ static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int
static int cel_dx010_lpc_drv_probe(struct platform_device *pdev)
{
struct resource *res;
int ret =0;
int ret = 0;
int portid_count;

cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct dx010_cpld_data),
Expand All @@ -594,6 +738,17 @@ static int cel_dx010_lpc_drv_probe(struct platform_device *pdev)
cpld_data->i2c_adapter[portid_count-1] =
cel_dx010_i2c_init(pdev, portid_count);

/* Enable INT0 interrupt register */
outb(inb(CPLD4_INT0_MSK) & 0xf8, CPLD4_INT0_MSK);

/* Enable modprs interrupt register */
outb(0, ABS_INT_MSK0108);
outb(0, ABS_INT_MSK0910);
outb(0, ABS_INT_MSK1118);
outb(0, ABS_INT_MSK1921);
outb(0, ABS_INT_MSK2229);
outb(0, ABS_INT_MSK3032);

return 0;
}

Expand Down Expand Up @@ -634,7 +789,7 @@ void cel_dx010_lpc_exit(void)
module_init(cel_dx010_lpc_init);
module_exit(cel_dx010_lpc_exit);

MODULE_AUTHOR("Abhisit Sangjan <asang@celestica.com>");
MODULE_AUTHOR("Pariwat Leamsumran <pleamsum@celestica.com>");
MODULE_AUTHOR("Pradchaya P <pphuchar@celestica.com>");
MODULE_VERSION("1.0.1");
MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver");
MODULE_LICENSE("GPL");
Loading