Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Software for White Rabbit PTP Core
Commits
8b0d60e5
Commit
8b0d60e5
authored
Jul 17, 2012
by
Grzegorz Daniluk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell: sfp add/erase/show commands for handling SFP DB in eeprom
parent
4300100f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
235 additions
and
157 deletions
+235
-157
eeprom.c
dev/eeprom.c
+147
-148
i2c.c
dev/i2c.c
+15
-0
eeprom.h
include/eeprom.h
+14
-5
cmd_sfp.c
shell/cmd_sfp.c
+59
-4
No files found.
dev/eeprom.c
View file @
8b0d60e5
...
...
@@ -10,26 +10,23 @@
* placed also outside the FMC standardized EEPROM structure. The only requirement
* is that it starts with 0xdeadbeef pattern. The structure of SFP section is:
*
* --------------------------------
* | 0xdeadbeef (4B) | count (4B) |
* -------------------------------------------------------------------------------
* | SFP(1) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) |
* -------------------------------------------------------------------------------
* | SFP(2) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) |
* -------------------------------------------------------------------------------
* | (....) | (....) | (....) | (....) |
* -------------------------------------------------------------------------------
* | SFP(count) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) |
* -------------------------------------------------------------------------------
* | checksum (1B) |
* -----------------
* --------------
* | count (4B) |
* --------------------------------------------------------------------------------------------
* | SFP(1) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) | chksum(1B) |
* --------------------------------------------------------------------------------------------
* | SFP(2) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) | chksum(1B) |
* --------------------------------------------------------------------------------------------
* | (....) | (....) | (....) | (....) | (...) |
* --------------------------------------------------------------------------------------------
* | SFP(count) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) | chksum(1B) |
* --------------------------------------------------------------------------------------------
*
* Fields description:
* count - how many SFPs are described in the list (binary)
* SFP(n) part number - SFP PN as read from SFP's EEPROM (e.g. AXGE-1254-0531)
* (16 ascii chars)
* checksum - low order 8 bits of the sum of all bytes starting from
* _count_ (without 0xdeadbeef)
* checksum - low order 8 bits of the sum of all bytes for the SFP(PN,alpha,dTx,dRx)
*
*/
...
...
@@ -61,89 +58,91 @@ int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf,
return
size
;
}
//
int eeprom_write(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
//
{
//
int i, busy;
//
//
for(i=0;i<size;i++)
//
{
//
mi2c_start(i2cif);
//
//
if(mi2c_put_byte(i2cif, i2c_addr << 1) < 0)
//
{
//
mi2c_stop(i2cif);
//
return -1;
//
}
//
mi2c_put_byte(i2cif, (offset >> 8) & 0xff);
//
mi2c_put_byte(i2cif, offset & 0xff);
//
mi2c_put_byte(i2cif, *buf++);
//
offset++;
//
mi2c_stop(i2cif);
//
//
do /* wait until the chip becomes ready */
//
{
//
mi2c_start(i2cif);
//
busy = mi2c_put_byte(i2cif, i2c_addr << 1);
//
mi2c_stop(i2cif);
//
} while(busy);
//
//
}
//
return size;
//
}
int
eeprom_write
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
uint32_t
offset
,
uint8_t
*
buf
,
size_t
size
)
{
int
i
,
busy
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
mi2c_start
(
i2cif
);
if
(
mi2c_put_byte
(
i2cif
,
i2c_addr
<<
1
)
<
0
)
{
mi2c_stop
(
i2cif
);
return
-
1
;
}
mi2c_put_byte
(
i2cif
,
(
offset
>>
8
)
&
0xff
);
mi2c_put_byte
(
i2cif
,
offset
&
0xff
);
mi2c_put_byte
(
i2cif
,
*
buf
++
);
offset
++
;
mi2c_stop
(
i2cif
);
do
/* wait until the chip becomes ready */
{
mi2c_start
(
i2cif
);
busy
=
mi2c_put_byte
(
i2cif
,
i2c_addr
<<
1
);
mi2c_stop
(
i2cif
);
}
while
(
busy
);
}
return
size
;
}
int32_t
eeprom_sfpdb_erase
(
uint8_t
i2cif
,
uint8_t
i2c_addr
)
{
uint8_t
sfpcount
=
0
;
int32_t
eeprom_sfp_section
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
size_t
size
,
uint16_t
*
section_sz
)
//just a dummy function that writes '0' to sfp count field of the SFP DB
if
(
eeprom_write
(
i2cif
,
i2c_addr
,
EE_BASE_SFP
,
&
sfpcount
,
sizeof
(
sfpcount
))
!=
sizeof
(
sfpcount
))
return
EE_RET_I2CERR
;
else
return
sfpcount
;
}
int32_t
eeprom_get_sfp
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
struct
s_sfpinfo
*
sfp
,
uint8_t
add
,
uint8_t
pos
)
{
uint8_t
c
,
match
;
uint
16_t
i
;
uint
32_t
sfp_pattern
=
SFP_SECTION_PATTERN
;
static
uint8_t
sfpcount
=
0
;
uint
8_t
i
,
chksum
=
0
;
uint
8_t
*
ptr
;
match
=
0x00
;
*
section_sz
=
0x0000
;
mi2c_start
(
i2cif
);
if
(
mi2c_put_byte
(
i2cif
,
i2c_addr
<<
1
)
!=
0
)
if
(
pos
>=
SFPS_MAX
)
return
EE_RET_POSERR
;
//position in database outside the range
//read how many SFPs are in the database, but only in the first call (pos==0)
if
(
!
pos
&&
eeprom_read
(
i2cif
,
i2c_addr
,
EE_BASE_SFP
,
&
sfpcount
,
sizeof
(
sfpcount
))
!=
sizeof
(
sfpcount
)
)
return
EE_RET_I2CERR
;
if
(
add
&&
sfpcount
==
SFPS_MAX
)
//no more space in the database to add new SFPs
return
EE_RET_DBFULL
;
else
if
(
!
pos
&&
!
add
&&
sfpcount
==
0
)
//there are no SFPs in the database to read
return
sfpcount
;
if
(
!
add
)
{
mi2c_stop
(
i2cif
);
return
-
1
;
if
(
eeprom_read
(
i2cif
,
i2c_addr
,
EE_BASE_SFP
+
sizeof
(
sfpcount
)
+
pos
*
sizeof
(
struct
s_sfpinfo
),
sfp
,
sizeof
(
struct
s_sfpinfo
))
!=
sizeof
(
struct
s_sfpinfo
)
)
return
EE_RET_I2CERR
;
ptr
=
(
uint8_t
*
)
sfp
;
for
(
i
=
0
;
i
<
sizeof
(
struct
s_sfpinfo
)
-
1
;
++
i
)
//'-1' because we do not include chksum in computation
chksum
=
(
uint8_t
)
((
uint16_t
)
chksum
+
*
(
ptr
++
))
&
0xff
;
if
(
chksum
!=
sfp
->
chksum
)
EE_RET_CHKSUM
;
}
mi2c_put_byte
(
i2cif
,
0x00
);
mi2c_put_byte
(
i2cif
,
0x00
);
mi2c_repeat_start
(
i2cif
);
mi2c_put_byte
(
i2cif
,
(
i2c_addr
<<
1
)
|
1
);
for
(
i
=
0
;
i
<
size
-
1
;
++
i
)
else
{
mi2c_get_byte
(
i2cif
,
&
c
,
0
);
if
(
match
==
0x0f
)
{
*
section_sz
=
((
uint16_t
)
c
)
<<
8
;
match
|=
0x10
;
}
else
if
(
match
==
0x1f
)
{
*
section_sz
|=
((
uint16_t
)
c
)
&
0xff
;
match
|=
0x20
;
}
else
if
(
c
==
(
uint8_t
)(
sfp_pattern
>>
24
)
)
match
=
0x01
;
else
if
(
c
==
(
uint8_t
)((
sfp_pattern
>>
16
)
&
0xff
)
)
match
|=
0x02
;
else
if
(
c
==
(
uint8_t
)((
sfp_pattern
>>
8
)
&
0xff
)
)
match
|=
0x04
;
else
if
(
c
==
(
uint8_t
)(
sfp_pattern
&
0xff
)
)
match
|=
0x08
;
else
match
=
0x00
;
if
(
match
==
0x3f
)
{
mi2c_get_byte
(
i2cif
,
&
c
,
1
);
mi2c_stop
(
i2cif
);
return
i
+
1
;
//first address of first SFP in the list
}
/*count checksum*/
ptr
=
(
uint8_t
*
)
sfp
;
for
(
i
=
0
;
i
<
sizeof
(
struct
s_sfpinfo
)
-
1
;
++
i
)
//'-1' because we do not include chksum in computation
chksum
=
(
uint8_t
)
((
uint16_t
)
chksum
+
*
(
ptr
++
))
&
0xff
;
sfp
->
chksum
=
chksum
;
/*add SFP at the end of DB*/
eeprom_write
(
i2cif
,
i2c_addr
,
EE_BASE_SFP
+
sizeof
(
sfpcount
)
+
sfpcount
*
sizeof
(
struct
s_sfpinfo
),
sfp
,
sizeof
(
struct
s_sfpinfo
));
sfpcount
++
;
eeprom_write
(
i2cif
,
i2c_addr
,
EE_BASE_SFP
,
&
sfpcount
,
sizeof
(
sfpcount
));
}
mi2c_get_byte
(
i2cif
,
&
c
,
1
);
mi2c_stop
(
i2cif
);
return
0
;
return
sfpcount
;
}
int8_t
eeprom_get_sfpinfo
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
uint32_t
offset
,
struct
s_sfpinfo
*
sfpinfo
,
uint16_t
section_sz
)
...
...
@@ -177,61 +176,61 @@ int8_t eeprom_get_sfpinfo(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, stru
}
}
int8_t
access_eeprom
(
char
*
sfp_pn
,
int32_t
*
alpha
,
int32_t
*
deltaTx
,
int32_t
*
deltaRx
)
{
uint16_t
i
;
uint8_t
j
;
uint16_t
sfp_sz
;
int32_t
sfp_adr
;
struct
s_sfpinfo
sfpinfo
[
SFPINFO
_MAX
];
mi2c_init
(
WRPC_FMC_I2C
);
sfp_adr
=
eeprom_sfp_section
(
WRPC_FMC_I2C
,
FMC_EEPROM_ADR
,
64
*
1024
,
&
sfp_sz
);
if
(
sfp_adr
==
-
1
)
{
mprintf
(
"FMC EEPROM not found
\n
"
);
return
-
1
;
}
else
if
(
sfp_sz
>
SFPINFO_MAX
)
{
//Ooops, there are too many of them, print warning
mprintf
(
"! Warning ! too many SFP entries (%d)
\n
"
,
sfp_sz
);
sfp_sz
=
SFPINFO_MAX
;
}
else
if
(
sfp_sz
==
0
)
{
mprintf
(
"EEPROM: could no find SFP section, staring with defaults
\n
"
);
return
-
1
;
}
mprintf
(
"EEPROM: found SFP section at %d size %d
\n
"
,
(
uint32_t
)
sfp_adr
,
(
uint32_t
)
sfp_sz
);
if
(
eeprom_get_sfpinfo
(
WRPC_FMC_I2C
,
FMC_EEPROM_ADR
,
sfp_adr
,
sfpinfo
,
sfp_sz
))
{
mprintf
(
"EEPROM ERROR
\n
"
);
return
-
1
;
}
for
(
i
=
0
;
i
<
sfp_sz
;
++
i
)
{
for
(
j
=
0
;
j
<
16
;
++
j
)
{
if
(
sfp_pn
[
j
]
!=
sfpinfo
[
i
].
pn
[
j
])
break
;
}
if
(
j
==
16
)
//which means sfp_pn = sfpinfo[i].pn
{
mprintf
(
"match SFP%d: pn="
,
i
+
1
);
for
(
j
=
0
;
j
<
16
;
++
j
)
mprintf
(
"%c"
,
sfpinfo
[
i
].
pn
[
j
]);
//mprintf(" alpha=%x deltaTx=%x deltaRx=%x\n", sfpinfo[i].alpha, sfpinfo[i].deltaTx, sfpinfo[i].deltaRx);
*
alpha
=
sfpinfo
[
i
].
alpha
;
*
deltaTx
=
sfpinfo
[
i
].
deltaTx
;
*
deltaRx
=
sfpinfo
[
i
].
deltaRx
;
}
}
return
0
;
}
//
int8_t access_eeprom(char *sfp_pn, int32_t *alpha, int32_t *deltaTx, int32_t *deltaRx)
//
{
//
uint16_t i;
//
uint8_t j;
//
uint16_t sfp_sz;
//
int32_t sfp_adr;
// struct s_sfpinfo sfpinfo[SFPS
_MAX];
//
//
mi2c_init(WRPC_FMC_I2C);
//
//
sfp_adr = eeprom_sfp_section(WRPC_FMC_I2C, FMC_EEPROM_ADR, 64*1024, &sfp_sz);
//
if(sfp_adr == -1)
//
{
//
mprintf("FMC EEPROM not found\n");
//
return -1;
//
}
//
else if(sfp_sz > SFPINFO_MAX)
//
{
//
//Ooops, there are too many of them, print warning
//
mprintf("! Warning ! too many SFP entries (%d)\n", sfp_sz);
//
sfp_sz = SFPINFO_MAX;
//
}
//
else if(sfp_sz == 0)
//
{
//
mprintf("EEPROM: could no find SFP section, staring with defaults\n");
//
return -1;
//
}
//
mprintf("EEPROM: found SFP section at %d size %d\n", (uint32_t)sfp_adr, (uint32_t)sfp_sz);
//
//
if( eeprom_get_sfpinfo(WRPC_FMC_I2C, FMC_EEPROM_ADR, sfp_adr, sfpinfo, sfp_sz))
//
{
//
mprintf("EEPROM ERROR\n");
//
return -1;
//
}
//
//
for(i=0; i<sfp_sz; ++i)
//
{
//
for(j=0; j<16; ++j)
//
{
//
if(sfp_pn[j] != sfpinfo[i].pn[j])
//
break;
//
}
//
//
if( j==16 ) //which means sfp_pn = sfpinfo[i].pn
//
{
//
mprintf("match SFP%d: pn=", i+1);
//
for(j=0; j<16; ++j)
//
mprintf("%c", sfpinfo[i].pn[j]);
//
//mprintf(" alpha=%x deltaTx=%x deltaRx=%x\n", sfpinfo[i].alpha, sfpinfo[i].deltaTx, sfpinfo[i].deltaRx);
//
//
*alpha = sfpinfo[i].alpha;
//
*deltaTx = sfpinfo[i].deltaTx;
//
*deltaRx = sfpinfo[i].deltaRx;
//
}
//
}
//
//
return 0;
//
}
dev/i2c.c
View file @
8b0d60e5
...
...
@@ -97,3 +97,18 @@ void mi2c_init(uint8_t i2cif)
M_SCL_OUT
(
i2cif
,
1
);
M_SDA_OUT
(
i2cif
,
1
);
}
//void mi2c_scan(uint8_t i2cif)
//{
// int i;
//
// //for(i=0;i<0x80;i++)
// for(i=0x50;i<0x51;i++)
// {
// mi2c_start(i2cif);
// if(!mi2c_put_byte(i2cif, i<<1)) mprintf("found : %x\n", i);
// mi2c_stop(i2cif);
//
// }
// mprintf("Nothing more found...\n");
//}
include/eeprom.h
View file @
8b0d60e5
...
...
@@ -2,20 +2,29 @@
#define __EEPROM_H
#define SFP_SECTION_PATTERN 0xdeadbeef
#define SFPINFO_MAX 4
#define SFPS_MAX 4
#define EE_BASE_SFP 4*1024
#define EE_BASE_INIT 4*1024+SFPS_MAX*29
__attribute__
((
packed
))
struct
s_sfpinfo
#define EE_RET_I2CERR -1
#define EE_RET_DBFULL -2
#define EE_RET_CHKSUM -3
#define EE_RET_POSERR -4
struct
s_sfpinfo
{
char
pn
[
16
];
int32_t
alpha
;
int32_t
deltaTx
;
int32_t
deltaRx
;
};
int32_t
dTx
;
int32_t
dRx
;
uint8_t
chksum
;
}
__attribute__
((
__packed__
));
int
eeprom_read
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
uint32_t
offset
,
uint8_t
*
buf
,
size_t
size
);
int
eeprom_write
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
uint32_t
offset
,
uint8_t
*
buf
,
size_t
size
);
int32_t
eeprom_sfpdb_erase
(
uint8_t
i2cif
,
uint8_t
i2c_addr
);
int32_t
eeprom_sfp_section
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
size_t
size
,
uint16_t
*
section_sz
);
int8_t
eeprom_get_sfpinfo
(
uint8_t
i2cif
,
uint8_t
i2c_addr
,
uint32_t
offset
,
struct
s_sfpinfo
*
sfpinfo
,
uint16_t
section_sz
);
int8_t
access_eeprom
(
char
*
sfp_pn
,
int32_t
*
alpha
,
int32_t
*
deltaTx
,
int32_t
*
deltaRx
);
...
...
shell/cmd_sfp.c
View file @
8b0d60e5
...
...
@@ -6,15 +6,21 @@
Subcommands:
add vendor_type delta_tx delta_rx alpha - adds an SFP to the database, with given alpha/delta_rx/delta_rx values
show - shows the SFP database
erase - cleans the SFP database
detect - detects the transceiver type
*/
#include "shell.h"
#include "eeprom.h"
#include "syscon.h"
#include "sfp.h"
int
cmd_sfp
(
const
char
*
args
[])
{
int8_t
sfpcount
=
1
,
i
,
temp
;
struct
s_sfpinfo
sfp
;
if
(
args
[
0
]
&&
!
strcasecmp
(
args
[
0
],
"detect"
))
{
char
pn
[
17
];
...
...
@@ -25,11 +31,60 @@ int cmd_sfp(const char *args[])
pn
[
16
]
=
0
;
mprintf
(
"%s
\n
"
,
pn
);
return
0
;
}
else
if
(
args
[
3
]
&&
!
strcasecmp
(
args
[
0
],
"add"
))
}
// else if (!strcasecmp(args[0], "i2cscan"))
// {
// mi2c_scan(WRPC_FMC_I2C);
// return 0;
// }
else
if
(
!
strcasecmp
(
args
[
0
],
"erase"
))
{
if
(
eeprom_sfpdb_erase
(
WRPC_FMC_I2C
,
FMC_EEPROM_ADR
)
==
EE_RET_I2CERR
)
mprintf
(
"Could not erase DB
\n
"
);
}
else
if
(
args
[
4
]
&&
!
strcasecmp
(
args
[
0
],
"add"
))
{
if
(
strlen
(
args
[
1
]
)
>
16
)
temp
=
16
;
else
temp
=
strlen
(
args
[
1
]
);
for
(
i
=
0
;
i
<
temp
;
++
i
)
sfp
.
pn
[
i
]
=
args
[
1
][
i
];
while
(
i
<
16
)
sfp
.
pn
[
i
++
]
=
' '
;
//padding
sfp
.
dTx
=
atoi
(
args
[
2
]);
sfp
.
dRx
=
atoi
(
args
[
3
]);
sfp
.
alpha
=
atoi
(
args
[
4
]);
temp
=
eeprom_get_sfp
(
WRPC_FMC_I2C
,
FMC_EEPROM_ADR
,
&
sfp
,
1
,
0
);
if
(
temp
==
EE_RET_DBFULL
)
mprintf
(
"SFP DB is full
\n
"
);
else
if
(
temp
==
EE_RET_I2CERR
)
mprintf
(
"I2C error
\n
"
);
else
mprintf
(
"%d SFPs in DB
\n
"
,
temp
);
}
else
if
(
args
[
0
]
&&
!
strcasecmp
(
args
[
0
],
"show"
))
{
for
(
i
=
0
;
i
<
sfpcount
;
++
i
)
{
temp
=
eeprom_get_sfp
(
WRPC_FMC_I2C
,
FMC_EEPROM_ADR
,
&
sfp
,
0
,
i
);
if
(
!
i
)
{
sfpcount
=
temp
;
//only in first round valid sfpcount is returned from eeprom_get_sfp
if
(
sfpcount
==
0
||
sfpcount
==
0xFF
)
{
mprintf
(
"SFP database empty...
\n
"
);
return
0
;
}
else
if
(
sfpcount
==
-
1
)
{
mprintf
(
"SFP database corrupted...
\n
"
);
return
0
;
}
}
mprintf
(
"%d: PN:"
,
i
+
1
);
for
(
temp
=
0
;
temp
<
16
;
++
temp
)
mprintf
(
"%c"
,
sfp
.
pn
[
temp
]);
mprintf
(
" dTx: %d, dRx: %d, alpha: %d
\n
"
,
sfp
.
dTx
,
sfp
.
dRx
,
sfp
.
alpha
);
}
}
return
0
;
}
\ No newline at end of file
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment