Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ MODULE_DEVICE_TABLE(i2c, as5912_54x_cpld_id);
#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index
#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 TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index

enum as5912_54x_cpld1_sysfs_attributes {
CPLD_VERSION,
Expand Down Expand Up @@ -272,6 +274,18 @@ enum as5912_54x_cpld1_sysfs_attributes {
TRANSCEIVER_TXFAULT_ATTR_ID(46),
TRANSCEIVER_TXFAULT_ATTR_ID(47),
TRANSCEIVER_TXFAULT_ATTR_ID(48),
TRANSCEIVER_RESET_ATTR_ID(49),
TRANSCEIVER_RESET_ATTR_ID(50),
TRANSCEIVER_RESET_ATTR_ID(51),
TRANSCEIVER_RESET_ATTR_ID(52),
TRANSCEIVER_RESET_ATTR_ID(53),
TRANSCEIVER_RESET_ATTR_ID(54),
TRANSCEIVER_LPMODE_ATTR_ID(49),
TRANSCEIVER_LPMODE_ATTR_ID(50),
TRANSCEIVER_LPMODE_ATTR_ID(51),
TRANSCEIVER_LPMODE_ATTR_ID(52),
TRANSCEIVER_LPMODE_ATTR_ID(53),
TRANSCEIVER_LPMODE_ATTR_ID(54),
};

/* sysfs attributes for hwmon
Expand All @@ -284,6 +298,8 @@ static ssize_t show_rxlos_all(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);
static ssize_t set_qsfp_control(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t show_version(struct device *dev, struct device_attribute *da,
Expand All @@ -305,6 +321,13 @@ static int as5912_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8
&sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \
&sensor_dev_attr_module_tx_fault_##index.dev_attr.attr

#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \
static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, show_status, set_qsfp_control, MODULE_RESET_##index); \
static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IRUGO | S_IWUSR, show_status, set_qsfp_control, MODULE_LPMODE_##index);
#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \
&sensor_dev_attr_module_reset_##index.dev_attr.attr, \
&sensor_dev_attr_module_lpmode_##index.dev_attr.attr

static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
/* transceiver attributes */
Expand Down Expand Up @@ -414,6 +437,13 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46);
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47);
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48);

DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54);

static struct attribute *as5912_54x_cpld1_attributes[] = {
&sensor_dev_attr_version.dev_attr.attr,
&sensor_dev_attr_access.dev_attr.attr,
Expand Down Expand Up @@ -535,6 +565,12 @@ static struct attribute *as5912_54x_cpld2_attributes[] = {
DECLARE_SFP_TRANSCEIVER_ATTR(46),
DECLARE_SFP_TRANSCEIVER_ATTR(47),
DECLARE_SFP_TRANSCEIVER_ATTR(48),
DECLARE_QSFP_TRANSCEIVER_ATTR(49),
DECLARE_QSFP_TRANSCEIVER_ATTR(50),
DECLARE_QSFP_TRANSCEIVER_ATTR(51),
DECLARE_QSFP_TRANSCEIVER_ATTR(52),
DECLARE_QSFP_TRANSCEIVER_ATTR(53),
DECLARE_QSFP_TRANSCEIVER_ATTR(54),
NULL
};

Expand Down Expand Up @@ -725,6 +761,15 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
reg = 0x34;
mask = 0x1 << (attr->index - MODULE_RXLOS_41);
break;
case MODULE_RESET_49 ... MODULE_RESET_54:
revert = 1;
reg = 0x53;
mask = 0x1 << (attr->index - MODULE_RESET_49);
break;
case MODULE_LPMODE_49 ... MODULE_LPMODE_54:
reg = 0x54;
mask = 0x1 << (attr->index - MODULE_LPMODE_49);
break;
default:
return 0;
}
Expand Down Expand Up @@ -819,6 +864,73 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
return status;
}

static ssize_t set_qsfp_control(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct as5912_54x_cpld_data *data = i2c_get_clientdata(client);
long value;
int status;
u8 reg = 0, mask = 0, invert = 0;

status = kstrtol(buf, 10, &value);
if (status) {
return status;
}

switch (attr->index) {
case MODULE_RESET_49 ... MODULE_RESET_54:
invert = 1;
reg = 0x53;
mask = 0x1 << (attr->index - MODULE_RESET_49);
break;
case MODULE_LPMODE_49 ... MODULE_LPMODE_54:
reg = 0x54;
mask = 0x1 << (attr->index - MODULE_LPMODE_49);
break;
default:
return 0;
}

/* Read current status */
mutex_lock(&data->update_lock);
status = as5912_54x_cpld_read_internal(client, reg);
if (unlikely(status < 0)) {
goto exit;
}

/* Update qsfp status */
if (invert)
{
if (value)
status &= ~mask;
else
status |= mask;
}
else
{
if (value) {
status |= mask;
}
else {
status &= ~mask;
}
}

status = as5912_54x_cpld_write_internal(client, reg, status);
if (unlikely(status < 0)) {
goto exit;
}

mutex_unlock(&data->update_lock);
return count;

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

static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,25 @@
#define MODULE_RXLOS_FORMAT "/sys/bus/i2c/devices/%d-00%d/module_rx_los_%d"
#define MODULE_TXFAULT_FORMAT "/sys/bus/i2c/devices/%d-00%d/module_tx_fault_%d"
#define MODULE_TXDISABLE_FORMAT "/sys/bus/i2c/devices/%d-00%d/module_tx_disable_%d"
#define MODULE_RESET_FORMAT "/sys/bus/i2c/devices/%d-00%d/module_reset_%d"
#define MODULE_LPMODE_FORMAT "/sys/bus/i2c/devices/%d-00%d/module_lpmode_%d"
#define MODULE_PRESENT_ALL_ATTR "/sys/bus/i2c/devices/%d-00%d/module_present_all"
#define MODULE_RXLOS_ALL_ATTR_CPLD1 "/sys/bus/i2c/devices/4-0060/module_rx_los_all"
#define MODULE_RXLOS_ALL_ATTR_CPLD2 "/sys/bus/i2c/devices/5-0062/module_rx_los_all"

#define PORT_MAX_NUM 54
#define VALIDATE_SFP(_port) \
do { \
if (_port < 0 || _port >= 48) \
return ONLP_STATUS_E_UNSUPPORTED; \
} while(0)

#define VALIDATE_QSFP(_port) \
do { \
if (_port < 48 || _port >= PORT_MAX_NUM) \
return ONLP_STATUS_E_UNSUPPORTED; \
} while(0)

/************************************************************
*
* SFPI Entry Points
Expand Down Expand Up @@ -291,7 +306,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
{
int rv;

if (port < 0 || port >= 48) {
if (port < 0 || port >= PORT_MAX_NUM) {
return ONLP_STATUS_E_UNSUPPORTED;
}

Expand All @@ -302,6 +317,8 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
{
case ONLP_SFP_CONTROL_TX_DISABLE:
{
VALIDATE_SFP(port);

if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
Expand All @@ -312,6 +329,34 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
break;
}

case ONLP_SFP_CONTROL_RESET:
{
VALIDATE_QSFP(port);

if (onlp_file_write_int(value, MODULE_RESET_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to set reset status to port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
}
else {
rv = ONLP_STATUS_OK;
}
break;
}

case ONLP_SFP_CONTROL_LP_MODE:
{
VALIDATE_QSFP(port);

if (onlp_file_write_int(value, MODULE_LPMODE_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to set lpmode status to port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
}
else {
rv = ONLP_STATUS_OK;
}
break;
}

default:
rv = ONLP_STATUS_E_UNSUPPORTED;
break;
Expand All @@ -325,7 +370,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
{
int rv;

if (port < 0 || port >= 48) {
if (port < 0 || port >= PORT_MAX_NUM) {
return ONLP_STATUS_E_UNSUPPORTED;
}

Expand All @@ -336,6 +381,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
{
case ONLP_SFP_CONTROL_RX_LOS:
{
VALIDATE_SFP(port);

if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
Expand All @@ -348,6 +395,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)

case ONLP_SFP_CONTROL_TX_FAULT:
{
VALIDATE_SFP(port);

if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
Expand All @@ -360,6 +409,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)

case ONLP_SFP_CONTROL_TX_DISABLE:
{
VALIDATE_SFP(port);

if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
Expand All @@ -370,6 +421,34 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
break;
}

case ONLP_SFP_CONTROL_RESET:
{
VALIDATE_QSFP(port);

if (onlp_file_read_int(value, MODULE_RESET_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
}
else {
rv = ONLP_STATUS_OK;
}
break;
}

case ONLP_SFP_CONTROL_LP_MODE:
{
VALIDATE_QSFP(port);

if (onlp_file_read_int(value, MODULE_LPMODE_FORMAT, bus, addr, (port+1)) < 0) {
AIM_LOG_ERROR("Unable to read lpmode status from port(%d)\r\n", port);
rv = ONLP_STATUS_E_INTERNAL;
}
else {
rv = ONLP_STATUS_OK;
}
break;
}

default:
rv = ONLP_STATUS_E_UNSUPPORTED;
}
Expand Down