Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Software for White Rabbit PTP Core
Manage
Activity
Members
Labels
Plan
Issues
39
Issue boards
Milestones
Wiki
Code
Merge requests
5
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Projects
Software for White Rabbit PTP Core
Commits
8b0d60e5
Commit
8b0d60e5
authored
12 years ago
by
Grzegorz Daniluk
Browse files
Options
Downloads
Patches
Plain Diff
shell: sfp add/erase/show commands for handling SFP DB in eeprom
parent
4300100f
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
dev/eeprom.c
+147
-148
147 additions, 148 deletions
dev/eeprom.c
dev/i2c.c
+15
-0
15 additions, 0 deletions
dev/i2c.c
include/eeprom.h
+14
-5
14 additions, 5 deletions
include/eeprom.h
shell/cmd_sfp.c
+59
-4
59 additions, 4 deletions
shell/cmd_sfp.c
with
235 additions
and
157 deletions
dev/eeprom.c
+
147
−
148
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
[
SFP
INFO
_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[SFP
S
_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;
//
}
This diff is collapsed.
Click to expand it.
dev/i2c.c
+
15
−
0
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");
//}
This diff is collapsed.
Click to expand it.
include/eeprom.h
+
14
−
5
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
);
...
...
This diff is collapsed.
Click to expand it.
shell/cmd_sfp.c
+
59
−
4
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
}
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment