Skip to content

Commit d693ecc

Browse files
committed
[Seastone] fix dx010 qsfp eeprom data write issue
Why I did it test_tx_disable, test_tx_disable_channel, test_power_override failed in dx010. How I did it Add i2c access algorithm for CPLD i2c adapters. How to verify it Verify it with platform_tests/api/test_sfp.py::TestSfpApi test cases. Signed-off-by: Eric Zhu <[email protected]>
1 parent 5a2a959 commit d693ecc

File tree

2 files changed

+174
-34
lines changed
  • device/celestica/x86_64-cel_seastone-r0/sonic_platform
  • platform/broadcom/sonic-platform-modules-cel/dx010/modules

2 files changed

+174
-34
lines changed

device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1520,7 +1520,7 @@ def get_power_override(self):
15201520
if dom_control_raw is not None:
15211521
dom_control_data = sfpd_obj.parse_control_bytes(
15221522
dom_control_raw, 0)
1523-
return ('On' == dom_control_data['data']['PowerOverride'])
1523+
return ('On' == dom_control_data['data']['PowerOverride']['value'])
15241524
else:
15251525
return False
15261526
else:

platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c

+173-33
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* dx010_cpld.c - driver for SeaStone's CPLD
33
*
4-
* Copyright (C) 2017 Celestica Corp.
4+
* Copyright (C) 2023 Celestica Corp.
55
*
66
* This program is free software; you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by
@@ -120,11 +120,11 @@
120120
#define SSRR_ID_BANK2 0x296
121121
#define SSRR_ID_BANK3 0x396
122122

123-
#define HST_CNTL2_QUICK 0x00
124-
#define HST_CNTL2_BYTE 0x01
125-
#define HST_CNTL2_BYTE_DATA 0x02
126-
#define HST_CNTL2_WORD_DATA 0x03
127-
#define HST_CNTL2_BLOCK 0x05
123+
#define SSRR_MASTER_ERR 0x80
124+
#define SSRR_BUS_BUSY 0x40
125+
126+
#define I2C_BAUD_RATE_100K 0x40
127+
128128

129129
struct dx010_i2c_data {
130130
int portid;
@@ -610,6 +610,166 @@ static int i2c_read_eeprom(struct i2c_adapter *a, u16 addr,
610610
return error;
611611
}
612612

613+
614+
/**
615+
* Read/Write eeprom of CPLD connected QSFP device.
616+
* @param a i2c adapter.
617+
* @param addr address to read.
618+
* @param new_data QSFP port number struct.
619+
* @param rw read/write flag
620+
* @param cmd i2c command.
621+
* @param size access size
622+
* @return 0 if not error, else the error code.
623+
*/
624+
static int dx010_cpld_i2c_access(struct i2c_adapter *a, u16 addr,
625+
struct dx010_i2c_data *new_data, char rw,
626+
u8 cmd, int size, union i2c_smbus_data *data)
627+
{
628+
u32 reg;
629+
int ioBase=0;
630+
char byte;
631+
char data_len = 0;
632+
short temp;
633+
short portid, opcode, devaddr, cmdbyte0, ssrr, writedata, readdata;
634+
__u16 word_data;
635+
__u8 byte_data;
636+
int error = -EIO;
637+
638+
mutex_lock(&cpld_data->cpld_lock);
639+
640+
if (((new_data->portid >= PORT_BANK1_START)
641+
&& (new_data->portid <= PORT_BANK1_END))
642+
|| (new_data->portid == PORT_SFPP1)
643+
|| (new_data->portid == PORT_SFPP2))
644+
{
645+
portid = PORT_ID_BANK1;
646+
opcode = OPCODE_ID_BANK1;
647+
devaddr = DEVADDR_ID_BANK1;
648+
cmdbyte0 = CMDBYT_ID_BANK1;
649+
ssrr = SSRR_ID_BANK1;
650+
writedata = WRITE_ID_BANK1;
651+
readdata = READ_ID_BANK1;
652+
}else if ((new_data->portid >= PORT_BANK2_START) && (new_data->portid <= PORT_BANK2_END)){
653+
portid = PORT_ID_BANK2;
654+
opcode = OPCODE_ID_BANK2;
655+
devaddr = DEVADDR_ID_BANK2;
656+
cmdbyte0 = CMDBYT_ID_BANK2;
657+
ssrr = SSRR_ID_BANK2;
658+
writedata = WRITE_ID_BANK2;
659+
readdata = READ_ID_BANK2;
660+
}else if ((new_data->portid >= PORT_BANK3_START) && (new_data->portid <= PORT_BANK3_END)){
661+
portid = PORT_ID_BANK3;
662+
opcode = OPCODE_ID_BANK3;
663+
devaddr = DEVADDR_ID_BANK3;
664+
cmdbyte0 = CMDBYT_ID_BANK3;
665+
ssrr = SSRR_ID_BANK3;
666+
writedata = WRITE_ID_BANK3;
667+
readdata = READ_ID_BANK3;
668+
}else{
669+
/* Invalid parameter! */
670+
error = -EINVAL;
671+
goto exit;
672+
}
673+
674+
if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA)
675+
data_len = 1;
676+
else if (size == I2C_SMBUS_WORD_DATA)
677+
data_len = 2;
678+
else {
679+
error = -EINVAL;
680+
goto exit;
681+
}
682+
683+
while ((inb(ioBase + ssrr) & SSRR_BUS_BUSY));
684+
if ((inb(ioBase + ssrr) & SSRR_MASTER_ERR) == SSRR_MASTER_ERR) {
685+
error = -EIO;
686+
/* Read error reset the port */
687+
outb(0x00, ioBase + ssrr);
688+
udelay(3000);
689+
outb(0x01, ioBase + ssrr);
690+
goto exit;
691+
}
692+
693+
byte = I2C_BAUD_RATE_100K + new_data->portid;
694+
reg = cmd;
695+
outb(byte, ioBase + portid);
696+
outb(reg, ioBase + cmdbyte0);
697+
byte = (data_len << 4) | 0x1;
698+
outb(byte, ioBase + opcode);
699+
addr = addr << 1;
700+
if (rw == I2C_SMBUS_READ)
701+
{
702+
addr |= 0x01;
703+
outb(addr, ioBase + devaddr);
704+
while ((inb(ioBase + ssrr) & SSRR_BUS_BUSY))
705+
{
706+
udelay(100);
707+
}
708+
709+
if ((inb(ioBase + ssrr) & SSRR_MASTER_ERR) == SSRR_MASTER_ERR) {
710+
/* Read error reset the port */
711+
error = -EIO;
712+
outb(0x00, ioBase + ssrr);
713+
udelay(3000);
714+
outb(0x01, ioBase + ssrr);
715+
goto exit;
716+
}
717+
718+
temp = ioBase + readdata;
719+
if (data_len == 1)
720+
{
721+
byte_data = inb(temp);
722+
data->byte = byte_data;
723+
}
724+
else if (data_len == 2)
725+
{
726+
word_data = inb(temp);
727+
word_data |= (inb(++temp) << 8);
728+
data->word = word_data;
729+
}
730+
}
731+
else // do i2c write
732+
{
733+
temp = ioBase + writedata;
734+
if (data_len == 1)
735+
{
736+
byte_data = data->byte;
737+
outb(byte_data, temp);
738+
}
739+
else if (data_len == 2)
740+
{
741+
word_data = data->word;
742+
outb((word_data & 0xff), temp);
743+
outb((word_data >> 4), (++temp));
744+
}
745+
// write dev addr
746+
outb(addr, ioBase + devaddr);
747+
748+
// check bus access status
749+
while ((inb(ioBase + ssrr) & SSRR_BUS_BUSY))
750+
{
751+
udelay(100);
752+
}
753+
754+
if ((inb(ioBase + ssrr) & SSRR_MASTER_ERR) == SSRR_MASTER_ERR) {
755+
/* Read error reset the port */
756+
error = -EIO;
757+
outb(0x00, ioBase + ssrr);
758+
udelay(3000);
759+
outb(0x01, ioBase + ssrr);
760+
goto exit;
761+
}
762+
}
763+
764+
mutex_unlock(&cpld_data->cpld_lock);
765+
return 0;
766+
767+
exit:
768+
mutex_unlock(&cpld_data->cpld_lock);
769+
return error;
770+
}
771+
772+
613773
static int dx010_i2c_access(struct i2c_adapter *a, u16 addr,
614774
unsigned short flags, char rw, u8 cmd,
615775
int size, union i2c_smbus_data *data)
@@ -624,39 +784,19 @@ static int dx010_i2c_access(struct i2c_adapter *a, u16 addr,
624784

625785
/* Map the size to what the chip understands */
626786
switch (size) {
627-
case I2C_SMBUS_QUICK:
628-
size = HST_CNTL2_QUICK;
629-
break;
630787
case I2C_SMBUS_BYTE:
631-
size = HST_CNTL2_BYTE;
632-
break;
633788
case I2C_SMBUS_BYTE_DATA:
634-
size = HST_CNTL2_BYTE_DATA;
635-
break;
636789
case I2C_SMBUS_WORD_DATA:
637-
size = HST_CNTL2_WORD_DATA;
638-
break;
639-
case I2C_SMBUS_BLOCK_DATA:
640-
size = HST_CNTL2_BLOCK;
641-
break;
642-
default:
643-
dev_warn(&a->dev, "Unsupported transaction %d\n", size);
644-
error = -EOPNOTSUPP;
645-
goto Done;
646-
}
647-
648-
switch (size) {
649-
case HST_CNTL2_BYTE: /* Result put in SMBHSTDAT0 */
650-
break;
651-
case HST_CNTL2_BYTE_DATA:
652-
break;
653-
case HST_CNTL2_WORD_DATA:
654-
if( 0 == i2c_read_eeprom(a,addr,new_data,cmd,data)){
790+
if(0 == dx010_cpld_i2c_access(a, addr, new_data, rw, cmd, size, data)){
655791
error = 0;
656792
}else{
657793
error = -EIO;
658794
}
659795
break;
796+
default:
797+
dev_warn(&a->dev, "Unsupported transaction %d\n", size);
798+
error = -EOPNOTSUPP;
799+
goto Done;
660800
}
661801

662802
Done:
@@ -790,6 +930,6 @@ module_init(cel_dx010_lpc_init);
790930
module_exit(cel_dx010_lpc_exit);
791931

792932
MODULE_AUTHOR("Pradchaya P <[email protected]>");
793-
MODULE_VERSION("1.0.1");
933+
MODULE_VERSION("1.0.2");
794934
MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver");
795-
MODULE_LICENSE("GPL");
935+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)