mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-25 01:07:01 +00:00
Merge pull request #386 from brandonchuang/as5812_54x
[as5812-54x] Add support for OOM driver(Fix eeprom unrecognized issue)
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -131,8 +131,8 @@ static ssize_t fan_set_duty_cycle(struct device *dev,
|
||||
static ssize_t fan_show_value(struct device *dev,
|
||||
struct device_attribute *da, char *buf);
|
||||
|
||||
extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
extern int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
|
||||
/*******************/
|
||||
@@ -258,12 +258,12 @@ static const struct attribute_group accton_as5812_54x_fan_group = {
|
||||
|
||||
static int accton_as5812_54x_fan_read_value(u8 reg)
|
||||
{
|
||||
return as5812_54x_i2c_cpld_read(0x60, reg);
|
||||
return as5812_54x_cpld_read(0x60, reg);
|
||||
}
|
||||
|
||||
static int accton_as5812_54x_fan_write_value(u8 reg, u8 value)
|
||||
{
|
||||
return as5812_54x_i2c_cpld_write(0x60, reg, value);
|
||||
return as5812_54x_cpld_write(0x60, reg, value);
|
||||
}
|
||||
|
||||
static void accton_as5812_54x_fan_update_device(struct device *dev)
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <linux/leds.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
extern int as5812_54x_i2c_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
extern int as5812_54x_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
@@ -220,12 +220,12 @@ static u8 led_light_mode_to_reg_val(enum led_type type,
|
||||
|
||||
static int accton_as5812_54x_led_read_value(u8 reg)
|
||||
{
|
||||
return as5812_54x_i2c_cpld_read(0x60, reg);
|
||||
return as5812_54x_cpld_read(0x60, reg);
|
||||
}
|
||||
|
||||
static int accton_as5812_54x_led_write_value(u8 reg, u8 value)
|
||||
{
|
||||
return as5812_54x_i2c_cpld_write(0x60, reg, value);
|
||||
return as5812_54x_cpld_write(0x60, reg, value);
|
||||
}
|
||||
|
||||
static void accton_as5812_54x_led_update(void)
|
||||
|
||||
@@ -44,7 +44,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, char
|
||||
static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t show_serial_number(struct device *dev, struct device_attribute *da,char *buf);
|
||||
static int as5812_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len);
|
||||
extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
static int as5812_54x_psu_model_name_get(struct device *dev , int get_serial);
|
||||
|
||||
/* Addresses scanned
|
||||
@@ -406,7 +406,7 @@ static struct as5812_54x_psu_data *as5812_54x_psu_update_device(struct device *d
|
||||
|
||||
|
||||
/* Read psu status */
|
||||
status = as5812_54x_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET);
|
||||
status = as5812_54x_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET);
|
||||
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status);
|
||||
@@ -426,20 +426,9 @@ exit:
|
||||
return data;
|
||||
}
|
||||
|
||||
static int __init as5812_54x_psu_init(void)
|
||||
{
|
||||
return i2c_add_driver(&as5812_54x_psu_driver);
|
||||
}
|
||||
|
||||
static void __exit as5812_54x_psu_exit(void)
|
||||
{
|
||||
i2c_del_driver(&as5812_54x_psu_driver);
|
||||
}
|
||||
module_i2c_driver(as5812_54x_psu_driver);
|
||||
|
||||
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
|
||||
MODULE_DESCRIPTION("accton as5812_54x_psu driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(as5812_54x_psu_init);
|
||||
module_exit(as5812_54x_psu_exit);
|
||||
|
||||
|
||||
@@ -1,508 +0,0 @@
|
||||
/*
|
||||
* An hwmon driver for accton as5812_54x sfp
|
||||
*
|
||||
* Copyright (C) 2015 Accton Technology Corporation.
|
||||
* Brandon Chuang <brandon_chuang@accton.com.tw>
|
||||
*
|
||||
* Based on ad7414.c
|
||||
* Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define NUM_OF_SFP_PORT 54
|
||||
#define BIT_INDEX(i) (1ULL << (i))
|
||||
|
||||
/* Addresses scanned
|
||||
*/
|
||||
static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
|
||||
|
||||
/* Each client has this additional data
|
||||
*/
|
||||
struct as5812_54x_sfp_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid; /* !=0 if registers are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
int port; /* Front port index */
|
||||
char eeprom[256]; /* eeprom data */
|
||||
u64 status[4]; /* bit0:port0, bit1:port1 and so on */
|
||||
/* index 0 => is_present
|
||||
1 => tx_fail
|
||||
2 => tx_disable
|
||||
3 => rx_loss */
|
||||
};
|
||||
|
||||
/* The table maps active port to cpld port.
|
||||
* Array index 0 is for active port 1,
|
||||
* index 1 for active port 2, and so on.
|
||||
* The array content implies cpld port index.
|
||||
*/
|
||||
static const u8 cpld_to_front_port_table[] =
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 52, 50, 53, 51, 54};
|
||||
|
||||
#define CPLD_PORT_TO_FRONT_PORT(port) (cpld_to_front_port_table[port])
|
||||
|
||||
static struct as5812_54x_sfp_data *as5812_54x_sfp_update_device(struct device *dev, int update_eeprom);
|
||||
static ssize_t show_port_number(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 show_eeprom(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
enum as5812_54x_sfp_sysfs_attributes {
|
||||
SFP_IS_PRESENT,
|
||||
SFP_TX_FAULT,
|
||||
SFP_TX_DISABLE,
|
||||
SFP_RX_LOSS,
|
||||
SFP_PORT_NUMBER,
|
||||
SFP_EEPROM,
|
||||
SFP_RX_LOS_ALL,
|
||||
SFP_IS_PRESENT_ALL,
|
||||
};
|
||||
|
||||
/* sysfs attributes for hwmon
|
||||
*/
|
||||
static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT);
|
||||
static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, show_status, NULL, SFP_TX_FAULT);
|
||||
static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, show_status, set_tx_disable, SFP_TX_DISABLE);
|
||||
static SENSOR_DEVICE_ATTR(sfp_rx_loss, S_IRUGO, show_status,NULL, SFP_RX_LOSS);
|
||||
static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER);
|
||||
static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM);
|
||||
static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, show_status,NULL, SFP_RX_LOS_ALL);
|
||||
static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL);
|
||||
|
||||
static struct attribute *as5812_54x_sfp_attributes[] = {
|
||||
&sensor_dev_attr_sfp_is_present.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_tx_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_rx_loss.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_tx_disable.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_eeprom.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_port_number.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_rx_los_all.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_is_present_all.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t show_port_number(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_sfp_data *data = i2c_get_clientdata(client);
|
||||
|
||||
return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port));
|
||||
}
|
||||
|
||||
static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5812_54x_sfp_data *data;
|
||||
u8 val;
|
||||
int values[7];
|
||||
|
||||
/* Error-check the CPLD read results. */
|
||||
#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \
|
||||
do { \
|
||||
_rv = (_read_expr); \
|
||||
if(_rv < 0) { \
|
||||
return sprintf(_buf, "READ ERROR\n"); \
|
||||
} \
|
||||
if(_invert) { \
|
||||
_rv = ~_rv; \
|
||||
} \
|
||||
_rv &= 0xFF; \
|
||||
} while(0)
|
||||
|
||||
if(attr->index == SFP_RX_LOS_ALL) {
|
||||
/*
|
||||
* Report the RX_LOS status for all ports.
|
||||
* This does not depend on the currently active SFP selector.
|
||||
*/
|
||||
|
||||
/* RX_LOS Ports 1-8 */
|
||||
VALIDATED_READ(buf, values[0], as5812_54x_i2c_cpld_read(0x61, 0x0F), 0);
|
||||
/* RX_LOS Ports 9-16 */
|
||||
VALIDATED_READ(buf, values[1], as5812_54x_i2c_cpld_read(0x61, 0x10), 0);
|
||||
/* RX_LOS Ports 17-24 */
|
||||
VALIDATED_READ(buf, values[2], as5812_54x_i2c_cpld_read(0x61, 0x11), 0);
|
||||
/* RX_LOS Ports 25-32 */
|
||||
VALIDATED_READ(buf, values[3], as5812_54x_i2c_cpld_read(0x62, 0x0F), 0);
|
||||
/* RX_LOS Ports 33-40 */
|
||||
VALIDATED_READ(buf, values[4], as5812_54x_i2c_cpld_read(0x62, 0x10), 0);
|
||||
/* RX_LOS Ports 41-48 */
|
||||
VALIDATED_READ(buf, values[5], as5812_54x_i2c_cpld_read(0x62, 0x11), 0);
|
||||
|
||||
/** Return values 1 -> 48 in order */
|
||||
return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n",
|
||||
values[0], values[1], values[2],
|
||||
values[3], values[4], values[5]);
|
||||
}
|
||||
|
||||
if(attr->index == SFP_IS_PRESENT_ALL) {
|
||||
/*
|
||||
* Report the SFP_PRESENCE status for all ports.
|
||||
* This does not depend on the currently active SFP selector.
|
||||
*/
|
||||
|
||||
/* SFP_PRESENT Ports 1-8 */
|
||||
VALIDATED_READ(buf, values[0], as5812_54x_i2c_cpld_read(0x61, 0x6), 1);
|
||||
/* SFP_PRESENT Ports 9-16 */
|
||||
VALIDATED_READ(buf, values[1], as5812_54x_i2c_cpld_read(0x61, 0x7), 1);
|
||||
/* SFP_PRESENT Ports 17-24 */
|
||||
VALIDATED_READ(buf, values[2], as5812_54x_i2c_cpld_read(0x61, 0x8), 1);
|
||||
/* SFP_PRESENT Ports 25-32 */
|
||||
VALIDATED_READ(buf, values[3], as5812_54x_i2c_cpld_read(0x62, 0x6), 1);
|
||||
/* SFP_PRESENT Ports 33-40 */
|
||||
VALIDATED_READ(buf, values[4], as5812_54x_i2c_cpld_read(0x62, 0x7), 1);
|
||||
/* SFP_PRESENT Ports 41-48 */
|
||||
VALIDATED_READ(buf, values[5], as5812_54x_i2c_cpld_read(0x62, 0x8), 1);
|
||||
/* QSFP_PRESENT Ports 49-54 */
|
||||
VALIDATED_READ(buf, values[6], as5812_54x_i2c_cpld_read(0x62, 0x14), 1);
|
||||
|
||||
/* Return values 1 -> 54 in order */
|
||||
return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n",
|
||||
values[0], values[1], values[2],
|
||||
values[3], values[4], values[5],
|
||||
values[6] & 0x3F);
|
||||
}
|
||||
/*
|
||||
* The remaining attributes are gathered on a per-selected-sfp basis.
|
||||
*/
|
||||
data = as5812_54x_sfp_update_device(dev, 0);
|
||||
if (attr->index == SFP_IS_PRESENT) {
|
||||
val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 0 : 1;
|
||||
}
|
||||
else {
|
||||
val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 1 : 0;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d", val);
|
||||
}
|
||||
|
||||
static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_sfp_data *data = i2c_get_clientdata(client);
|
||||
unsigned short cpld_addr = 0;
|
||||
u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0;
|
||||
long disable;
|
||||
int error;
|
||||
|
||||
/* Tx disable is not supported for QSFP ports(49-54) */
|
||||
if (data->port >= 48) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = kstrtol(buf, 10, &disable);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if(data->port < 24) {
|
||||
cpld_addr = 0x61;
|
||||
cpld_reg = 0xC + data->port / 8;
|
||||
cpld_bit = 1 << (data->port % 8);
|
||||
}
|
||||
else {
|
||||
cpld_addr = 0x62;
|
||||
cpld_reg = 0xC + (data->port - 24) / 8;
|
||||
cpld_bit = 1 << (data->port % 8);
|
||||
}
|
||||
|
||||
cpld_val = as5812_54x_i2c_cpld_read(cpld_addr, cpld_reg);
|
||||
|
||||
/* Update tx_disable status */
|
||||
if (disable) {
|
||||
data->status[SFP_TX_DISABLE] |= BIT_INDEX(data->port);
|
||||
cpld_val |= cpld_bit;
|
||||
}
|
||||
else {
|
||||
data->status[SFP_TX_DISABLE] &= ~BIT_INDEX(data->port);
|
||||
cpld_val &= ~cpld_bit;
|
||||
}
|
||||
|
||||
as5812_54x_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val);
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_eeprom(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct as5812_54x_sfp_data *data = as5812_54x_sfp_update_device(dev, 1);
|
||||
|
||||
if (!data->valid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buf, data->eeprom, sizeof(data->eeprom));
|
||||
|
||||
return sizeof(data->eeprom);
|
||||
}
|
||||
|
||||
static const struct attribute_group as5812_54x_sfp_group = {
|
||||
.attrs = as5812_54x_sfp_attributes,
|
||||
};
|
||||
|
||||
static int as5812_54x_sfp_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *dev_id)
|
||||
{
|
||||
struct as5812_54x_sfp_data *data;
|
||||
int status;
|
||||
|
||||
extern int platform_accton_as5812_54x(void);
|
||||
if(!platform_accton_as5812_54x()) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(struct as5812_54x_sfp_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_init(&data->update_lock);
|
||||
data->port = dev_id->driver_data;
|
||||
i2c_set_clientdata(client, data);
|
||||
|
||||
dev_info(&client->dev, "chip found\n");
|
||||
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&client->dev.kobj, &as5812_54x_sfp_group);
|
||||
if (status) {
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
status = PTR_ERR(data->hwmon_dev);
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "%s: sfp '%s'\n",
|
||||
dev_name(data->hwmon_dev), client->name);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
sysfs_remove_group(&client->dev.kobj, &as5812_54x_sfp_group);
|
||||
exit_free:
|
||||
kfree(data);
|
||||
exit:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int as5812_54x_sfp_remove(struct i2c_client *client)
|
||||
{
|
||||
struct as5812_54x_sfp_data *data = i2c_get_clientdata(client);
|
||||
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &as5812_54x_sfp_group);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum port_numbers {
|
||||
as5812_54x_sfp1, as5812_54x_sfp2, as5812_54x_sfp3, as5812_54x_sfp4,
|
||||
as5812_54x_sfp5, as5812_54x_sfp6, as5812_54x_sfp7, as5812_54x_sfp8,
|
||||
as5812_54x_sfp9, as5812_54x_sfp10, as5812_54x_sfp11,as5812_54x_sfp12,
|
||||
as5812_54x_sfp13, as5812_54x_sfp14, as5812_54x_sfp15,as5812_54x_sfp16,
|
||||
as5812_54x_sfp17, as5812_54x_sfp18, as5812_54x_sfp19,as5812_54x_sfp20,
|
||||
as5812_54x_sfp21, as5812_54x_sfp22, as5812_54x_sfp23,as5812_54x_sfp24,
|
||||
as5812_54x_sfp25, as5812_54x_sfp26, as5812_54x_sfp27,as5812_54x_sfp28,
|
||||
as5812_54x_sfp29, as5812_54x_sfp30, as5812_54x_sfp31,as5812_54x_sfp32,
|
||||
as5812_54x_sfp33, as5812_54x_sfp34, as5812_54x_sfp35,as5812_54x_sfp36,
|
||||
as5812_54x_sfp37, as5812_54x_sfp38, as5812_54x_sfp39,as5812_54x_sfp40,
|
||||
as5812_54x_sfp41, as5812_54x_sfp42, as5812_54x_sfp43,as5812_54x_sfp44,
|
||||
as5812_54x_sfp45, as5812_54x_sfp46, as5812_54x_sfp47,as5812_54x_sfp48,
|
||||
as5812_54x_sfp49, as5812_54x_sfp52, as5812_54x_sfp50,as5812_54x_sfp53,
|
||||
as5812_54x_sfp51, as5812_54x_sfp54
|
||||
};
|
||||
|
||||
static const struct i2c_device_id as5812_54x_sfp_id[] = {
|
||||
{ "as5812_54x_sfp1", as5812_54x_sfp1 }, { "as5812_54x_sfp2", as5812_54x_sfp2 },
|
||||
{ "as5812_54x_sfp3", as5812_54x_sfp3 }, { "as5812_54x_sfp4", as5812_54x_sfp4 },
|
||||
{ "as5812_54x_sfp5", as5812_54x_sfp5 }, { "as5812_54x_sfp6", as5812_54x_sfp6 },
|
||||
{ "as5812_54x_sfp7", as5812_54x_sfp7 }, { "as5812_54x_sfp8", as5812_54x_sfp8 },
|
||||
{ "as5812_54x_sfp9", as5812_54x_sfp9 }, { "as5812_54x_sfp10", as5812_54x_sfp10 },
|
||||
{ "as5812_54x_sfp11", as5812_54x_sfp11 }, { "as5812_54x_sfp12", as5812_54x_sfp12 },
|
||||
{ "as5812_54x_sfp13", as5812_54x_sfp13 }, { "as5812_54x_sfp14", as5812_54x_sfp14 },
|
||||
{ "as5812_54x_sfp15", as5812_54x_sfp15 }, { "as5812_54x_sfp16", as5812_54x_sfp16 },
|
||||
{ "as5812_54x_sfp17", as5812_54x_sfp17 }, { "as5812_54x_sfp18", as5812_54x_sfp18 },
|
||||
{ "as5812_54x_sfp19", as5812_54x_sfp19 }, { "as5812_54x_sfp20", as5812_54x_sfp20 },
|
||||
{ "as5812_54x_sfp21", as5812_54x_sfp21 }, { "as5812_54x_sfp22", as5812_54x_sfp22 },
|
||||
{ "as5812_54x_sfp23", as5812_54x_sfp23 }, { "as5812_54x_sfp24", as5812_54x_sfp24 },
|
||||
{ "as5812_54x_sfp25", as5812_54x_sfp25 }, { "as5812_54x_sfp26", as5812_54x_sfp26 },
|
||||
{ "as5812_54x_sfp27", as5812_54x_sfp27 }, { "as5812_54x_sfp28", as5812_54x_sfp28 },
|
||||
{ "as5812_54x_sfp29", as5812_54x_sfp29 }, { "as5812_54x_sfp30", as5812_54x_sfp30 },
|
||||
{ "as5812_54x_sfp31", as5812_54x_sfp31 }, { "as5812_54x_sfp32", as5812_54x_sfp32 },
|
||||
{ "as5812_54x_sfp33", as5812_54x_sfp33 }, { "as5812_54x_sfp34", as5812_54x_sfp34 },
|
||||
{ "as5812_54x_sfp35", as5812_54x_sfp35 }, { "as5812_54x_sfp36", as5812_54x_sfp36 },
|
||||
{ "as5812_54x_sfp37", as5812_54x_sfp37 }, { "as5812_54x_sfp38", as5812_54x_sfp38 },
|
||||
{ "as5812_54x_sfp39", as5812_54x_sfp39 }, { "as5812_54x_sfp40", as5812_54x_sfp40 },
|
||||
{ "as5812_54x_sfp41", as5812_54x_sfp41 }, { "as5812_54x_sfp42", as5812_54x_sfp42 },
|
||||
{ "as5812_54x_sfp43", as5812_54x_sfp43 }, { "as5812_54x_sfp44", as5812_54x_sfp44 },
|
||||
{ "as5812_54x_sfp45", as5812_54x_sfp45 }, { "as5812_54x_sfp46", as5812_54x_sfp46 },
|
||||
{ "as5812_54x_sfp47", as5812_54x_sfp47 }, { "as5812_54x_sfp48", as5812_54x_sfp48 },
|
||||
{ "as5812_54x_sfp49", as5812_54x_sfp49 }, { "as5812_54x_sfp50", as5812_54x_sfp50 },
|
||||
{ "as5812_54x_sfp51", as5812_54x_sfp51 }, { "as5812_54x_sfp52", as5812_54x_sfp52 },
|
||||
{ "as5812_54x_sfp53", as5812_54x_sfp53 }, { "as5812_54x_sfp54", as5812_54x_sfp54 },
|
||||
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, as5812_54x_sfp_id);
|
||||
|
||||
static struct i2c_driver as5812_54x_sfp_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "as5812_54x_sfp",
|
||||
},
|
||||
.probe = as5812_54x_sfp_probe,
|
||||
.remove = as5812_54x_sfp_remove,
|
||||
.id_table = as5812_54x_sfp_id,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
static int as5812_54x_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data)
|
||||
{
|
||||
int result = i2c_smbus_read_byte_data(client, command);
|
||||
|
||||
if (unlikely(result < 0)) {
|
||||
dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
*data = (u8)result;
|
||||
result = 0;
|
||||
|
||||
abort:
|
||||
return result;
|
||||
}
|
||||
|
||||
#define ALWAYS_UPDATE_DEVICE 1
|
||||
|
||||
static struct as5812_54x_sfp_data *as5812_54x_sfp_update_device(struct device *dev, int update_eeprom)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_sfp_data *data = i2c_get_clientdata(client);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (ALWAYS_UPDATE_DEVICE || time_after(jiffies, data->last_updated + HZ + HZ / 2)
|
||||
|| !data->valid) {
|
||||
int status = -1;
|
||||
int i = 0, j = 0;
|
||||
|
||||
data->valid = 0;
|
||||
//dev_dbg(&client->dev, "Starting as5812_54x sfp status update\n");
|
||||
memset(data->status, 0, sizeof(data->status));
|
||||
|
||||
/* Read status of port 1~48(SFP port) */
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 12; j++) {
|
||||
status = as5812_54x_i2c_cpld_read(0x61+i, 0x6+j);
|
||||
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", 0x61+i, 0x6+j, status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring QSFPs out of reset,
|
||||
* This is a temporary fix until the QSFP+_MOD_RST register
|
||||
* can be exposed through the driver.
|
||||
*/
|
||||
as5812_54x_i2c_cpld_write(0x62, 0x15, 0x3F);
|
||||
|
||||
/* Read present status of port 49-54(QSFP port) */
|
||||
status = as5812_54x_i2c_cpld_read(0x62, 0x14);
|
||||
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", 0x61+i, 0x6+j, status);
|
||||
}
|
||||
else {
|
||||
data->status[SFP_IS_PRESENT] |= (u64)status << 48;
|
||||
}
|
||||
|
||||
if (update_eeprom) {
|
||||
/* Read eeprom data based on port number */
|
||||
memset(data->eeprom, 0, sizeof(data->eeprom));
|
||||
|
||||
/* Check if the port is present */
|
||||
if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) {
|
||||
/* read eeprom */
|
||||
for (i = 0; i < sizeof(data->eeprom); i++) {
|
||||
status = as5812_54x_sfp_read_byte(client, i, data->eeprom + i);
|
||||
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n",
|
||||
CPLD_PORT_TO_FRONT_PORT(data->port));
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->valid = 1;
|
||||
data->last_updated = jiffies;
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
module_i2c_driver(as5812_54x_sfp_driver);
|
||||
|
||||
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
|
||||
MODULE_DESCRIPTION("accton as5812_54x_sfp driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -24,20 +24,24 @@
|
||||
*
|
||||
***********************************************************/
|
||||
#include <onlp/platformi/sfpi.h>
|
||||
|
||||
#include <fcntl.h> /* For O_RDWR && open */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <onlplib/i2c.h>
|
||||
#include "platform_lib.h"
|
||||
#include <onlplib/file.h>
|
||||
#include "x86_64_accton_as5812_54x_int.h"
|
||||
#include "x86_64_accton_as5812_54x_log.h"
|
||||
|
||||
#define MAX_SFP_PATH 64
|
||||
static char sfp_node_path[MAX_SFP_PATH] = {0};
|
||||
#define CPLD_MUX_BUS_START_INDEX 2
|
||||
|
||||
static int front_port_to_cpld_mux_index(int port)
|
||||
#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom"
|
||||
#define MODULE_PRESENT_FORMAT "/sys/bus/i2c/devices/0-00%d/module_present_%d"
|
||||
#define MODULE_RXLOS_FORMAT "/sys/bus/i2c/devices/0-00%d/module_rx_los_%d"
|
||||
#define MODULE_TXFAULT_FORMAT "/sys/bus/i2c/devices/0-00%d/module_tx_fault_%d"
|
||||
#define MODULE_TXDISABLE_FORMAT "/sys/bus/i2c/devices/0-00%d/module_tx_disable_%d"
|
||||
#define MODULE_PRESENT_ALL_ATTR_CPLD2 "/sys/bus/i2c/devices/0-0061/module_present_all"
|
||||
#define MODULE_PRESENT_ALL_ATTR_CPLD3 "/sys/bus/i2c/devices/0-0062/module_present_all"
|
||||
#define MODULE_RXLOS_ALL_ATTR_CPLD2 "/sys/bus/i2c/devices/0-0061/module_rx_los_all"
|
||||
#define MODULE_RXLOS_ALL_ATTR_CPLD3 "/sys/bus/i2c/devices/0-0062/module_rx_los_all"
|
||||
|
||||
static int front_port_bus_index(int port)
|
||||
{
|
||||
int rport = 0;
|
||||
|
||||
@@ -63,38 +67,6 @@ static int front_port_to_cpld_mux_index(int port)
|
||||
return (rport + CPLD_MUX_BUS_START_INDEX);
|
||||
}
|
||||
|
||||
static int
|
||||
as5812_54x_sfp_node_read_int(char *node_path, int *value, int data_len)
|
||||
{
|
||||
int ret = 0;
|
||||
char buf[8] = {0};
|
||||
*value = 0;
|
||||
|
||||
ret = deviceNodeReadString(node_path, buf, sizeof(buf), data_len);
|
||||
|
||||
if (ret == 0) {
|
||||
*value = atoi(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char*
|
||||
as5812_54x_sfp_get_port_path_addr(int port, int addr, char *node_name)
|
||||
{
|
||||
sprintf(sfp_node_path, "/sys/bus/i2c/devices/%d-00%d/%s",
|
||||
front_port_to_cpld_mux_index(port), addr,
|
||||
node_name);
|
||||
return sfp_node_path;
|
||||
}
|
||||
|
||||
static char*
|
||||
as5812_54x_sfp_get_port_path(int port, char *node_name)
|
||||
{
|
||||
return as5812_54x_sfp_get_port_path_addr(port, 50, node_name);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* SFPI Entry Points
|
||||
@@ -203,10 +175,10 @@ onlp_sfpi_is_present(int port)
|
||||
* Return < 0 if error.
|
||||
*/
|
||||
int present;
|
||||
char* path = as5812_54x_sfp_get_port_path(port, "sfp_is_present");
|
||||
|
||||
if (as5812_54x_sfp_node_read_int(path, &present, 1) != 0) {
|
||||
AIM_LOG_INFO("Unable to read present status from port(%d)\r\n", port);
|
||||
int addr = (port < 24) ? 61 : 62;
|
||||
|
||||
if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, addr, (port+1)) < 0) {
|
||||
AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -217,29 +189,35 @@ int
|
||||
onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
|
||||
{
|
||||
uint32_t bytes[7];
|
||||
char* path;
|
||||
FILE* fp;
|
||||
|
||||
path = as5812_54x_sfp_get_port_path(0, "sfp_is_present_all");
|
||||
fp = fopen(path, "r");
|
||||
|
||||
/* Read present status of port 0~23 */
|
||||
fp = fopen(MODULE_PRESENT_ALL_ATTR_CPLD2, "r");
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the sfp_is_present_all device file.");
|
||||
AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD2.");
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
int count = fscanf(fp, "%x %x %x %x %x %x %x",
|
||||
bytes+0,
|
||||
bytes+1,
|
||||
bytes+2,
|
||||
bytes+3,
|
||||
bytes+4,
|
||||
bytes+5,
|
||||
bytes+6
|
||||
);
|
||||
|
||||
int count = fscanf(fp, "%x %x %x", bytes+0, bytes+1, bytes+2);
|
||||
fclose(fp);
|
||||
if(count != AIM_ARRAYSIZE(bytes)) {
|
||||
if(count != 3) {
|
||||
/* Likely a CPLD read timeout. */
|
||||
AIM_LOG_ERROR("Unable to read all fields from the sfp_is_present_all device file.");
|
||||
AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD2.");
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
/* Read present status of port 24~53 */
|
||||
fp = fopen(MODULE_PRESENT_ALL_ATTR_CPLD3, "r");
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD3.");
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
count = fscanf(fp, "%x %x %x %x", bytes+3, bytes+4, bytes+5, bytes+6);
|
||||
fclose(fp);
|
||||
if(count != 4) {
|
||||
/* Likely a CPLD read timeout. */
|
||||
AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD3.");
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -268,33 +246,39 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
|
||||
int
|
||||
onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
|
||||
{
|
||||
uint32_t bytes[7];
|
||||
char* path;
|
||||
uint32_t bytes[6];
|
||||
uint32_t *ptr = bytes;
|
||||
FILE* fp;
|
||||
|
||||
path = as5812_54x_sfp_get_port_path(0, "sfp_rx_los_all");
|
||||
fp = fopen(path, "r");
|
||||
/* Read present status of port 0~23 */
|
||||
int addr, i = 0;
|
||||
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the sfp_rx_los_all device file.");
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
int count = fscanf(fp, "%x %x %x %x %x %x",
|
||||
bytes+0,
|
||||
bytes+1,
|
||||
bytes+2,
|
||||
bytes+3,
|
||||
bytes+4,
|
||||
bytes+5
|
||||
);
|
||||
fclose(fp);
|
||||
if(count != 6) {
|
||||
AIM_LOG_ERROR("Unable to read all fields from the sfp_rx_los_all device file.");
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
for (addr = 61; addr <= 62; addr++) {
|
||||
if (addr == 61) {
|
||||
fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD2, "r");
|
||||
}
|
||||
else {
|
||||
fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD3, "r");
|
||||
}
|
||||
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the module_rx_los_all device file of CPLD(0x%d)", addr);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
int count = fscanf(fp, "%x %x %x", ptr+0, ptr+1, ptr+2);
|
||||
fclose(fp);
|
||||
if(count != 3) {
|
||||
/* Likely a CPLD read timeout. */
|
||||
AIM_LOG_ERROR("Unable to read all fields from the module_rx_los_all device file of CPLD(0x%d)", addr);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
ptr += count;
|
||||
}
|
||||
|
||||
/* Convert to 64 bit integer in port order */
|
||||
int i = 0;
|
||||
i = 0;
|
||||
uint64_t rx_los_all = 0 ;
|
||||
for(i = 5; i >= 0; i--) {
|
||||
rx_los_all <<= 8;
|
||||
@@ -315,18 +299,22 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
|
||||
int
|
||||
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
|
||||
{
|
||||
char* path = as5812_54x_sfp_get_port_path(port, "sfp_eeprom");
|
||||
|
||||
/*
|
||||
* Read the SFP eeprom into data[]
|
||||
*
|
||||
* Return MISSING if SFP is missing.
|
||||
* Return OK if eeprom is read
|
||||
*/
|
||||
int size = 0;
|
||||
memset(data, 0, 256);
|
||||
|
||||
if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) {
|
||||
AIM_LOG_INFO("Unable to read eeprom from port(%d)\r\n", port);
|
||||
if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, front_port_bus_index(port)) != ONLP_STATUS_OK) {
|
||||
AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
if (size != 256) {
|
||||
AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -336,11 +324,26 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])
|
||||
int
|
||||
onlp_sfpi_dom_read(int port, uint8_t data[256])
|
||||
{
|
||||
char* path = as5812_54x_sfp_get_port_path_addr(port, 51, "sfp_eeprom");
|
||||
memset(data, 0, 256);
|
||||
FILE* fp;
|
||||
char file[64] = {0};
|
||||
|
||||
sprintf(file, PORT_EEPROM_FORMAT, front_port_bus_index(port));
|
||||
fp = fopen(file, "r");
|
||||
if(fp == NULL) {
|
||||
AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) {
|
||||
AIM_LOG_INFO("Unable to read eeprom from port(%d)\r\n", port);
|
||||
if (fseek(fp, 256, SEEK_CUR) != 0) {
|
||||
fclose(fp);
|
||||
AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
int ret = fread(data, 1, 256, fp);
|
||||
fclose(fp);
|
||||
if (ret != 256) {
|
||||
AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -350,28 +353,28 @@ onlp_sfpi_dom_read(int port, uint8_t data[256])
|
||||
int
|
||||
onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr)
|
||||
{
|
||||
int bus = front_port_to_cpld_mux_index(port);
|
||||
int bus = front_port_bus_index(port);
|
||||
return onlp_i2c_readb(bus, devaddr, addr, ONLP_I2C_F_FORCE);
|
||||
}
|
||||
|
||||
int
|
||||
onlp_sfpi_dev_writeb(int port, uint8_t devaddr, uint8_t addr, uint8_t value)
|
||||
{
|
||||
int bus = front_port_to_cpld_mux_index(port);
|
||||
int bus = front_port_bus_index(port);
|
||||
return onlp_i2c_writeb(bus, devaddr, addr, value, ONLP_I2C_F_FORCE);
|
||||
}
|
||||
|
||||
int
|
||||
onlp_sfpi_dev_readw(int port, uint8_t devaddr, uint8_t addr)
|
||||
{
|
||||
int bus = front_port_to_cpld_mux_index(port);
|
||||
int bus = front_port_bus_index(port);
|
||||
return onlp_i2c_readw(bus, devaddr, addr, ONLP_I2C_F_FORCE);
|
||||
}
|
||||
|
||||
int
|
||||
onlp_sfpi_dev_writew(int port, uint8_t devaddr, uint8_t addr, uint16_t value)
|
||||
{
|
||||
int bus = front_port_to_cpld_mux_index(port);
|
||||
int bus = front_port_bus_index(port);
|
||||
return onlp_i2c_writew(bus, devaddr, addr, value, ONLP_I2C_F_FORCE);
|
||||
}
|
||||
|
||||
@@ -384,13 +387,13 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
|
||||
return ONLP_STATUS_E_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int addr = (port < 24) ? 61 : 62;
|
||||
|
||||
switch(control)
|
||||
{
|
||||
case ONLP_SFP_CONTROL_TX_DISABLE:
|
||||
{
|
||||
char* path = as5812_54x_sfp_get_port_path(port, "sfp_tx_disable");
|
||||
|
||||
if (deviceNodeWriteInt(path, value, 0) != 0) {
|
||||
if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, addr, (port+1)) < 0) {
|
||||
AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port);
|
||||
rv = ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
@@ -412,19 +415,18 @@ int
|
||||
onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
|
||||
{
|
||||
int rv;
|
||||
char* path = NULL;
|
||||
|
||||
if (port < 0 || port >= 48) {
|
||||
return ONLP_STATUS_E_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int addr = (port < 24) ? 61 : 62;
|
||||
|
||||
switch(control)
|
||||
{
|
||||
case ONLP_SFP_CONTROL_RX_LOS:
|
||||
{
|
||||
path = as5812_54x_sfp_get_port_path(port, "sfp_rx_loss");
|
||||
|
||||
if (as5812_54x_sfp_node_read_int(path, value, 1) != 0) {
|
||||
if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, addr, (port+1)) < 0) {
|
||||
AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port);
|
||||
rv = ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
@@ -436,9 +438,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
|
||||
|
||||
case ONLP_SFP_CONTROL_TX_FAULT:
|
||||
{
|
||||
path = as5812_54x_sfp_get_port_path(port, "sfp_tx_fault");
|
||||
|
||||
if (as5812_54x_sfp_node_read_int(path, value, 1) != 0) {
|
||||
if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, addr, (port+1)) < 0) {
|
||||
AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port);
|
||||
rv = ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
@@ -450,9 +450,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
|
||||
|
||||
case ONLP_SFP_CONTROL_TX_DISABLE:
|
||||
{
|
||||
path = as5812_54x_sfp_get_port_path(port, "sfp_tx_disable");
|
||||
|
||||
if (as5812_54x_sfp_node_read_int(path, value, 0) != 0) {
|
||||
if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, addr, (port+1)) < 0) {
|
||||
AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port);
|
||||
rv = ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,10 @@ class OnlPlatform_x86_64_accton_as5812_54x_r0(OnlPlatformAccton,
|
||||
SYS_OBJECT_ID=".5812.54.1"
|
||||
|
||||
def baseconfig(self):
|
||||
self.insmod('optoe')
|
||||
self.insmod('cpr_4011_4mxx')
|
||||
self.insmod("ym2651y")
|
||||
for m in [ 'cpld', 'fan', 'psu', 'leds', 'sfp' ]:
|
||||
for m in [ 'cpld', 'fan', 'psu', 'leds' ]:
|
||||
self.insmod("x86-64-accton-as5812-54x-%s.ko" % m)
|
||||
|
||||
########### initialize I2C bus 0 ###########
|
||||
@@ -26,16 +27,18 @@ class OnlPlatform_x86_64_accton_as5812_54x_r0(OnlPlatformAccton,
|
||||
)
|
||||
# initialize SFP devices
|
||||
for port in range(1, 49):
|
||||
self.new_i2c_device('as5812_54x_sfp%d' % port, 0x50, port+1)
|
||||
self.new_i2c_device('as5812_54x_sfp%d' % port, 0x51, port+1)
|
||||
self.new_i2c_device('optoe2', 0x50, port+1)
|
||||
subprocess.call('echo port%d > /sys/bus/i2c/devices/%d-0050/port_name' % (port, port+1), shell=True)
|
||||
|
||||
# Initialize QSFP devices
|
||||
self.new_i2c_device('as5812_54x_sfp49', 0x50, 50)
|
||||
self.new_i2c_device('as5812_54x_sfp52', 0x50, 51)
|
||||
self.new_i2c_device('as5812_54x_sfp50', 0x50, 52)
|
||||
self.new_i2c_device('as5812_54x_sfp53', 0x50, 53)
|
||||
self.new_i2c_device('as5812_54x_sfp51', 0x50, 54)
|
||||
self.new_i2c_device('as5812_54x_sfp54', 0x50, 55)
|
||||
for port in range(49, 55):
|
||||
self.new_i2c_device('optoe1', 0x50, port+1)
|
||||
subprocess.call('echo port49 > /sys/bus/i2c/devices/50-0050/port_name', shell=True)
|
||||
subprocess.call('echo port52 > /sys/bus/i2c/devices/51-0050/port_name', shell=True)
|
||||
subprocess.call('echo port50 > /sys/bus/i2c/devices/52-0050/port_name', shell=True)
|
||||
subprocess.call('echo port53 > /sys/bus/i2c/devices/53-0050/port_name', shell=True)
|
||||
subprocess.call('echo port51 > /sys/bus/i2c/devices/54-0050/port_name', shell=True)
|
||||
subprocess.call('echo port54 > /sys/bus/i2c/devices/55-0050/port_name', shell=True)
|
||||
|
||||
########### initialize I2C bus 1 ###########
|
||||
self.new_i2c_devices(
|
||||
|
||||
Reference in New Issue
Block a user