Valiadate the SFP bitmaps, present and rx_los.

Signed-off-by: roy_lee <roy_lee@accton.com>
This commit is contained in:
roy_lee
2018-03-28 11:32:17 +08:00
parent 2ce2ba37cc
commit a27f118fcc
2 changed files with 138 additions and 83 deletions

View File

@@ -581,74 +581,138 @@ static const struct attribute_group as7326_56x_cpld1_group = {
.attrs = as7326_56x_cpld1_attributes,
};
/*Split a number into bytes and insert blank between any 2 of bytes.*/
static int string_byte_sep(char *out, int bits, u64 bytes)
{
int i;
char sb[8];
if (!out)
return -EINVAL;
out[0] = 0;
for (i = 0; i < ((bits+7)/8); i++) {
sprintf(sb, "%02llx ", (bytes>>(i*8))&0xff);
strncat(out, sb, strlen(sb));
}
out[strlen(out)-1] = 0;
return 0;
}
static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
char *buf)
{
int i, status;
u8 values[4] = {0};
u8 regs[] = {0x9, 0xA, 0xB, 0x18};
struct i2c_client *client = to_i2c_client(dev);
struct as7326_56x_cpld_data *data = i2c_get_clientdata(client);
int i, status;
u64 values = 0, num;
struct i2c_client *client = to_i2c_client(dev);
struct as7326_56x_cpld_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
status = as7326_56x_cpld_read_internal(client, regs[i]);
if (status < 0) {
goto exit;
}
values[i] = ~(u8)status;
}
mutex_unlock(&data->update_lock);
/* Return values 1 -> 56 in order */
if (data->type == as7326_56x_cpld2) {
values[3] &= 0xF;
}
else { /* as7326_56x_cpld3 */
values[3] &= 0x3;
}
u8 byte;
u8 regs[] = {0x0F, 0x10, 0x11, 0x12};
return sprintf(buf, "%.2x %.2x %.2x %.2x\n",
values[0], values[1], values[2], values[3]);
mutex_lock(&data->update_lock);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
status = as7326_56x_cpld_read_internal(client, regs[i]);
if (status < 0) {
goto exit;
}
byte= (u64)status;
byte= ~byte;
values |= (byte)<<(i*8);
}
mutex_unlock(&data->update_lock);
/* Return values for port 1~30 in order */
num = 30;
values &= (1<<num)-1;
}
else { /* as7326_56x_cpld1 */
u8 regs[] = {0x10, 0x11, 0x12, 0x13};
u8 bytes[4] = {0};
mutex_lock(&data->update_lock);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
status = as7326_56x_cpld_read_internal(client, regs[i]);
if (status < 0) {
goto exit;
}
bytes[i] = (u8)status;
bytes[i] = ~bytes[i];
}
mutex_unlock(&data->update_lock);
/* Return values of port 31 -> 58 in order */
values = bytes[0] | (bytes[1]<<8) | ((bytes[2]&0x3)<<16) | ((bytes[3])<<18) |
(((bytes[2]&0xC) >> 2)<<26);
num = 28;
values &= (1<<num)-1;
}
string_byte_sep(buf, num, values);
return sprintf(buf, "%s", buf);
exit:
mutex_unlock(&data->update_lock);
return status;
mutex_unlock(&data->update_lock);
return status;
}
static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
char *buf)
{
int i, status;
u8 values[3] = {0};
u8 regs[] = {0x12, 0x13, 0x14};
struct i2c_client *client = to_i2c_client(dev);
struct as7326_56x_cpld_data *data = i2c_get_clientdata(client);
int i, status;
u64 values = 0, num;
struct i2c_client *client = to_i2c_client(dev);
struct as7326_56x_cpld_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
if (data->type == as7326_56x_cpld2) {
u8 byte;
u8 regs[] = {0x0B, 0x0C, 0x0D, 0x0E};
for (i = 0; i < ARRAY_SIZE(regs); i++) {
status = as7326_56x_cpld_read_internal(client, regs[i]);
mutex_lock(&data->update_lock);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
status = as7326_56x_cpld_read_internal(client, regs[i]);
if (status < 0) {
goto exit;
if (status < 0) {
goto exit;
}
byte= (u64)status;
values |= (byte)<<(i*8);
}
mutex_unlock(&data->update_lock);
/* Return values for port 1~30 in order */
num = 30;
values &= (1<<num)-1;
values[i] = (u8)status;
}
else { /* as7326_56x_cpld1 */
u8 regs[] = {0x17, 0x18, 0x19};
u8 bytes[4] = {0};
mutex_unlock(&data->update_lock);
mutex_lock(&data->update_lock);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
status = as7326_56x_cpld_read_internal(client, regs[i]);
if (status < 0) {
goto exit;
}
bytes[i] = (u8)status;
}
mutex_unlock(&data->update_lock);
/* Return values 1 -> 24 in order */
return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]);
/* Return values of port 31 -> 58 in order */
values = bytes[0] | (bytes[1]<<8) | ((bytes[2]&0x3)<<16) |
(((bytes[2]&0xC) >> 2)<<26);
num = 28;
values &= (1<<num)-1;
}
string_byte_sep(buf, num, values);
return sprintf(buf, "%s", buf);
exit:
mutex_unlock(&data->update_lock);
return status;
mutex_unlock(&data->update_lock);
return status;
}
static ssize_t show_status(struct device *dev, struct device_attribute *da,

View File

@@ -103,11 +103,12 @@ onlp_sfpi_is_present(int port)
int
onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
{
uint32_t bytes[8], *ptr = NULL;
uint8_t bytes[8];
uint32_t *words[2];
FILE* fp;
int addr;
ptr = bytes;
int addr, i;
uint8_t *ptr = bytes;
unsigned long long presence_all = 0, per_cpld;
for (addr = 62; addr >= 60; addr-=2) {
/* Read present status of port 0~53 */
@@ -121,7 +122,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
return ONLP_STATUS_E_INTERNAL;
}
int count = fscanf(fp, "%x %x %x %x", ptr+0, ptr+1, ptr+2, ptr+3);
int count = fscanf(fp, "%hhx %hhx %hhx %hhx", ptr+0, ptr+1, ptr+2, ptr+3);
fclose(fp);
if(count != 4) {
/* Likely a CPLD read timeout. */
@@ -132,26 +133,14 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
ptr += count;
}
/* Mask out non-existant QSFP ports */
bytes[3] &= 0xF;
bytes[7] &= 0x3;
/*Presumed here are little-endian.*/
words[0] = (uint32_t*)&bytes[0];
words[1] = (uint32_t*)&bytes[4];
/* Convert to 64 bit integer in port order */
int i = 0;
uint64_t presence_all = 0 ;
presence_all |= bytes[7];
presence_all <<= 4;
presence_all |= bytes[3];
for(i = 6; i >= 4; i--) {
presence_all <<= 8;
presence_all |= bytes[i];
}
for(i = 2; i >= 0; i--) {
presence_all <<= 8;
presence_all |= bytes[i];
}
presence_all |= *words[0] & ((1<<30)-1); /*30 port at cpld 2*/
per_cpld = (unsigned long long)(*words[1] & ((1<<28)-1)) << 30; /*28 port at cpld 1*/
presence_all |= per_cpld;
/* Populate bitmap */
for(i = 0; presence_all; i++) {
@@ -165,19 +154,21 @@ 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[6];
uint32_t *ptr = bytes;
uint8_t bytes[8];
uint32_t *words[2];
uint8_t *ptr = bytes;
FILE* fp;
unsigned long long all = 0, per_cpld;
/* Read present status of port 0~23 */
int addr, i = 0;
for (addr = 62; addr >= 60; addr-=2) {
if (addr == 62) {
fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD1, "r");
fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD2, "r");
}
else {
fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD2, "r");
fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD1, "r");
}
if(fp == NULL) {
@@ -185,9 +176,9 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
return ONLP_STATUS_E_INTERNAL;
}
int count = fscanf(fp, "%x %x %x", ptr+0, ptr+1, ptr+2);
int count = fscanf(fp, "%hhx %hhx %hhx %hhx", ptr+0, ptr+1, ptr+2, ptr+3);
fclose(fp);
if(count != 3) {
if(count != 4) {
/* 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;
@@ -195,19 +186,19 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
ptr += count;
}
/*Presumed here are little-endian.*/
words[0] = (uint32_t*)&bytes[0];
words[1] = (uint32_t*)&bytes[4];
/* Convert to 64 bit integer in port order */
i = 0;
uint64_t rx_los_all = 0 ;
for(i = 5; i >= 0; i--) {
rx_los_all <<= 8;
rx_los_all |= bytes[i];
}
all |= *words[0] & ((1<<30)-1); /*30 port at cpld 2*/
per_cpld = (unsigned long long)(*words[1] & ((1<<28)-1)) << 30; /*28 port at cpld 1*/
all |= per_cpld;
/* Populate bitmap */
for(i = 0; rx_los_all; i++) {
AIM_BITMAP_MOD(dst, i, (rx_los_all & 1));
rx_los_all >>= 1;
for(i = 0; all; i++) {
AIM_BITMAP_MOD(dst, i, (all & 1));
all >>= 1;
}
return ONLP_STATUS_OK;