Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
c5977fb9
Commit
c5977fb9
authored
Jan 20, 2024
by
Antoine Kaufmann
Committed by
Antoine Kaufmann
Jun 26, 2024
Browse files
sims/nic/i40e_bm: PTP support (PHC, rx/tx timestamping)
parent
5e4267ae
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
430 additions
and
7 deletions
+430
-7
sims/nic/i40e_bm/headers.h
sims/nic/i40e_bm/headers.h
+34
-0
sims/nic/i40e_bm/i40e_adminq.cc
sims/nic/i40e_bm/i40e_adminq.cc
+1
-1
sims/nic/i40e_bm/i40e_bm.cc
sims/nic/i40e_bm/i40e_bm.cc
+105
-1
sims/nic/i40e_bm/i40e_bm.h
sims/nic/i40e_bm/i40e_bm.h
+47
-1
sims/nic/i40e_bm/i40e_lan.cc
sims/nic/i40e_bm/i40e_lan.cc
+129
-3
sims/nic/i40e_bm/i40e_ptp.cc
sims/nic/i40e_bm/i40e_ptp.cc
+113
-0
sims/nic/i40e_bm/rules.mk
sims/nic/i40e_bm/rules.mk
+1
-1
No files found.
sims/nic/i40e_bm/headers.h
View file @
c5977fb9
...
@@ -35,6 +35,7 @@ namespace headers {
...
@@ -35,6 +35,7 @@ namespace headers {
#define ETH_TYPE_IP 0x0800
#define ETH_TYPE_IP 0x0800
#define ETH_TYPE_ARP 0x0806
#define ETH_TYPE_ARP 0x0806
#define ETH_TYPE_PTP 0x88F7
struct
eth_addr
{
struct
eth_addr
{
uint8_t
addr
[
ETH_ADDR_LEN
];
uint8_t
addr
[
ETH_ADDR_LEN
];
...
@@ -177,6 +178,39 @@ struct udp_hdr {
...
@@ -177,6 +178,39 @@ struct udp_hdr {
uint16_t
chksum
;
uint16_t
chksum
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/******************************************************************************/
/* PTP */
struct
ptp_v1_hdr
{
uint16_t
version_ptp
;
uint16_t
version_network
;
uint8_t
subdomain
;
uint8_t
_rsvd0
[
15
];
uint8_t
msg_type
;
uint8_t
src_comm_tech
;
uint8_t
src_uuid
[
6
];
uint16_t
src_portid
;
uint16_t
seq_id
;
uint8_t
ctrl
;
uint8_t
_rsvd1
;
uint16_t
flags
;
}
__attribute__
((
packed
));
struct
ptp_v2_hdr
{
uint8_t
msg_type
;
uint8_t
version_ptp
;
uint16_t
msg_len
;
uint8_t
subdomain
;
uint8_t
_rsvd0
;
uint16_t
flags
;
uint64_t
correction
;
uint32_t
_rsvd1
;
uint8_t
src_port_id
[
10
];
uint16_t
seq_id
;
uint8_t
ctrl
;
uint8_t
log_msg_period
;
}
__attribute__
((
packed
));
/******************************************************************************/
/******************************************************************************/
/* whole packets */
/* whole packets */
...
...
sims/nic/i40e_bm/i40e_adminq.cc
View file @
c5977fb9
...
@@ -142,7 +142,7 @@ void queue_admin_tx::admin_desc_ctx::process() {
...
@@ -142,7 +142,7 @@ void queue_admin_tx::admin_desc_ctx::process() {
reinterpret_cast
<
struct
i40e_aqc_get_version
*>
(
d
->
params
.
raw
);
reinterpret_cast
<
struct
i40e_aqc_get_version
*>
(
d
->
params
.
raw
);
gv
->
rom_ver
=
0
;
gv
->
rom_ver
=
0
;
gv
->
fw_build
=
0
;
gv
->
fw_build
=
0
;
gv
->
fw_major
=
0
;
gv
->
fw_major
=
6
;
gv
->
fw_minor
=
0
;
gv
->
fw_minor
=
0
;
gv
->
api_major
=
I40E_FW_API_VERSION_MAJOR
;
gv
->
api_major
=
I40E_FW_API_VERSION_MAJOR
;
gv
->
api_minor
=
I40E_FW_API_VERSION_MINOR_X710
;
gv
->
api_minor
=
I40E_FW_API_VERSION_MINOR_X710
;
...
...
sims/nic/i40e_bm/i40e_bm.cc
View file @
c5977fb9
...
@@ -40,7 +40,8 @@ i40e_bm::i40e_bm()
...
@@ -40,7 +40,8 @@ i40e_bm::i40e_bm()
pf_atq
(
*
this
,
regs
.
pf_atqba
,
regs
.
pf_atqlen
,
regs
.
pf_atqh
,
regs
.
pf_atqt
),
pf_atq
(
*
this
,
regs
.
pf_atqba
,
regs
.
pf_atqlen
,
regs
.
pf_atqh
,
regs
.
pf_atqt
),
hmc
(
*
this
),
hmc
(
*
this
),
shram
(
*
this
),
shram
(
*
this
),
lanmgr
(
*
this
,
NUM_QUEUES
)
{
lanmgr
(
*
this
,
NUM_QUEUES
),
ptp
(
*
this
)
{
reset
(
false
);
reset
(
false
);
}
}
...
@@ -425,6 +426,74 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) {
...
@@ -425,6 +426,74 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) {
val
=
regs
.
glrpb_plw
;
val
=
regs
.
glrpb_plw
;
break
;
break
;
case
I40E_PRTTSYN_CTL0
:
val
=
regs
.
prtsyn_ctl_0
;
break
;
case
I40E_PRTTSYN_CTL1
:
val
=
regs
.
prtsyn_ctl_1
;
break
;
case
I40E_PRTTSYN_AUX_0
(
0
):
val
=
regs
.
prtsyn_aux_0
;
break
;
case
I40E_PRTTSYN_STAT_0
:
val
=
regs
.
prtsyn_stat_0
;
regs
.
prtsyn_stat_0
=
0
;
break
;
case
I40E_PRTTSYN_STAT_1
:
val
=
regs
.
prtsyn_stat_1
;
break
;
case
I40E_PRTTSYN_ADJ
:
val
=
ptp
.
adj_get
();
break
;
/* note the latching behavior prescribed by the spec for the L/H paired
registers: driver must read L first, which will latch the current value
for a future consistent read for h. */
case
I40E_PRTTSYN_INC_L
:
regs
.
prtsyn_inc_h
=
(
regs
.
prtsyn_inc
>>
32
);
val
=
regs
.
prtsyn_inc
;
break
;
case
I40E_PRTTSYN_INC_H
:
val
=
regs
.
prtsyn_inc_h
;
break
;
case
I40E_PRTTSYN_TIME_L
:
{
uint64_t
phc
=
ptp
.
phc_read
();
regs
.
prtsyn_time_h
=
(
phc
>>
32
);
val
=
phc
;
break
;
}
case
I40E_PRTTSYN_TIME_H
:
val
=
regs
.
prtsyn_time_h
;
break
;
case
I40E_PRTTSYN_RXTIME_L
(
0
):
/* fallthrough */
case
I40E_PRTTSYN_RXTIME_L
(
1
):
/* fallthrough */
case
I40E_PRTTSYN_RXTIME_L
(
2
):
/* fallthrough */
case
I40E_PRTTSYN_RXTIME_L
(
3
):
{
size_t
i
=
(
addr
-
I40E_PRTTSYN_RXTIME_L
(
0
))
/
(
I40E_PRTTSYN_RXTIME_L
(
1
)
-
I40E_PRTTSYN_RXTIME_L
(
0
));
regs
.
prtsyn_rxtime_h
[
i
]
=
(
regs
.
prtsyn_rxtime
[
i
]
>>
32
);
val
=
regs
.
prtsyn_rxtime
[
i
];
break
;
}
case
I40E_PRTTSYN_RXTIME_H
(
0
):
/* fallthrough */
case
I40E_PRTTSYN_RXTIME_H
(
1
):
/* fallthrough */
case
I40E_PRTTSYN_RXTIME_H
(
2
):
/* fallthrough */
case
I40E_PRTTSYN_RXTIME_H
(
3
):
{
size_t
i
=
(
addr
-
I40E_PRTTSYN_RXTIME_H
(
0
))
/
(
I40E_PRTTSYN_RXTIME_H
(
1
)
-
I40E_PRTTSYN_RXTIME_H
(
0
));
val
=
regs
.
prtsyn_rxtime_h
[
i
];
regs
.
prtsyn_rxtime_lock
[
i
]
=
false
;
regs
.
prtsyn_stat_1
&=
~
(
1
<<
(
I40E_PRTTSYN_STAT_1_RXT0_SHIFT
+
i
));
break
;
}
case
I40E_PRTTSYN_TXTIME_L
:
regs
.
prtsyn_txtime_h
=
(
regs
.
prtsyn_txtime
>>
32
);
val
=
regs
.
prtsyn_txtime
;
break
;
case
I40E_PRTTSYN_TXTIME_H
:
val
=
regs
.
prtsyn_txtime_h
;
break
;
default:
default:
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"unhandled mem read addr="
<<
addr
<<
logger
::
endl
;
log
<<
"unhandled mem read addr="
<<
addr
<<
logger
::
endl
;
...
@@ -640,6 +709,38 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) {
...
@@ -640,6 +709,38 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) {
case
I40E_GLRPB_PLW
:
case
I40E_GLRPB_PLW
:
regs
.
glrpb_plw
=
val
;
regs
.
glrpb_plw
=
val
;
break
;
break
;
case
I40E_PRTTSYN_CTL0
:
regs
.
prtsyn_ctl_0
=
val
;
break
;
case
I40E_PRTTSYN_CTL1
:
regs
.
prtsyn_ctl_1
=
val
;
break
;
case
I40E_PRTTSYN_AUX_0
(
0
):
regs
.
prtsyn_aux_0
=
val
;
break
;
case
I40E_PRTTSYN_ADJ
:
ptp
.
adj_set
(
val
);
break
;
/* note the latching behavior prescribed by the spec for the L/H paired
registers: driver must read L first, which will latch the current value
for a future consistent read for h. */
case
I40E_PRTTSYN_INC_L
:
regs
.
prtsyn_inc_l
=
val
;
break
;
case
I40E_PRTTSYN_INC_H
:
regs
.
prtsyn_inc
=
(((
uint64_t
)
val
)
<<
32
)
|
regs
.
prtsyn_inc_l
;
ptp
.
inc_set
(
regs
.
prtsyn_inc
);
break
;
case
I40E_PRTTSYN_TIME_L
:
{
regs
.
prtsyn_time_l
=
val
;
break
;
}
case
I40E_PRTTSYN_TIME_H
:
ptp
.
phc_write
((((
uint64_t
)
val
)
<<
32
)
|
regs
.
prtsyn_time_l
);
break
;
default:
default:
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"unhandled mem write addr="
<<
addr
<<
" val="
<<
val
log
<<
"unhandled mem write addr="
<<
addr
<<
" val="
<<
val
...
@@ -752,6 +853,9 @@ void i40e_bm::reset(bool indicate_done) {
...
@@ -752,6 +853,9 @@ void i40e_bm::reset(bool indicate_done) {
regs
.
glrpb_ghw
=
0xF2000
;
regs
.
glrpb_ghw
=
0xF2000
;
regs
.
glrpb_phw
=
0x1246
;
regs
.
glrpb_phw
=
0x1246
;
regs
.
glrpb_plw
=
0x0846
;
regs
.
glrpb_plw
=
0x0846
;
regs
.
prtsyn_ctl_1
=
(
1
<<
I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT
)
|
(
1
<<
I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT
);
}
}
shadow_ram
::
shadow_ram
(
i40e_bm
&
dev_
)
:
dev
(
dev_
),
log
(
"sram"
,
dev_
)
{
shadow_ram
::
shadow_ram
(
i40e_bm
&
dev_
)
:
dev
(
dev_
),
log
(
"sram"
,
dev_
)
{
...
...
sims/nic/i40e_bm/i40e_bm.h
View file @
c5977fb9
...
@@ -420,7 +420,8 @@ class lan_queue_rx : public lan_queue_base {
...
@@ -420,7 +420,8 @@ class lan_queue_rx : public lan_queue_base {
public:
public:
explicit
rx_desc_ctx
(
lan_queue_rx
&
queue_
);
explicit
rx_desc_ctx
(
lan_queue_rx
&
queue_
);
virtual
void
process
();
virtual
void
process
();
void
packet_received
(
const
void
*
data
,
size_t
len
,
bool
last
);
void
packet_received
(
const
void
*
data
,
size_t
len
,
bool
last
,
int
rxtime_id
);
};
};
uint16_t
dbuff_size
;
uint16_t
dbuff_size
;
...
@@ -432,6 +433,7 @@ class lan_queue_rx : public lan_queue_base {
...
@@ -432,6 +433,7 @@ class lan_queue_rx : public lan_queue_base {
virtual
void
initialize
();
virtual
void
initialize
();
virtual
desc_ctx
&
desc_ctx_create
();
virtual
desc_ctx
&
desc_ctx_create
();
bool
ptp_rx_sample
(
const
void
*
data
,
size_t
len
);
public:
public:
lan_queue_rx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail
,
size_t
idx
,
uint32_t
&
reg_ena
,
lan_queue_rx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail
,
size_t
idx
,
uint32_t
&
reg_ena
,
...
@@ -483,6 +485,31 @@ class lan {
...
@@ -483,6 +485,31 @@ class lan {
void
packet_received
(
const
void
*
data
,
size_t
len
);
void
packet_received
(
const
void
*
data
,
size_t
len
);
};
};
class
ptpmgr
{
protected:
static
const
uint64_t
CLOCK_HZ
=
625000000
;
i40e_bm
&
dev
;
uint64_t
last_updated
;
__uint128_t
last_val
;
int64_t
offset
;
uint64_t
inc_val
;
bool
adj_neg
;
uint32_t
adj_val
;
uint64_t
update_clock
();
public:
explicit
ptpmgr
(
i40e_bm
&
dev
);
uint64_t
phc_read
();
void
phc_write
(
uint64_t
val
);
uint32_t
adj_get
();
void
adj_set
(
uint32_t
val
);
void
inc_set
(
uint64_t
inc
);
};
class
shadow_ram
{
class
shadow_ram
{
protected:
protected:
i40e_bm
&
dev
;
i40e_bm
&
dev
;
...
@@ -579,6 +606,24 @@ class i40e_bm : public nicbm::Runner::Device {
...
@@ -579,6 +606,24 @@ class i40e_bm : public nicbm::Runner::Device {
uint32_t
glrpb_glw
;
uint32_t
glrpb_glw
;
uint32_t
glrpb_phw
;
uint32_t
glrpb_phw
;
uint32_t
glrpb_plw
;
uint32_t
glrpb_plw
;
uint32_t
prtsyn_ctl_0
;
uint32_t
prtsyn_ctl_1
;
uint32_t
prtsyn_aux_0
;
uint32_t
prtsyn_stat_0
;
uint32_t
prtsyn_stat_1
;
uint64_t
prtsyn_inc
;
uint32_t
prtsyn_inc_l
;
uint32_t
prtsyn_inc_h
;
uint32_t
prtsyn_time_l
;
uint32_t
prtsyn_time_h
;
bool
prtsyn_rxtime_lock
[
4
];
uint64_t
prtsyn_rxtime
[
4
];
uint32_t
prtsyn_rxtime_h
[
4
];
uint64_t
prtsyn_txtime
;
uint32_t
prtsyn_txtime_h
;
};
};
public:
public:
...
@@ -604,6 +649,7 @@ class i40e_bm : public nicbm::Runner::Device {
...
@@ -604,6 +649,7 @@ class i40e_bm : public nicbm::Runner::Device {
host_mem_cache
hmc
;
host_mem_cache
hmc
;
shadow_ram
shram
;
shadow_ram
shram
;
lan
lanmgr
;
lan
lanmgr
;
ptpmgr
ptp
;
int_ev
intevs
[
NUM_PFINTS
];
int_ev
intevs
[
NUM_PFINTS
];
...
...
sims/nic/i40e_bm/i40e_lan.cc
View file @
c5977fb9
...
@@ -305,6 +305,93 @@ queue_base::desc_ctx &lan_queue_rx::desc_ctx_create() {
...
@@ -305,6 +305,93 @@ queue_base::desc_ctx &lan_queue_rx::desc_ctx_create() {
return
*
new
rx_desc_ctx
(
*
this
);
return
*
new
rx_desc_ctx
(
*
this
);
}
}
/* determine if we should sample a ptp rx timestamp for this packet */
bool
lan_queue_rx
::
ptp_rx_sample
(
const
void
*
data
,
size_t
len
)
{
if
(
!
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_TSYNENA_MASK
))
return
false
;
uint8_t
tsyntype
=
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_TSYNTYPE_MASK
)
>>
I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT
;
uint8_t
udp_ena
=
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_UDP_ENA_MASK
)
>>
I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT
;
uint8_t
v1messtype0
=
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK
)
>>
I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT
;
uint8_t
v1messtype1
=
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_V1MESSTYPE1_MASK
)
>>
I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT
;
uint8_t
v2messtype0
=
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK
)
>>
I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT
;
uint8_t
v2messtype1
=
(
dev
.
regs
.
prtsyn_ctl_1
&
I40E_PRTTSYN_CTL1_V2MESSTYPE1_MASK
)
>>
I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT
;
const
headers
::
pkt_udp
*
udp
=
reinterpret_cast
<
const
headers
::
pkt_udp
*>
(
data
);
const
void
*
ptp_start
;
bool
is_udp
=
false
;
// TODO(antoinek): ipv6
if
(
udp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
)
&&
udp
->
ip
.
proto
==
IP_PROTO_UDP
)
{
// no udp packet types enabled
if
(
tsyntype
==
0
)
return
false
;
uint16_t
port
=
ntohs
(
udp
->
udp
.
dest
);
if
(
!
(
port
==
0x013F
&&
(
udp_ena
==
1
||
udp_ena
==
3
))
&&
!
(
port
==
0x0140
&&
(
udp_ena
==
2
||
udp_ena
==
3
)))
return
false
;
is_udp
=
true
;
ptp_start
=
udp
+
1
;
}
else
if
(
udp
->
eth
.
type
==
htons
(
ETH_TYPE_PTP
))
{
if
(
tsyntype
==
1
)
return
false
;
ptp_start
=
&
udp
->
ip
;
}
else
{
return
false
;
}
const
headers
::
ptp_v1_hdr
*
v1
=
reinterpret_cast
<
const
headers
::
ptp_v1_hdr
*>
(
ptp_start
);
const
headers
::
ptp_v2_hdr
*
v2
=
reinterpret_cast
<
const
headers
::
ptp_v2_hdr
*>
(
ptp_start
);
/* handle ptp v1 */
if
(
v1
->
version_ptp
==
1
)
{
/* check if v1 is allowed*/
if
(
tsyntype
!=
1
)
return
false
;
if
(
v1messtype0
==
0xff
||
v1messtype1
==
0xff
)
return
true
;
if
(
v1
->
msg_type
==
v1messtype0
||
v1
->
msg_type
==
v1messtype1
)
return
true
;
return
false
;
}
else
if
(
v2
->
version_ptp
==
2
)
{
/* check if no v1 packets allowed*/
if
(
tsyntype
==
1
)
return
false
;
if
(
tsyntype
==
0
&&
is_udp
)
return
false
;
if
(
tsyntype
==
3
)
return
v2
->
msg_type
<
8
;
if
(
v2messtype0
==
0xf
)
return
true
;
if
(
v2
->
msg_type
==
v2messtype0
||
v2
->
msg_type
==
v2messtype1
)
return
true
;
return
false
;
}
return
false
;
}
void
lan_queue_rx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
void
lan_queue_rx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
uint32_t
h
)
{
uint32_t
h
)
{
size_t
num_descs
=
(
pktlen
+
dbuff_size
-
1
)
/
dbuff_size
;
size_t
num_descs
=
(
pktlen
+
dbuff_size
-
1
)
/
dbuff_size
;
...
@@ -320,6 +407,21 @@ void lan_queue_rx::packet_received(const void *data, size_t pktlen,
...
@@ -320,6 +407,21 @@ void lan_queue_rx::packet_received(const void *data, size_t pktlen,
return
;
return
;
}
}
// sample ptp rx timestamp if enabled, packet matches conditions, and a free
// rx timestamp register can be found.
int
rxtime_id
=
-
1
;
if
(
ptp_rx_sample
(
data
,
pktlen
))
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
if
(
!
dev
.
regs
.
prtsyn_rxtime_lock
[
i
])
{
dev
.
regs
.
prtsyn_rxtime
[
i
]
=
dev
.
ptp
.
phc_read
();
dev
.
regs
.
prtsyn_rxtime_lock
[
i
]
=
true
;
dev
.
regs
.
prtsyn_stat_1
|=
1
<<
(
I40E_PRTTSYN_STAT_1_RXT0_SHIFT
+
i
);
rxtime_id
=
i
;
break
;
}
}
}
for
(
size_t
i
=
0
;
i
<
num_descs
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
num_descs
;
i
++
)
{
rx_desc_ctx
&
ctx
=
*
dcache
.
front
();
rx_desc_ctx
&
ctx
=
*
dcache
.
front
();
...
@@ -332,9 +434,9 @@ void lan_queue_rx::packet_received(const void *data, size_t pktlen,
...
@@ -332,9 +434,9 @@ void lan_queue_rx::packet_received(const void *data, size_t pktlen,
const
uint8_t
*
buf
=
(
const
uint8_t
*
)
data
+
(
dbuff_size
*
i
);
const
uint8_t
*
buf
=
(
const
uint8_t
*
)
data
+
(
dbuff_size
*
i
);
if
(
i
==
num_descs
-
1
)
{
if
(
i
==
num_descs
-
1
)
{
// last packet
// last packet
ctx
.
packet_received
(
buf
,
pktlen
-
dbuff_size
*
i
,
true
);
ctx
.
packet_received
(
buf
,
pktlen
-
dbuff_size
*
i
,
true
,
rxtime_id
);
}
else
{
}
else
{
ctx
.
packet_received
(
buf
,
dbuff_size
,
false
);
ctx
.
packet_received
(
buf
,
dbuff_size
,
false
,
-
1
);
}
}
}
}
}
}
...
@@ -352,7 +454,7 @@ void lan_queue_rx::rx_desc_ctx::process() {
...
@@ -352,7 +454,7 @@ void lan_queue_rx::rx_desc_ctx::process() {
}
}
void
lan_queue_rx
::
rx_desc_ctx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
void
lan_queue_rx
::
rx_desc_ctx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
bool
last
)
{
bool
last
,
int
rxtime_id
)
{
// we only use fields in the lowest 16b anyways, even if set to 32b
// we only use fields in the lowest 16b anyways, even if set to 32b
union
i40e_16byte_rx_desc
*
rxd
=
union
i40e_16byte_rx_desc
*
rxd
=
reinterpret_cast
<
union
i40e_16byte_rx_desc
*>
(
desc
);
reinterpret_cast
<
union
i40e_16byte_rx_desc
*>
(
desc
);
...
@@ -371,6 +473,15 @@ void lan_queue_rx::rx_desc_ctx::packet_received(const void *data, size_t pktlen,
...
@@ -371,6 +473,15 @@ void lan_queue_rx::rx_desc_ctx::packet_received(const void *data, size_t pktlen,
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_EOF_SHIFT
);
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_EOF_SHIFT
);
// TODO(antoinek): only if checksums are correct
// TODO(antoinek): only if checksums are correct
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_L3L4P_SHIFT
);
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_L3L4P_SHIFT
);
// if an rx timestamp was assigned, need to report ts register id in
// descriptor
if
(
rxtime_id
>=
0
)
{
rxd
->
wb
.
qword1
.
status_error_len
|=
((
uint32_t
)
rxtime_id
)
<<
I40E_RX_DESC_STATUS_TSYNINDX_SHIFT
;
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_TSYNVALID_SHIFT
);
}
}
}
data_write
(
addr
,
pktlen
,
data
);
data_write
(
addr
,
pktlen
,
data
);
}
}
...
@@ -444,6 +555,7 @@ bool lan_queue_tx::trigger_tx_packet() {
...
@@ -444,6 +555,7 @@ bool lan_queue_tx::trigger_tx_packet() {
uint64_t
d1
;
uint64_t
d1
;
uint32_t
iipt
,
l4t
,
pkt_len
,
total_len
=
0
,
data_limit
;
uint32_t
iipt
,
l4t
,
pkt_len
,
total_len
=
0
,
data_limit
;
bool
tso
=
false
;
bool
tso
=
false
;
bool
tsyn
=
false
;
uint32_t
tso_mss
=
0
,
tso_paylen
=
0
;
uint32_t
tso_mss
=
0
,
tso_paylen
=
0
;
uint16_t
maclen
=
0
,
iplen
=
0
,
l4len
=
0
;
uint16_t
maclen
=
0
,
iplen
=
0
,
l4len
=
0
;
...
@@ -470,6 +582,7 @@ bool lan_queue_tx::trigger_tx_packet() {
...
@@ -470,6 +582,7 @@ bool lan_queue_tx::trigger_tx_packet() {
((
d1
&
I40E_TXD_CTX_QW1_CMD_MASK
)
>>
I40E_TXD_CTX_QW1_CMD_SHIFT
);
((
d1
&
I40E_TXD_CTX_QW1_CMD_MASK
)
>>
I40E_TXD_CTX_QW1_CMD_SHIFT
);
tso
=
!!
(
cmd
&
I40E_TX_CTX_DESC_TSO
);
tso
=
!!
(
cmd
&
I40E_TX_CTX_DESC_TSO
);
tso_mss
=
(
d1
&
I40E_TXD_CTX_QW1_MSS_MASK
)
>>
I40E_TXD_CTX_QW1_MSS_SHIFT
;
tso_mss
=
(
d1
&
I40E_TXD_CTX_QW1_MSS_MASK
)
>>
I40E_TXD_CTX_QW1_MSS_SHIFT
;
tsyn
=
!!
(
cmd
&
I40E_TX_CTX_DESC_TSYN
);
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" tso="
<<
tso
<<
" mss="
<<
tso_mss
<<
logger
::
endl
;
log
<<
" tso="
<<
tso
<<
" mss="
<<
tso_mss
<<
logger
::
endl
;
...
@@ -625,6 +738,19 @@ bool lan_queue_tx::trigger_tx_packet() {
...
@@ -625,6 +738,19 @@ bool lan_queue_tx::trigger_tx_packet() {
}
}
}
}
// PTP transmit timestamping
if
(
tsyn
)
{
dev
.
regs
.
prtsyn_txtime
=
dev
.
ptp
.
phc_read
();
lanmgr
.
dev
.
regs
.
prtsyn_stat_0
|=
I40E_PRTTSYN_STAT_0_TXTIME_MASK
;
if
((
dev
.
regs
.
prtsyn_ctl_0
&
I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK
)
&&
(
lanmgr
.
dev
.
regs
.
pfint_icr0_ena
&
I40E_PFINT_ICR0_ENA_TIMESYNC_MASK
))
{
lanmgr
.
dev
.
regs
.
pfint_icr0
|=
I40E_PFINT_ICR0_INTEVENT_MASK
|
I40E_PFINT_ICR0_TIMESYNC_MASK
;
lanmgr
.
dev
.
SignalInterrupt
(
0
,
0
);
}
}
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" unit done"
<<
logger
::
endl
;
log
<<
" unit done"
<<
logger
::
endl
;
#endif
#endif
...
...
sims/nic/i40e_bm/i40e_ptp.cc
0 → 100644
View file @
c5977fb9
/*
* Copyright 2024 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <cassert>
#include <iostream>
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_bm.h"
namespace
i40e
{
ptpmgr
::
ptpmgr
(
i40e_bm
&
dev_
)
:
dev
(
dev_
),
last_updated
(
0
),
last_val
(
0
),
offset
(
0
),
inc_val
(
0
),
adj_neg
(
false
),
adj_val
(
0
)
{
}
uint64_t
ptpmgr
::
update_clock
()
{
/* this simulates the behavior of the PHC, but instead of doing it cycle by
cycle, we calculate updates when the clock is accessed or parameters are
modified, applying the same changes that should have happened cycle by
cycle. Before modifying any of the parameters update_clock has to be
called to get the correct behavior, to ensure e.g. that updates to adj and
inc are applied at the correct points in time.*/
uint64_t
ps_per_cycle
=
1000000000000ULL
/
CLOCK_HZ
;
uint64_t
cycle_now
=
dev
.
runner_
->
TimePs
()
/
ps_per_cycle
;
uint64_t
cycles_passed
=
cycle_now
-
last_updated
;
// increment clock
last_val
+=
(
__uint128_t
)
inc_val
*
cycles_passed
;
// factor in adjustments
if
(
adj_val
!=
0
)
{
__uint128_t
adj
;
if
(
adj_val
<=
cycles_passed
)
{
adj
=
cycles_passed
;
adj_val
-=
cycles_passed
;
}
else
{
adj
=
adj_val
;
adj_val
=
0
;
}
adj
=
adj
<<
32
;
if
(
adj_neg
)
last_val
-=
adj
;
else
last_val
+=
adj
;
}
last_updated
=
cycle_now
;
return
(
last_val
>>
32
)
+
offset
;
}
uint64_t
ptpmgr
::
phc_read
()
{
return
update_clock
();
}
void
ptpmgr
::
phc_write
(
uint64_t
val
)
{
uint64_t
cur_val
=
update_clock
();
offset
+=
(
val
-
cur_val
);
}
uint32_t
ptpmgr
::
adj_get
()
{
update_clock
();
uint32_t
x
=
(
adj_val
<<
I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT
)
&
I40E_PRTTSYN_ADJ_TSYNADJ_MASK
;
if
(
adj_neg
)
x
|=
I40E_PRTTSYN_ADJ_SIGN_MASK
;
return
x
;
}
void
ptpmgr
::
adj_set
(
uint32_t
val
)
{
update_clock
();
adj_val
=
(
val
&
I40E_PRTTSYN_ADJ_TSYNADJ_MASK
)
>>
I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT
;
adj_neg
=
(
val
&
I40E_PRTTSYN_ADJ_SIGN_MASK
);
}
void
ptpmgr
::
inc_set
(
uint64_t
inc
)
{
update_clock
();
inc_val
=
inc
;
}
}
// namespace i40e
sims/nic/i40e_bm/rules.mk
View file @
c5977fb9
...
@@ -25,7 +25,7 @@ include mk/subdir_pre.mk
...
@@ -25,7 +25,7 @@ include mk/subdir_pre.mk
bin_i40e_bm
:=
$(d)
i40e_bm
bin_i40e_bm
:=
$(d)
i40e_bm
OBJS
:=
$(
addprefix
$(d)
,i40e_bm.o i40e_queues.o i40e_adminq.o i40e_hmc.o
\
OBJS
:=
$(
addprefix
$(d)
,i40e_bm.o i40e_queues.o i40e_adminq.o i40e_hmc.o
\
i40e_lan.o xsums.o rss.o logger.o
)
i40e_lan.o
i40e_ptp.o
xsums.o rss.o logger.o
)
$(OBJS)
:
CPPFLAGS := $(CPPFLAGS) -I$(d)include/
$(OBJS)
:
CPPFLAGS := $(CPPFLAGS) -I$(d)include/
...
...
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