Skip to content
Open
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 @@ -37,6 +37,8 @@
#define I2C_RW_RETRY_COUNT 10
#define I2C_RW_RETRY_INTERVAL 60 /* ms */

#define MAC_PCIE_RESET_DELAY 100 /* ms */

static LIST_HEAD(cpld_client_list);
static struct mutex list_lock;

Expand Down Expand Up @@ -76,7 +78,8 @@ MODULE_DEVICE_TABLE(i2c, as9726_32d_cpld_id);

enum as9726_32d_cpld_sysfs_attributes {
CPLD_VERSION,
BIOS_FLASH_ID,
BIOS_FLASH_ID,
RESET_MAC,
ACCESS,
MODULE_PRESENT_ALL,
MODULE_RXLOS_ALL,
Expand Down Expand Up @@ -210,6 +213,10 @@ static ssize_t show_bios_flash_id(struct device *dev, struct device_attribute *d
static int as9726_32d_cpld_read_internal(struct i2c_client *client, u8 reg);
static int as9726_32d_cpld_write_internal(struct i2c_client *client, u8 reg,
u8 value);
static ssize_t get_reset(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t set_reset(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);

/* transceiver attributes */
#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \
Expand Down Expand Up @@ -247,6 +254,8 @@ static int as9726_32d_cpld_write_internal(struct i2c_client *client, u8 reg,
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
static SENSOR_DEVICE_ATTR(bios_flash_id, S_IRUGO, show_bios_flash_id, NULL, BIOS_FLASH_ID);
static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
static SENSOR_DEVICE_ATTR(reset_mac, S_IRUGO | S_IWUSR, \
get_reset, set_reset, RESET_MAC);

static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, \
NULL, MODULE_PRESENT_ALL);
Expand Down Expand Up @@ -293,6 +302,7 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34);
static struct attribute *as9726_32d_fpga_attributes[] = {
&sensor_dev_attr_version.dev_attr.attr,
&sensor_dev_attr_access.dev_attr.attr,
&sensor_dev_attr_reset_mac.dev_attr.attr,
NULL
};

Expand Down Expand Up @@ -836,6 +846,113 @@ static ssize_t show_bios_flash_id(struct device *dev, struct device_attribute *a
return sprintf(buf, "%d\n", ( ((val >> 2) & 0x1) == 1 ) ? 1 : 2); /*1: master, 2: slave*/
}

static ssize_t get_reset(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 as9726_32d_cpld_data *data = i2c_get_clientdata(client);

int status = 0, val = 0;
u8 reg = 0, mask_mac = 0x80, mask_pcie = 0x10, mask = 0;

switch (attr->index) {
case RESET_MAC:
reg = 0x8;
mask = mask_mac | mask_pcie;
break;
default:
return 0;
}

mutex_lock(&data->update_lock);
status = as9726_32d_cpld_read_internal(client, reg);

if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);

val = ((status & mask) == 0x0) ? 1 : 0;
return sprintf(buf, "%d\n", val);

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

static ssize_t set_reset(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 as9726_32d_cpld_data *data = i2c_get_clientdata(client);
long value;
int status;
u8 reg = 0, mask_mac, mask_pcie = 0;

status = kstrtol(buf, 10, &value);

if (status)
return status;

if (value != 1)
return -EINVAL;

switch (attr->index) {
case RESET_MAC:
reg = 0x8;
mask_mac = 0x80;
mask_pcie = 0x10;

mutex_lock(&data->update_lock);

/* put mac & pcie to low */
status = as9726_32d_cpld_read_internal(client, reg);
if (unlikely(status < 0))
goto exit;

status &= ~(mask_mac | mask_pcie);
status = as9726_32d_cpld_write_internal(client, reg, status);
if (unlikely(status < 0))
goto exit;

/* put mac to high */
status = as9726_32d_cpld_read_internal(client, reg);
if (unlikely(status < 0))
goto exit;

status |= mask_mac;
status = as9726_32d_cpld_write_internal(client, reg, status);
if (unlikely(status < 0))
goto exit;

msleep(MAC_PCIE_RESET_DELAY);

/* put pcie to high */
status = as9726_32d_cpld_read_internal(client, reg);
if (unlikely(status < 0))
goto exit;

status |= mask_pcie;
status = as9726_32d_cpld_write_internal(client, reg, status);
if (unlikely(status < 0))
goto exit;

mutex_unlock(&data->update_lock);
break;

default:
return -EINVAL;
}

return count;

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

/*
* I2C init/probing/exit functions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,32 @@ enum onlp_fan_dir onlp_get_fan_dir(void)

return dir;
}

/**
* @brief warm reset for mac
* @param unit_id The warm reset device unit id, should be 0
* @param reset_dev The warm reset device id, should be 1 ~ (WARM_RESET_MAX-1)
* @param ret return value.
*/
int onlp_data_path_reset(uint8_t unit_id, uint8_t reset_dev)
{
int ret = ONLP_STATUS_OK;
char *device_id[] = { NULL, "mac" };
char buf[4] = "1";

if (unit_id != 0 || reset_dev >= WARM_RESET_MAX) {
return ONLP_STATUS_E_PARAM;
}

if (reset_dev == 0) {
return ONLP_STATUS_E_UNSUPPORTED;
}

/* Reset device */
ret = onlp_file_write_str(buf, WARM_RESET_FORMAT, device_id[reset_dev]);
if (ret < 0) {
AIM_LOG_ERROR("Reset device-%d:(%s) failed.", reset_dev, device_id[reset_dev]);
}

return ret;
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#define FAN_NODE(node) FAN_BOARD_PATH#node

#define IDPROM_PATH "/sys/bus/i2c/devices/13-0056/eeprom"
#define WARM_RESET_FORMAT "/sys/bus/i2c/devices/1-0060/reset_mac"

enum onlp_thermal_id
{
Expand Down Expand Up @@ -96,6 +97,11 @@ enum onlp_fan_dir {
FAN_DIR_COUNT,
};

enum reset_dev_type {
WARM_RESET_MAC = 1,
WARM_RESET_MAX
};

enum onlp_fan_dir onlp_get_fan_dir(void);

psu_type_t get_psu_type(int id, char* modelname, int modelname_len);
Expand Down