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

[as9716-32d]Add support get_transceiver_change_event #4105

Merged
merged 1 commit into from
Apr 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 90 additions & 7 deletions device/accton/x86_64-accton_as9716_32d-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 sys, getopt
from sonic_sfp.sfputilbase import SfpUtilBase
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
Expand Down Expand Up @@ -141,10 +143,91 @@ def reset(self, port_num):

return True

def get_transceiver_change_event(self):
"""
TODO: This function need to be implemented
when decide to support monitoring SFP(Xcvrd)
on this platform.
"""
raise NotImplementedError
def get_cpld_interrupt(self):
port_dict={}
for i in range(0,4):
if i==0 or i==1:
cpld_i2c_path = self.BASE_CPLD1_PATH + "cpld_intr_" + str(i+1)
else:
cpld_i2c_path = self.BASE_CPLD2_PATH + "cpld_intr_" +str(i+1)

start_i=(i*8)
end_i=(i*8+8)
try:
val_file = open(cpld_i2c_path)
except IOError as e:
print "Error: unable to open file: %s" % str(e)

for k in range (start_i, end_i):
port_dict[k]=0
return port_dict

status = val_file.readline().rstrip()
val_file.close()
status=status.strip()
status= int(status, 16)

interrupt_status = ~(status & 0xff)
if interrupt_status:
port_shift=0
for k in range (start_i, end_i):
if interrupt_status & (0x1<<port_shift):
port_dict[k]=1
else:
port_dict[k]=0
port_shift=port_shift+1

return port_dict

def get_transceiver_change_event(self, timeout=0):
start_time = time.time()
port_dict = {}
ori_present ={}
forever = False

if timeout == 0:
forever = True
elif timeout > 0:
timeout = timeout / float(1000) # Convert to secs
else:
print "get_transceiver_change_event:Invalid timeout value", timeout
return False, {}

end_time = start_time + timeout
if start_time > end_time:
print 'get_transceiver_change_event:' \
'time wrap / invalid timeout value', timeout

return False, {} # Time wrap or possibly incorrect timeout

#for i in range(self.port_start, self.port_end+1):
# ori_present[i]=self.get_presence(i)

while timeout >= 0:
change_status=0

port_dict = self.get_cpld_interrupt()
present=0
for key, value in port_dict.iteritems():
if value==1:
present=self.get_presence(key)
change_status=1
if present:
port_dict[key]='1'
else:
port_dict[key]='0'

if change_status:
return True, port_dict
if forever:
time.sleep(1)
else:
timeout = end_time - time.time()
if timeout >= 1:
time.sleep(1) # We poll at 1 second granularity
else:
if timeout > 0:
time.sleep(timeout)
return True, {}
print "get_evt_change_event: Should not reach here."
return False, {}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(i2c, as9716_32d_cpld_id);
#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index
#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index
#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index
#define CPLD_INTR_ATTR_ID(index) CPLD_INTR_##index

enum as9716_32d_cpld_sysfs_attributes {
CPLD_VERSION,
Expand Down Expand Up @@ -149,10 +150,17 @@ enum as9716_32d_cpld_sysfs_attributes {
TRANSCEIVER_RESET_ATTR_ID(30),
TRANSCEIVER_RESET_ATTR_ID(31),
TRANSCEIVER_RESET_ATTR_ID(32),
CPLD_INTR_ATTR_ID(1),
CPLD_INTR_ATTR_ID(2),
CPLD_INTR_ATTR_ID(3),
CPLD_INTR_ATTR_ID(4),

};

/* sysfs attributes for hwmon
*/
static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_status(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
Expand Down Expand Up @@ -188,6 +196,11 @@ static int as9716_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8
static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, MODULE_RESET_##index)
#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr

/*cpld interrupt*/
#define DECLARE_CPLD_DEVICE_INTR_ATTR(index) \
static SENSOR_DEVICE_ATTR(cpld_intr_##index, S_IRUGO, show_interrupt, NULL, CPLD_INTR_##index)
#define DECLARE_CPLD_INTR_ATTR(index) &sensor_dev_attr_cpld_intr_##index.dev_attr.attr



static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
Expand Down Expand Up @@ -261,6 +274,10 @@ DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(29);
DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(30);
DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(31);
DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(32);
DECLARE_CPLD_DEVICE_INTR_ATTR(1);
DECLARE_CPLD_DEVICE_INTR_ATTR(2);
DECLARE_CPLD_DEVICE_INTR_ATTR(3);
DECLARE_CPLD_DEVICE_INTR_ATTR(4);



Expand Down Expand Up @@ -309,6 +326,8 @@ static struct attribute *as9716_32d_cpld1_attributes[] = {
DECLARE_TRANSCEIVER_RESET_ATTR(14),
DECLARE_TRANSCEIVER_RESET_ATTR(15),
DECLARE_TRANSCEIVER_RESET_ATTR(16),
DECLARE_CPLD_INTR_ATTR(1),
DECLARE_CPLD_INTR_ATTR(2),
NULL
};

Expand Down Expand Up @@ -355,6 +374,8 @@ static struct attribute *as9716_32d_cpld2_attributes[] = {
DECLARE_TRANSCEIVER_RESET_ATTR(30),
DECLARE_TRANSCEIVER_RESET_ATTR(31),
DECLARE_TRANSCEIVER_RESET_ATTR(32),
DECLARE_CPLD_INTR_ATTR(3),
DECLARE_CPLD_INTR_ATTR(4),
NULL
};

Expand All @@ -363,6 +384,47 @@ static const struct attribute_group as9716_32d_cpld2_group = {
};


static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct as9716_32d_cpld_data *data = i2c_get_clientdata(client);
int status = 0;
u8 reg = 0;

switch (attr->index)
{
case CPLD_INTR_1:
reg = 0x10;
break;
case CPLD_INTR_3:
reg = 0x10;
break;
case CPLD_INTR_2:
reg = 0x11;
break;
case CPLD_INTR_4:
reg = 0x11;
break;
default:
return -ENODEV;
}
mutex_lock(&data->update_lock);
status = as9716_32d_cpld_read_internal(client, reg);
if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);

return sprintf(buf, "0x%x\n", status);

exit:
mutex_unlock(&data->update_lock);
return status;
}


static ssize_t show_status(struct device *dev, struct device_attribute *da,
char *buf)
{
Expand Down Expand Up @@ -723,9 +785,21 @@ static int as9716_32d_cpld_probe(struct i2c_client *client,
break;
case as9716_32d_cpld1:
group = &as9716_32d_cpld1_group;
/*Set interrupt mask to 0, and then can get intr from 0x8*/
status=as9716_32d_cpld_write_internal(client, 0x9, 0x0);
if (status < 0)
{
dev_dbg(&client->dev, "cpld1 reg 0x9 err %d\n", status);
}
break;
case as9716_32d_cpld2:
group = &as9716_32d_cpld2_group;
/*Set interrupt mask to 0, and then can get intr from 0x8*/
status=as9716_32d_cpld_write_internal(client, 0x9, 0x0);
if (status < 0)
{
dev_dbg(&client->dev, "cpld2 reg 0x65 err %d\n", status);
}
break;
case as9716_32d_cpld_cpu:
/* Disable CPLD reset to avoid DUT will be reset.
Expand Down