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
d4666c97
Commit
d4666c97
authored
Feb 13, 2021
by
Antoine Kaufmann
Browse files
Reformat closer to google style
parent
eb125a88
Changes
41
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
3623 additions
and
3840 deletions
+3623
-3840
sims/nic/corundum_bm/corundum_bm.h
sims/nic/corundum_bm/corundum_bm.h
+226
-225
sims/nic/corundum_bm/tester.c
sims/nic/corundum_bm/tester.c
+138
-150
sims/nic/i40e_bm/headers.h
sims/nic/i40e_bm/headers.h
+34
-36
sims/nic/i40e_bm/i40e_adminq.cc
sims/nic/i40e_bm/i40e_adminq.cc
+293
-302
sims/nic/i40e_bm/i40e_base_wrapper.h
sims/nic/i40e_bm/i40e_base_wrapper.h
+64
-64
sims/nic/i40e_bm/i40e_bm.cc
sims/nic/i40e_bm/i40e_bm.cc
+713
-747
sims/nic/i40e_bm/i40e_bm.h
sims/nic/i40e_bm/i40e_bm.h
+510
-510
sims/nic/i40e_bm/i40e_hmc.cc
sims/nic/i40e_bm/i40e_hmc.cc
+86
-90
sims/nic/i40e_bm/i40e_lan.cc
sims/nic/i40e_bm/i40e_lan.cc
+463
-499
sims/nic/i40e_bm/i40e_queues.cc
sims/nic/i40e_bm/i40e_queues.cc
+288
-316
sims/nic/i40e_bm/logger.cc
sims/nic/i40e_bm/logger.cc
+36
-47
sims/nic/i40e_bm/rss.cc
sims/nic/i40e_bm/rss.cc
+49
-57
sims/nic/i40e_bm/xsums.cc
sims/nic/i40e_bm/xsums.cc
+104
-115
trace/events.h
trace/events.h
+191
-214
trace/gem5.cc
trace/gem5.cc
+133
-139
trace/log_parser.cc
trace/log_parser.cc
+64
-73
trace/nicbm.cc
trace/nicbm.cc
+47
-65
trace/parser.h
trace/parser.h
+70
-75
trace/process.cc
trace/process.cc
+66
-67
trace/process.h
trace/process.h
+48
-49
No files found.
sims/nic/corundum_bm/corundum_bm.h
View file @
d4666c97
...
@@ -24,9 +24,10 @@
...
@@ -24,9 +24,10 @@
#pragma once
#pragma once
#include <stdint.h>
#include <list>
#include <list>
#include <vector>
#include <vector>
#include <stdint.h>
extern
"C"
{
extern
"C"
{
#include <simbricks/proto/pcie.h>
#include <simbricks/proto/pcie.h>
}
}
...
@@ -36,92 +37,92 @@ typedef uint32_t reg_t;
...
@@ -36,92 +37,92 @@ typedef uint32_t reg_t;
typedef
uint64_t
addr_t
;
typedef
uint64_t
addr_t
;
typedef
uint16_t
ptr_t
;
typedef
uint16_t
ptr_t
;
#define REG_FW_ID
0x0000
#define REG_FW_ID 0x0000
#define REG_FW_VER
0x0004
#define REG_FW_VER 0x0004
#define REG_BOARD_ID
0x0008
#define REG_BOARD_ID 0x0008
#define REG_BOARD_VER
0x000C
#define REG_BOARD_VER 0x000C
#define REG_PHC_COUNT
0x0010
#define REG_PHC_COUNT 0x0010
#define REG_PHC_OFFSET
0x0014
#define REG_PHC_OFFSET 0x0014
#define REG_PHC_STRIDE
0x0018
#define REG_PHC_STRIDE 0x0018
#define REG_IF_COUNT
0x0020
#define REG_IF_COUNT 0x0020
#define REG_IF_STRIDE
0x0024
#define REG_IF_STRIDE 0x0024
#define REG_IF_CSR_OFFSET
0x002C
#define REG_IF_CSR_OFFSET 0x002C
#define IF_FEATURE_RSS
(1 << 0)
#define IF_FEATURE_RSS (1 << 0)
#define IF_FEATURE_PTP_TS
(1 << 4)
#define IF_FEATURE_PTP_TS (1 << 4)
#define IF_FEATURE_TX_CSUM
(1 << 8)
#define IF_FEATURE_TX_CSUM (1 << 8)
#define IF_FEATURE_RX_CSUM
(1 << 9)
#define IF_FEATURE_RX_CSUM (1 << 9)
#define IF_FEATURE_RX_HASH
(1 << 10)
#define IF_FEATURE_RX_HASH (1 << 10)
#define PHC_REG_FEATURES
0x0200
#define PHC_REG_FEATURES 0x0200
#define PHC_REG_PTP_CUR_SEC_L
0x0218
#define PHC_REG_PTP_CUR_SEC_L 0x0218
#define PHC_REG_PTP_CUR_SEC_H
0x021C
#define PHC_REG_PTP_CUR_SEC_H 0x021C
#define PHC_REG_PTP_SET_FNS
0x0230
#define PHC_REG_PTP_SET_FNS 0x0230
#define PHC_REG_PTP_SET_NS
0x0234
#define PHC_REG_PTP_SET_NS 0x0234
#define PHC_REG_PTP_SET_SEC_L
0x0238
#define PHC_REG_PTP_SET_SEC_L 0x0238
#define PHC_REG_PTP_SET_SEC_H
0x023C
#define PHC_REG_PTP_SET_SEC_H 0x023C
#define IF_REG_IF_ID
0x80000
#define IF_REG_IF_ID 0x80000
#define IF_REG_IF_FEATURES
0x80004
#define IF_REG_IF_FEATURES 0x80004
#define IF_REG_EVENT_QUEUE_COUNT
0x80010
#define IF_REG_EVENT_QUEUE_COUNT 0x80010
#define IF_REG_EVENT_QUEUE_OFFSET
0x80014
#define IF_REG_EVENT_QUEUE_OFFSET 0x80014
#define IF_REG_TX_QUEUE_COUNT
0x80020
#define IF_REG_TX_QUEUE_COUNT 0x80020
#define IF_REG_TX_QUEUE_OFFSET
0x80024
#define IF_REG_TX_QUEUE_OFFSET 0x80024
#define IF_REG_TX_CPL_QUEUE_COUNT
0x80028
#define IF_REG_TX_CPL_QUEUE_COUNT 0x80028
#define IF_REG_TX_CPL_QUEUE_OFFSET
0x8002C
#define IF_REG_TX_CPL_QUEUE_OFFSET 0x8002C
#define IF_REG_RX_QUEUE_COUNT
0x80030
#define IF_REG_RX_QUEUE_COUNT 0x80030
#define IF_REG_RX_QUEUE_OFFSET
0x80034
#define IF_REG_RX_QUEUE_OFFSET 0x80034
#define IF_REG_RX_CPL_QUEUE_COUNT
0x80038
#define IF_REG_RX_CPL_QUEUE_COUNT 0x80038
#define IF_REG_RX_CPL_QUEUE_OFFSET
0x8003C
#define IF_REG_RX_CPL_QUEUE_OFFSET 0x8003C
#define IF_REG_PORT_COUNT
0x80040
#define IF_REG_PORT_COUNT 0x80040
#define IF_REG_PORT_OFFSET
0x80044
#define IF_REG_PORT_OFFSET 0x80044
#define IF_REG_PORT_STRIDE
0x80048
#define IF_REG_PORT_STRIDE 0x80048
#define QUEUE_ACTIVE_MASK 0x80000000
#define QUEUE_ACTIVE_MASK 0x80000000
#define QUEUE_ARM_MASK 0x80000000
#define QUEUE_ARM_MASK 0x80000000
#define QUEUE_CONT_MASK 0x40000000
#define QUEUE_CONT_MASK 0x40000000
#define EVENT_QUEUE_BASE_ADDR_REG
0x100000
#define EVENT_QUEUE_BASE_ADDR_REG 0x100000
#define EVENT_QUEUE_ACTIVE_LOG_SIZE_REG 0x100008
#define EVENT_QUEUE_ACTIVE_LOG_SIZE_REG 0x100008
#define EVENT_QUEUE_INTERRUPT_INDEX_REG 0x10000C
#define EVENT_QUEUE_INTERRUPT_INDEX_REG 0x10000C
#define EVENT_QUEUE_HEAD_PTR_REG
0x100010
#define EVENT_QUEUE_HEAD_PTR_REG 0x100010
#define EVENT_QUEUE_TAIL_PTR_REG
0x100018
#define EVENT_QUEUE_TAIL_PTR_REG 0x100018
#define TX_QUEUE_BASE_ADDR_REG
0x200000
#define TX_QUEUE_BASE_ADDR_REG 0x200000
#define TX_QUEUE_ACTIVE_LOG_SIZE_REG 0x200008
#define TX_QUEUE_ACTIVE_LOG_SIZE_REG 0x200008
#define TX_QUEUE_CPL_QUEUE_INDEX_REG 0x20000C
#define TX_QUEUE_CPL_QUEUE_INDEX_REG 0x20000C
#define TX_QUEUE_HEAD_PTR_REG
0x200010
#define TX_QUEUE_HEAD_PTR_REG 0x200010
#define TX_QUEUE_TAIL_PTR_REG
0x200018
#define TX_QUEUE_TAIL_PTR_REG 0x200018
#define TX_CPL_QUEUE_BASE_ADDR_REG
0x400000
#define TX_CPL_QUEUE_BASE_ADDR_REG 0x400000
#define TX_CPL_QUEUE_ACTIVE_LOG_SIZE_REG 0x400008
#define TX_CPL_QUEUE_ACTIVE_LOG_SIZE_REG 0x400008
#define TX_CPL_QUEUE_INTERRUPT_INDEX_REG 0x40000C
#define TX_CPL_QUEUE_INTERRUPT_INDEX_REG 0x40000C
#define TX_CPL_QUEUE_HEAD_PTR_REG
0x400010
#define TX_CPL_QUEUE_HEAD_PTR_REG 0x400010
#define TX_CPL_QUEUE_TAIL_PTR_REG
0x400018
#define TX_CPL_QUEUE_TAIL_PTR_REG 0x400018
#define RX_QUEUE_BASE_ADDR_REG
0x600000
#define RX_QUEUE_BASE_ADDR_REG 0x600000
#define RX_QUEUE_ACTIVE_LOG_SIZE_REG 0x600008
#define RX_QUEUE_ACTIVE_LOG_SIZE_REG 0x600008
#define RX_QUEUE_CPL_QUEUE_INDEX_REG 0x60000C
#define RX_QUEUE_CPL_QUEUE_INDEX_REG 0x60000C
#define RX_QUEUE_HEAD_PTR_REG
0x600010
#define RX_QUEUE_HEAD_PTR_REG 0x600010
#define RX_QUEUE_TAIL_PTR_REG
0x600018
#define RX_QUEUE_TAIL_PTR_REG 0x600018
#define RX_CPL_QUEUE_BASE_ADDR_REG
0x700000
#define RX_CPL_QUEUE_BASE_ADDR_REG 0x700000
#define RX_CPL_QUEUE_ACTIVE_LOG_SIZE_REG 0x700008
#define RX_CPL_QUEUE_ACTIVE_LOG_SIZE_REG 0x700008
#define RX_CPL_QUEUE_INTERRUPT_INDEX_REG 0x70000C
#define RX_CPL_QUEUE_INTERRUPT_INDEX_REG 0x70000C
#define RX_CPL_QUEUE_HEAD_PTR_REG
0x700010
#define RX_CPL_QUEUE_HEAD_PTR_REG 0x700010
#define RX_CPL_QUEUE_TAIL_PTR_REG
0x700018
#define RX_CPL_QUEUE_TAIL_PTR_REG 0x700018
#define PORT_REG_PORT_ID
0x800000
#define PORT_REG_PORT_ID 0x800000
#define PORT_REG_PORT_FEATURES
0x800004
#define PORT_REG_PORT_FEATURES 0x800004
#define PORT_REG_PORT_MTU
0x800008
#define PORT_REG_PORT_MTU 0x800008
#define PORT_REG_SCHED_COUNT
0x800010
#define PORT_REG_SCHED_COUNT 0x800010
#define PORT_REG_SCHED_OFFSET
0x800014
#define PORT_REG_SCHED_OFFSET 0x800014
#define PORT_REG_SCHED_STRIDE
0x800018
#define PORT_REG_SCHED_STRIDE 0x800018
#define PORT_REG_SCHED_TYPE
0x80001C
#define PORT_REG_SCHED_TYPE 0x80001C
#define PORT_REG_SCHED_ENABLE
0x800040
#define PORT_REG_SCHED_ENABLE 0x800040
#define PORT_REG_RSS_MASK
0x800080
#define PORT_REG_RSS_MASK 0x800080
#define PORT_QUEUE_ENABLE
0x900000
#define PORT_QUEUE_ENABLE 0x900000
namespace
corundum
{
namespace
corundum
{
...
@@ -133,209 +134,209 @@ namespace corundum {
...
@@ -133,209 +134,209 @@ namespace corundum {
class
DescRing
;
class
DescRing
;
struct
Desc
{
struct
Desc
{
uint16_t
rsvd0
;
uint16_t
rsvd0
;
uint16_t
tx_csum_cmd
;
uint16_t
tx_csum_cmd
;
uint32_t
len
;
uint32_t
len
;
uint64_t
addr
;
uint64_t
addr
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
struct
Cpl
{
struct
Cpl
{
uint16_t
queue
;
uint16_t
queue
;
uint16_t
index
;
uint16_t
index
;
uint16_t
len
;
uint16_t
len
;
uint16_t
rsvd0
;
uint16_t
rsvd0
;
uint32_t
ts_ns
;
uint32_t
ts_ns
;
uint16_t
ts_s
;
uint16_t
ts_s
;
uint16_t
rx_csum
;
uint16_t
rx_csum
;
uint32_t
rx_hash
;
uint32_t
rx_hash
;
uint8_t
rx_hash_type
;
uint8_t
rx_hash_type
;
uint8_t
rsvd1
;
uint8_t
rsvd1
;
uint8_t
rsvd2
;
uint8_t
rsvd2
;
uint8_t
rsvd3
;
uint8_t
rsvd3
;
uint32_t
rsvd4
;
uint32_t
rsvd4
;
uint32_t
rsvd5
;
uint32_t
rsvd5
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
#define EVENT_TYPE_TX_CPL 0x0000
#define EVENT_TYPE_TX_CPL 0x0000
#define EVENT_TYPE_RX_CPL 0x0001
#define EVENT_TYPE_RX_CPL 0x0001
struct
Event
{
struct
Event
{
uint16_t
type
;
uint16_t
type
;
uint16_t
source
;
uint16_t
source
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
struct
RxData
{
struct
RxData
{
size_t
len
;
size_t
len
;
uint8_t
data
[
MAX_DMA_LEN
];
uint8_t
data
[
MAX_DMA_LEN
];
};
};
#define DMA_TYPE_DESC
0
#define DMA_TYPE_DESC 0
#define DMA_TYPE_MEM
1
#define DMA_TYPE_MEM 1
#define DMA_TYPE_TX_CPL 2
#define DMA_TYPE_TX_CPL 2
#define DMA_TYPE_RX_CPL 3
#define DMA_TYPE_RX_CPL 3
#define DMA_TYPE_EVENT
4
#define DMA_TYPE_EVENT 4
struct
DMAOp
:
public
nicbm
::
DMAOp
{
struct
DMAOp
:
public
nicbm
::
DMAOp
{
DMAOp
()
{
DMAOp
()
{
data
=
databuf
;
data
=
databuf
;
}
}
uint8_t
type
;
uint8_t
type
;
DescRing
*
ring
;
DescRing
*
ring
;
RxData
*
rx_data
;
RxData
*
rx_data
;
uint64_t
tag
;
uint64_t
tag
;
uint8_t
databuf
[
MAX_DMA_LEN
];
uint8_t
databuf
[
MAX_DMA_LEN
];
};
};
class
DescRing
{
class
DescRing
{
public:
public:
DescRing
();
DescRing
();
~
DescRing
();
~
DescRing
();
addr_t
dmaAddr
();
addr_t
dmaAddr
();
size_t
sizeLog
();
size_t
sizeLog
();
unsigned
index
();
unsigned
index
();
ptr_t
headPtr
();
ptr_t
headPtr
();
ptr_t
tailPtr
();
ptr_t
tailPtr
();
void
setDMALower
(
uint32_t
addr
);
void
setDMALower
(
uint32_t
addr
);
void
setDMAUpper
(
uint32_t
addr
);
void
setDMAUpper
(
uint32_t
addr
);
void
setSizeLog
(
size_t
size_log
);
void
setSizeLog
(
size_t
size_log
);
void
setIndex
(
unsigned
index
);
void
setIndex
(
unsigned
index
);
virtual
void
setHeadPtr
(
ptr_t
ptr
);
virtual
void
setHeadPtr
(
ptr_t
ptr
);
void
setTailPtr
(
ptr_t
ptr
);
void
setTailPtr
(
ptr_t
ptr
);
virtual
void
dmaDone
(
DMAOp
*
op
)
=
0
;
virtual
void
dmaDone
(
DMAOp
*
op
)
=
0
;
protected:
protected:
bool
empty
();
bool
empty
();
bool
full
();
bool
full
();
bool
updatePtr
(
ptr_t
ptr
,
bool
head
);
bool
updatePtr
(
ptr_t
ptr
,
bool
head
);
addr_t
_dmaAddr
;
addr_t
_dmaAddr
;
size_t
_sizeLog
;
size_t
_sizeLog
;
size_t
_size
;
size_t
_size
;
size_t
_sizeMask
;
size_t
_sizeMask
;
unsigned
_index
;
unsigned
_index
;
ptr_t
_headPtr
;
ptr_t
_headPtr
;
ptr_t
_tailPtr
;
ptr_t
_tailPtr
;
ptr_t
_currHead
;
ptr_t
_currHead
;
ptr_t
_currTail
;
ptr_t
_currTail
;
bool
active
;
bool
active
;
bool
armed
;
bool
armed
;
std
::
vector
<
bool
>
cplDma
;
std
::
vector
<
bool
>
cplDma
;
};
};
class
EventRing
:
public
DescRing
{
class
EventRing
:
public
DescRing
{
public:
public:
EventRing
();
EventRing
();
~
EventRing
();
~
EventRing
();
void
dmaDone
(
DMAOp
*
op
)
override
;
void
dmaDone
(
DMAOp
*
op
)
override
;
void
issueEvent
(
unsigned
type
,
unsigned
source
);
void
issueEvent
(
unsigned
type
,
unsigned
source
);
};
};
class
CplRing
:
public
DescRing
{
class
CplRing
:
public
DescRing
{
public:
public:
CplRing
(
EventRing
*
eventRing
);
CplRing
(
EventRing
*
eventRing
);
~
CplRing
();
~
CplRing
();
void
dmaDone
(
DMAOp
*
op
)
override
;
void
dmaDone
(
DMAOp
*
op
)
override
;
void
complete
(
unsigned
index
,
size_t
len
,
bool
tx
);
void
complete
(
unsigned
index
,
size_t
len
,
bool
tx
);
private:
private:
struct
CplData
{
struct
CplData
{
unsigned
index
;
unsigned
index
;
size_t
len
;
size_t
len
;
bool
tx
;
bool
tx
;
};
};
EventRing
*
eventRing
;
EventRing
*
eventRing
;
std
::
list
<
CplData
>
pending
;
std
::
list
<
CplData
>
pending
;
};
};
class
TxRing
:
public
DescRing
{
class
TxRing
:
public
DescRing
{
public:
public:
TxRing
(
CplRing
*
cplRing
);
TxRing
(
CplRing
*
cplRing
);
~
TxRing
();
~
TxRing
();
void
setHeadPtr
(
ptr_t
ptr
)
override
;
void
setHeadPtr
(
ptr_t
ptr
)
override
;
void
dmaDone
(
DMAOp
*
op
)
override
;
void
dmaDone
(
DMAOp
*
op
)
override
;
private:
private:
CplRing
*
txCplRing
;
CplRing
*
txCplRing
;
};
};
class
RxRing
:
public
DescRing
{
class
RxRing
:
public
DescRing
{
public:
public:
RxRing
(
CplRing
*
cplRing
);
RxRing
(
CplRing
*
cplRing
);
~
RxRing
();
~
RxRing
();
void
dmaDone
(
DMAOp
*
op
)
override
;
void
dmaDone
(
DMAOp
*
op
)
override
;
void
rx
(
RxData
*
rx_data
);
void
rx
(
RxData
*
rx_data
);
private:
private:
CplRing
*
rxCplRing
;
CplRing
*
rxCplRing
;
};
};
class
Port
{
class
Port
{
public:
public:
Port
();
Port
();
~
Port
();
~
Port
();
unsigned
id
();
unsigned
id
();
unsigned
features
();
unsigned
features
();
size_t
mtu
();
size_t
mtu
();
size_t
schedCount
();
size_t
schedCount
();
addr_t
schedOffset
();
addr_t
schedOffset
();
addr_t
schedStride
();
addr_t
schedStride
();
unsigned
schedType
();
unsigned
schedType
();
unsigned
rssMask
();
unsigned
rssMask
();
void
setId
(
unsigned
id
);
void
setId
(
unsigned
id
);
void
setFeatures
(
unsigned
features
);
void
setFeatures
(
unsigned
features
);
void
setMtu
(
size_t
mtu
);
void
setMtu
(
size_t
mtu
);
void
setSchedCount
(
size_t
count
);
void
setSchedCount
(
size_t
count
);
void
setSchedOffset
(
addr_t
offset
);
void
setSchedOffset
(
addr_t
offset
);
void
setSchedStride
(
addr_t
stride
);
void
setSchedStride
(
addr_t
stride
);
void
setSchedType
(
unsigned
type
);
void
setSchedType
(
unsigned
type
);
void
setRssMask
(
unsigned
mask
);
void
setRssMask
(
unsigned
mask
);
void
schedEnable
();
void
schedEnable
();
void
schedDisable
();
void
schedDisable
();
void
queueEnable
();
void
queueEnable
();
void
queueDisable
();
void
queueDisable
();
private:
private:
unsigned
_id
;
unsigned
_id
;
unsigned
_features
;
unsigned
_features
;
size_t
_mtu
;
size_t
_mtu
;
size_t
_schedCount
;
size_t
_schedCount
;
addr_t
_schedOffset
;
addr_t
_schedOffset
;
addr_t
_schedStride
;
addr_t
_schedStride
;
unsigned
_schedType
;
unsigned
_schedType
;
unsigned
_rssMask
;
unsigned
_rssMask
;
bool
_schedEnable
;
bool
_schedEnable
;
bool
_queueEnable
;
bool
_queueEnable
;
};
};
class
Corundum
:
public
nicbm
::
SimpleDevice
<
reg_t
>
{
class
Corundum
:
public
nicbm
::
SimpleDevice
<
reg_t
>
{
public:
public:
Corundum
();
Corundum
();
~
Corundum
();
~
Corundum
();
virtual
void
setup_intro
(
struct
cosim_pcie_proto_dev_intro
&
di
);
virtual
void
setup_intro
(
struct
cosim_pcie_proto_dev_intro
&
di
);
virtual
reg_t
reg_read
(
uint8_t
bar
,
addr_t
addr
);
virtual
reg_t
reg_read
(
uint8_t
bar
,
addr_t
addr
);
virtual
void
reg_write
(
uint8_t
bar
,
addr_t
addr
,
reg_t
val
);
virtual
void
reg_write
(
uint8_t
bar
,
addr_t
addr
,
reg_t
val
);
virtual
void
dma_complete
(
nicbm
::
DMAOp
&
op
);
virtual
void
dma_complete
(
nicbm
::
DMAOp
&
op
);
virtual
void
eth_rx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
);
virtual
void
eth_rx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
);
private:
private:
EventRing
eventRing
;
EventRing
eventRing
;
TxRing
txRing
;
TxRing
txRing
;
CplRing
txCplRing
;
CplRing
txCplRing
;
RxRing
rxRing
;
RxRing
rxRing
;
CplRing
rxCplRing
;
CplRing
rxCplRing
;
Port
port
;
Port
port
;
uint32_t
features
;
uint32_t
features
;
};
};
}
// namespace corundum
}
// namespace corundum
sims/nic/corundum_bm/tester.c
View file @
d4666c97
...
@@ -22,19 +22,18 @@
...
@@ -22,19 +22,18 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
*/
#include <stdlib.h>
#include <assert.h>
#include <cosim_pcie_proto.h>
#include <fcntl.h>
#include <nicsim.h>
#include <signal.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/un.h>
#include <sys/mman.h>
#include <unistd.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <assert.h>
#include <nicsim.h>
#include <cosim_pcie_proto.h>
static
uint8_t
*
d2h_queue
;
static
uint8_t
*
d2h_queue
;
static
size_t
d2h_pos
;
static
size_t
d2h_pos
;
...
@@ -46,179 +45,168 @@ static size_t h2d_pos;
...
@@ -46,179 +45,168 @@ static size_t h2d_pos;
static
size_t
h2d_elen
;
static
size_t
h2d_elen
;
static
size_t
h2d_enum
;
static
size_t
h2d_enum
;
static
void
sigint_handler
(
int
dummy
)
static
void
sigint_handler
(
int
dummy
)
{
{
exit
(
1
);
exit
(
1
);
}
}
static
int
uxsocket_init
()
static
int
uxsocket_init
()
{
{
int
cfd
;
int
cfd
;
if
((
cfd
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
))
==
-
1
)
{
if
((
cfd
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
))
==
-
1
)
{
return
-
1
;
return
-
1
;
}
}
struct
sockaddr_un
saun
;
struct
sockaddr_un
saun
;
memset
(
&
saun
,
0
,
sizeof
(
saun
));
memset
(
&
saun
,
0
,
sizeof
(
saun
));
saun
.
sun_family
=
AF_UNIX
;
saun
.
sun_family
=
AF_UNIX
;
memcpy
(
saun
.
sun_path
,
"/tmp/cosim-pci"
,
strlen
(
"/tmp/cosim-pci"
));
memcpy
(
saun
.
sun_path
,
"/tmp/cosim-pci"
,
strlen
(
"/tmp/cosim-pci"
));
if
(
connect
(
cfd
,
(
struct
sockaddr
*
)
&
saun
,
sizeof
(
saun
))
==
-
1
)
{
if
(
connect
(
cfd
,
(
struct
sockaddr
*
)
&
saun
,
sizeof
(
saun
))
==
-
1
)
{
close
(
cfd
);
close
(
cfd
);
return
-
1
;
return
-
1
;
}
}
return
cfd
;
return
cfd
;
}
}
static
int
queue_create
(
const
struct
cosim_pcie_proto_dev_intro
di
)
static
int
queue_create
(
const
struct
cosim_pcie_proto_dev_intro
di
)
{
{
int
fd
=
-
1
;
int
fd
=
-
1
;
if
((
fd
=
open
(
"/dev/shm/dummy_nic_shm"
,
O_RDWR
))
==
-
1
)
{
if
((
fd
=
open
(
"/dev/shm/dummy_nic_shm"
,
O_RDWR
))
==
-
1
)
{
perror
(
"Failed to open shm file"
);
perror
(
"Failed to open shm file"
);
goto
error
;
goto
error
;
}
}
void
*
addr
;
void
*
addr
;
if
((
addr
=
mmap
(
NULL
,
32
*
1024
*
1024
,
PROT_READ
|
PROT_WRITE
,
if
((
addr
=
mmap
(
NULL
,
32
*
1024
*
1024
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
|
MAP_POPULATE
,
fd
,
0
))
==
(
void
*
)
-
1
)
{
MAP_SHARED
|
MAP_POPULATE
,
fd
,
0
))
==
(
void
*
)
-
1
)
{
perror
(
"mmap failed"
);
perror
(
"mmap failed"
);
goto
error
;
goto
error
;
}
}
d2h_queue
=
(
uint8_t
*
)
addr
+
di
.
d2h_offset
;
d2h_queue
=
(
uint8_t
*
)
addr
+
di
.
d2h_offset
;
d2h_pos
=
0
;
d2h_pos
=
0
;
d2h_elen
=
di
.
d2h_elen
;
d2h_elen
=
di
.
d2h_elen
;
d2h_enum
=
di
.
d2h_nentries
;
d2h_enum
=
di
.
d2h_nentries
;
h2d_queue
=
(
uint8_t
*
)
addr
+
di
.
h2d_offset
;
h2d_queue
=
(
uint8_t
*
)
addr
+
di
.
h2d_offset
;
h2d_pos
=
0
;
h2d_pos
=
0
;
h2d_elen
=
di
.
h2d_elen
;
h2d_elen
=
di
.
h2d_elen
;
h2d_enum
=
di
.
h2d_nentries
;
h2d_enum
=
di
.
h2d_nentries
;
return
0
;
return
0
;
error:
error:
if
(
fd
>
0
)
{
if
(
fd
>
0
)
{
close
(
fd
);
close
(
fd
);
}
}
return
-
1
;
return
-
1
;
}
}
volatile
union
cosim_pcie_proto_h2d
*
h2d_alloc
()
volatile
union
cosim_pcie_proto_h2d
*
h2d_alloc
()
{
{
volatile
union
cosim_pcie_proto_h2d
*
msg
=
volatile
union
cosim_pcie_proto_h2d
*
msg
=
(
volatile
union
cosim_pcie_proto_h2d
*
)(
h2d_queue
+
h2d_pos
*
h2d_elen
);
(
volatile
union
cosim_pcie_proto_h2d
*
)
(
h2d_queue
+
h2d_pos
*
h2d_elen
);
if
((
msg
->
dummy
.
own_type
&
COSIM_PCIE_PROTO_H2D_OWN_MASK
)
!=
if
((
msg
->
dummy
.
own_type
&
COSIM_PCIE_PROTO_H2D_OWN_MASK
)
!=
COSIM_PCIE_PROTO_H2D_OWN_HOST
)
{
COSIM_PCIE_PROTO_H2D_OWN_HOST
)
{
fprintf
(
stderr
,
"cosim: failed to allocate h2d message
\n
"
);
fprintf
(
stderr
,
"cosim: failed to allocate h2d message
\n
"
);
exit
(
1
);
exit
(
1
);
}
}
h2d_pos
=
(
h2d_pos
+
1
)
%
h2d_enum
;
h2d_pos
=
(
h2d_pos
+
1
)
%
h2d_enum
;
return
msg
;
return
msg
;
}
}
volatile
union
cosim_pcie_proto_d2h
*
d2h_poll
()
volatile
union
cosim_pcie_proto_d2h
*
d2h_poll
()
{
{
volatile
union
cosim_pcie_proto_d2h
*
msg
;
volatile
union
cosim_pcie_proto_d2h
*
msg
;
msg
=
(
volatile
union
cosim_pcie_proto_d2h
*
)
msg
=
(
volatile
union
cosim_pcie_proto_d2h
*
)(
d2h_queue
+
d2h_pos
*
d2h_elen
);
(
d2h_queue
+
d2h_pos
*
d2h_elen
);
if
((
msg
->
dummy
.
own_type
&
COSIM_PCIE_PROTO_D2H_OWN_MASK
)
==
if
((
msg
->
dummy
.
own_type
&
COSIM_PCIE_PROTO_D2H_OWN_MASK
)
==
COSIM_PCIE_PROTO_D2H_OWN_DEV
)
{
COSIM_PCIE_PROTO_D2H_OWN_DEV
)
{
return
NULL
;
return
NULL
;
}
}
return
msg
;
return
msg
;
}
}
void
d2h_done
(
volatile
union
cosim_pcie_proto_d2h
*
msg
)
void
d2h_done
(
volatile
union
cosim_pcie_proto_d2h
*
msg
)
{
{
msg
->
dummy
.
own_type
=
(
msg
->
dummy
.
own_type
&
COSIM_PCIE_PROTO_D2H_MSG_MASK
)
|
msg
->
dummy
.
own_type
=
(
msg
->
dummy
.
own_type
&
COSIM_PCIE_PROTO_D2H_MSG_MASK
)
COSIM_PCIE_PROTO_D2H_OWN_DEV
;
|
COSIM_PCIE_PROTO_D2H_OWN_DEV
;
d2h_pos
=
(
d2h_pos
+
1
)
%
d2h_enum
;
d2h_pos
=
(
d2h_pos
+
1
)
%
d2h_enum
;
}
}
static
void
dev_read
(
uint64_t
offset
,
uint16_t
len
)
static
void
dev_read
(
uint64_t
offset
,
uint16_t
len
)
{
{
volatile
union
cosim_pcie_proto_h2d
*
h2d_msg
=
h2d_alloc
();
volatile
union
cosim_pcie_proto_h2d
*
h2d_msg
=
h2d_alloc
();
volatile
struct
cosim_pcie_proto_h2d_read
*
read
=
&
h2d_msg
->
read
;
volatile
struct
cosim_pcie_proto_h2d_read
*
read
=
&
h2d_msg
->
read
;
read
->
req_id
=
0xF
;
read
->
req_id
=
0xF
;
read
->
offset
=
offset
;
read
->
offset
=
offset
;
read
->
len
=
len
;
read
->
len
=
len
;
read
->
bar
=
0
;
read
->
bar
=
0
;
read
->
own_type
=
COSIM_PCIE_PROTO_H2D_MSG_READ
|
COSIM_PCIE_PROTO_H2D_OWN_DEV
;
read
->
own_type
=
COSIM_PCIE_PROTO_H2D_MSG_READ
|
COSIM_PCIE_PROTO_H2D_OWN_DEV
;
volatile
union
cosim_pcie_proto_d2h
*
d2h_msg
=
NULL
;
while
(
d2h_msg
==
NULL
)
{
volatile
union
cosim_pcie_proto_d2h
*
d2h_msg
=
NULL
;
d2h_msg
=
d2h_poll
();
while
(
d2h_msg
==
NULL
)
{
}
d2h_msg
=
d2h_poll
();
volatile
struct
cosim_pcie_proto_d2h_readcomp
*
rc
;
}
rc
=
&
d2h_msg
->
readcomp
;
volatile
struct
cosim_pcie_proto_d2h_readcomp
*
rc
;
assert
(
rc
->
req_id
==
0xF
);
rc
=
&
d2h_msg
->
readcomp
;
printf
(
"received readcomp with data "
);
assert
(
rc
->
req_id
==
0xF
);
for
(
int
i
=
0
;
i
<
read
->
len
;
i
++
)
{
printf
(
"received readcomp with data "
);
printf
(
"%x "
,
((
const
uint8_t
*
)
rc
->
data
)[
i
]);
for
(
int
i
=
0
;
i
<
read
->
len
;
i
++
)
{
}
printf
(
"%x "
,
((
const
uint8_t
*
)
rc
->
data
)[
i
]);
printf
(
"
\n
"
);
}
printf
(
"
\n
"
);
d2h_done
(
d2h_msg
);
d2h_done
(
d2h_msg
);
}
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
signal
(
SIGINT
,
sigint_handler
);
signal
(
SIGINT
,
sigint_handler
);
int
cfd
;
if
((
cfd
=
uxsocket_init
())
<
0
)
{
fprintf
(
stderr
,
"Failed to open unix socket
\n
"
);
return
-
1
;
}
struct
cosim_pcie_proto_dev_intro
di
;
int
cfd
;
if
(
recv
(
cfd
,
&
di
,
sizeof
(
di
),
0
)
!=
sizeof
(
di
))
{
if
((
cfd
=
uxsocket_init
())
<
0
)
{
perror
(
"Failed to receive dev_intro"
);
fprintf
(
stderr
,
"Failed to open unix socket
\n
"
);
close
(
cfd
);
return
-
1
;
return
-
1
;
}
}
if
(
queue_create
(
di
)
!=
0
)
{
struct
cosim_pcie_proto_dev_intro
di
;
fprintf
(
stderr
,
"Failed to create shm queues
\n
"
);
if
(
recv
(
cfd
,
&
di
,
sizeof
(
di
),
0
)
!=
sizeof
(
di
))
{
close
(
cfd
);
perror
(
"Failed to receive dev_intro"
);
return
-
1
;
close
(
cfd
);
}
return
-
1
;
}
struct
cosim_pcie_proto_host_intro
hi
;
if
(
queue_create
(
di
)
!=
0
)
{
hi
.
flags
=
COSIM_PCIE_PROTO_FLAGS_HI_SYNC
;
fprintf
(
stderr
,
"Failed to create shm queues
\n
"
);
if
(
send
(
cfd
,
&
hi
,
sizeof
(
hi
),
0
)
!=
sizeof
(
hi
))
{
close
(
cfd
);
perror
(
"Failed to send host_intro"
);
return
-
1
;
close
(
cfd
);
}
return
-
1
;
}
while
(
1
)
{
struct
cosim_pcie_proto_host_intro
hi
;
int
op_type
;
hi
.
flags
=
COSIM_PCIE_PROTO_FLAGS_HI_SYNC
;
uint64_t
offset
;
if
(
send
(
cfd
,
&
hi
,
sizeof
(
hi
),
0
)
!=
sizeof
(
hi
))
{
uint16_t
len
;
perror
(
"Failed to send host_intro"
);
printf
(
"op type (0-read): "
);
close
(
cfd
);
scanf
(
"%d"
,
&
op_type
);
return
-
1
;
printf
(
"offset: "
);
}
scanf
(
"%lx"
,
&
offset
);
printf
(
"len: "
);
while
(
1
)
{
scanf
(
"%hu"
,
&
len
);
int
op_type
;
switch
(
op_type
)
{
uint64_t
offset
;
case
0
:
uint16_t
len
;
dev_read
(
offset
,
len
);
printf
(
"op type (0-read): "
);
break
;
scanf
(
"%d"
,
&
op_type
);
default:
printf
(
"offset: "
);
fprintf
(
stderr
,
"Unimplemented type %u
\n
"
,
op_type
);
scanf
(
"%lx"
,
&
offset
);
}
printf
(
"len: "
);
scanf
(
"%hu"
,
&
len
);
switch
(
op_type
)
{
case
0
:
dev_read
(
offset
,
len
);
break
;
default:
fprintf
(
stderr
,
"Unimplemented type %u
\n
"
,
op_type
);
}
}
}
close
(
cfd
);
close
(
cfd
);
return
0
;
return
0
;
}
}
sims/nic/i40e_bm/headers.h
View file @
d4666c97
...
@@ -33,8 +33,8 @@ namespace headers {
...
@@ -33,8 +33,8 @@ namespace headers {
#define ETH_ADDR_LEN 6
#define ETH_ADDR_LEN 6
#define ETH_TYPE_IP
0x0800
#define ETH_TYPE_IP 0x0800
#define ETH_TYPE_ARP
0x0806
#define ETH_TYPE_ARP 0x0806
struct
eth_addr
{
struct
eth_addr
{
uint8_t
addr
[
ETH_ADDR_LEN
];
uint8_t
addr
[
ETH_ADDR_LEN
];
...
@@ -46,11 +46,10 @@ struct eth_hdr {
...
@@ -46,11 +46,10 @@ struct eth_hdr {
uint16_t
type
;
uint16_t
type
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/******************************************************************************/
/******************************************************************************/
/* IPv4 */
/* IPv4 */
#define IPH_V(hdr)
((hdr)->_v_hl >> 4)
#define IPH_V(hdr) ((hdr)->_v_hl >> 4)
#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
#define IPH_TOS(hdr) ((hdr)->_tos)
#define IPH_TOS(hdr) ((hdr)->_tos)
#define IPH_ECN(hdr) ((hdr)->_tos & 0x3)
#define IPH_ECN(hdr) ((hdr)->_tos & 0x3)
...
@@ -61,19 +60,19 @@ struct eth_hdr {
...
@@ -61,19 +60,19 @@ struct eth_hdr {
#define IP_HLEN 20
#define IP_HLEN 20
#define IP_PROTO_IP
0
#define IP_PROTO_IP 0
#define IP_PROTO_ICMP
1
#define IP_PROTO_ICMP 1
#define IP_PROTO_IGMP
2
#define IP_PROTO_IGMP 2
#define IP_PROTO_IPENCAP 4
#define IP_PROTO_IPENCAP 4
#define IP_PROTO_UDP
17
#define IP_PROTO_UDP 17
#define IP_PROTO_UDPLITE 136
#define IP_PROTO_UDPLITE 136
#define IP_PROTO_TCP
6
#define IP_PROTO_TCP 6
#define IP_PROTO_DCCP
33
#define IP_PROTO_DCCP 33
#define IP_ECN_NONE
0x0
#define IP_ECN_NONE 0x0
#define IP_ECN_ECT0
0x2
#define IP_ECN_ECT0 0x2
#define IP_ECN_ECT1
0x1
#define IP_ECN_ECT1 0x1
#define IP_ECN_CE
0x3
#define IP_ECN_CE 0x3
struct
ip_hdr
{
struct
ip_hdr
{
/* version / header length */
/* version / header length */
...
@@ -97,7 +96,6 @@ struct ip_hdr {
...
@@ -97,7 +96,6 @@ struct ip_hdr {
uint32_t
dest
;
uint32_t
dest
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/******************************************************************************/
/******************************************************************************/
/* ARP */
/* ARP */
...
@@ -118,7 +116,6 @@ struct arp_hdr {
...
@@ -118,7 +116,6 @@ struct arp_hdr {
uint32_t
tpa
;
uint32_t
tpa
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/******************************************************************************/
/******************************************************************************/
/* TCP */
/* TCP */
...
@@ -130,7 +127,7 @@ struct arp_hdr {
...
@@ -130,7 +127,7 @@ struct arp_hdr {
#define TCP_URG 0x20U
#define TCP_URG 0x20U
#define TCP_ECE 0x40U
#define TCP_ECE 0x40U
#define TCP_CWR 0x80U
#define TCP_CWR 0x80U
#define TCP_NS
0x100U
#define TCP_NS 0x100U
#define TCP_FLAGS 0x1ffU
#define TCP_FLAGS 0x1ffU
...
@@ -138,23 +135,26 @@ struct arp_hdr {
...
@@ -138,23 +135,26 @@ struct arp_hdr {
#define TCP_HLEN 20
#define TCP_HLEN 20
#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = \
#define TCPH_HDRLEN_SET(phdr, len) \
htons(((len) << 12) | TCPH_FLAGS(phdr))
(phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = \
#define TCPH_FLAGS_SET(phdr, flags) \
(((phdr)->_hdrlen_rsvd_flags & PP_HTONS( \
(phdr)->_hdrlen_rsvd_flags = \
(uint16_t)(~(uint16_t)(TCP_FLAGS)))) | htons(flags))
(((phdr)->_hdrlen_rsvd_flags & \
PP_HTONS((uint16_t)(~(uint16_t)(TCP_FLAGS)))) | \
htons(flags))
#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) \
#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) \
(phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags))
(phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags))
#define TCPH_SET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = \
#define TCPH_SET_FLAG(phdr, flags) \
((phdr)->_hdrlen_rsvd_flags | htons(flags))
(phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags))
#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = \
#define TCPH_UNSET_FLAG(phdr, flags) \
htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
(phdr)->_hdrlen_rsvd_flags = \
htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)))
#define TCP_TCPLEN(seg)
((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) &
\
#define TCP_TCPLEN(seg) \
(TCP_FIN | TCP_SYN)) != 0))
((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) &
(TCP_FIN | TCP_SYN)) != 0))
struct
tcp_hdr
{
struct
tcp_hdr
{
uint16_t
src
;
uint16_t
src
;
...
@@ -167,7 +167,6 @@ struct tcp_hdr {
...
@@ -167,7 +167,6 @@ struct tcp_hdr {
uint16_t
urgp
;
uint16_t
urgp
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/******************************************************************************/
/******************************************************************************/
/* UDP */
/* UDP */
...
@@ -178,7 +177,6 @@ struct udp_hdr {
...
@@ -178,7 +177,6 @@ struct udp_hdr {
uint16_t
chksum
;
uint16_t
chksum
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/******************************************************************************/
/******************************************************************************/
/* whole packets */
/* whole packets */
...
@@ -189,18 +187,18 @@ struct pkt_arp {
...
@@ -189,18 +187,18 @@ struct pkt_arp {
struct
pkt_ip
{
struct
pkt_ip
{
struct
eth_hdr
eth
;
struct
eth_hdr
eth
;
struct
ip_hdr
ip
;
struct
ip_hdr
ip
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
struct
pkt_tcp
{
struct
pkt_tcp
{
struct
eth_hdr
eth
;
struct
eth_hdr
eth
;
struct
ip_hdr
ip
;
struct
ip_hdr
ip
;
struct
tcp_hdr
tcp
;
struct
tcp_hdr
tcp
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
struct
pkt_udp
{
struct
pkt_udp
{
struct
eth_hdr
eth
;
struct
eth_hdr
eth
;
struct
ip_hdr
ip
;
struct
ip_hdr
ip
;
struct
udp_hdr
udp
;
struct
udp_hdr
udp
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
...
...
sims/nic/i40e_bm/i40e_adminq.cc
View file @
d4666c97
...
@@ -24,409 +24,400 @@
...
@@ -24,409 +24,400 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <cassert>
#include <cassert>
#include <iostream>
#include <iostream>
#include "sims/nic/i40e_bm/i40e_bm.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_bm.h"
using
namespace
i40e
;
using
namespace
i40e
;
extern
nicbm
::
Runner
*
runner
;
extern
nicbm
::
Runner
*
runner
;
queue_admin_tx
::
queue_admin_tx
(
i40e_bm
&
dev_
,
uint64_t
&
reg_base_
,
queue_admin_tx
::
queue_admin_tx
(
i40e_bm
&
dev_
,
uint64_t
&
reg_base_
,
uint32_t
&
reg_len_
,
uint32_t
&
reg_head_
,
uint32_t
&
reg_tail_
)
uint32_t
&
reg_len_
,
uint32_t
&
reg_head_
,
:
queue_base
(
"atx"
,
reg_head_
,
reg_tail_
),
dev
(
dev_
),
reg_base
(
reg_base_
),
uint32_t
&
reg_tail_
)
reg_len
(
reg_len_
)
:
queue_base
(
"atx"
,
reg_head_
,
reg_tail_
),
{
dev
(
dev_
),
desc_len
=
32
;
reg_base
(
reg_base_
),
ctxs_init
();
reg_len
(
reg_len_
)
{
desc_len
=
32
;
ctxs_init
();
}
}
queue_base
::
desc_ctx
&
queue_admin_tx
::
desc_ctx_create
()
queue_base
::
desc_ctx
&
queue_admin_tx
::
desc_ctx_create
()
{
{
return
*
new
admin_desc_ctx
(
*
this
,
dev
);
return
*
new
admin_desc_ctx
(
*
this
,
dev
);
}
}
void
queue_admin_tx
::
reg_updated
()
void
queue_admin_tx
::
reg_updated
()
{
{
base
=
reg_base
;
base
=
reg_base
;
len
=
(
reg_len
&
I40E_GL_ATQLEN_ATQLEN_MASK
)
>>
I40E_GL_ATQLEN_ATQLEN_SHIFT
;
len
=
(
reg_len
&
I40E_GL_ATQLEN_ATQLEN_MASK
)
>>
I40E_GL_ATQLEN_ATQLEN_SHIFT
;
if
(
!
enabled
&&
(
reg_len
&
I40E_GL_ATQLEN_ATQENABLE_MASK
))
{
if
(
!
enabled
&&
(
reg_len
&
I40E_GL_ATQLEN_ATQENABLE_MASK
))
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
log
<<
" enable base="
<<
base
<<
" len="
<<
len
<<
log
<<
" enable base="
<<
base
<<
" len="
<<
len
<<
logger
::
endl
;
logger
::
endl
;
#endif
#endif
enabled
=
true
;
enabled
=
true
;
}
else
if
(
enabled
&&
!
(
reg_len
&
I40E_GL_ATQLEN_ATQENABLE_MASK
))
{
}
else
if
(
enabled
&&
!
(
reg_len
&
I40E_GL_ATQLEN_ATQENABLE_MASK
))
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
log
<<
" disable"
<<
logger
::
endl
;
log
<<
" disable"
<<
logger
::
endl
;
#endif
#endif
enabled
=
false
;
enabled
=
false
;
}
}
queue_base
::
reg_updated
();
queue_base
::
reg_updated
();
}
}
queue_admin_tx
::
admin_desc_ctx
::
admin_desc_ctx
(
queue_admin_tx
&
queue_
,
queue_admin_tx
::
admin_desc_ctx
::
admin_desc_ctx
(
queue_admin_tx
&
queue_
,
i40e_bm
&
dev_
)
i40e_bm
&
dev_
)
:
i40e
::
queue_base
::
desc_ctx
(
queue_
),
aq
(
queue_
),
dev
(
dev_
)
:
i40e
::
queue_base
::
desc_ctx
(
queue_
),
aq
(
queue_
),
dev
(
dev_
)
{
{
d
=
reinterpret_cast
<
struct
i40e_aq_desc
*>
(
desc
);
d
=
reinterpret_cast
<
struct
i40e_aq_desc
*>
(
desc
);
}
}
void
queue_admin_tx
::
admin_desc_ctx
::
data_written
(
uint64_t
addr
,
size_t
len
)
void
queue_admin_tx
::
admin_desc_ctx
::
data_written
(
uint64_t
addr
,
size_t
len
)
{
{
processed
();
processed
();
}
}
void
queue_admin_tx
::
admin_desc_ctx
::
desc_compl_prepare
(
uint16_t
retval
,
void
queue_admin_tx
::
admin_desc_ctx
::
desc_compl_prepare
(
uint16_t
retval
,
uint16_t
extra_flags
)
uint16_t
extra_flags
)
{
{
d
->
flags
&=
~
0x1ff
;
d
->
flags
&=
~
0x1ff
;
d
->
flags
|=
I40E_AQ_FLAG_DD
|
I40E_AQ_FLAG_CMP
|
extra_flags
;
d
->
flags
|=
I40E_AQ_FLAG_DD
|
I40E_AQ_FLAG_CMP
|
extra_flags
;
if
(
retval
)
if
(
retval
)
d
->
flags
|=
I40E_AQ_FLAG_ERR
;
d
->
flags
|=
I40E_AQ_FLAG_ERR
;
d
->
retval
=
retval
;
d
->
retval
=
retval
;
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" desc_compl_prepare index="
<<
index
<<
" retval="
<<
queue
.
log
<<
" desc_compl_prepare index="
<<
index
<<
" retval="
<<
retval
retval
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
}
}
void
queue_admin_tx
::
admin_desc_ctx
::
desc_complete
(
uint16_t
retval
,
void
queue_admin_tx
::
admin_desc_ctx
::
desc_complete
(
uint16_t
retval
,
uint16_t
extra_flags
)
uint16_t
extra_flags
)
{
{
desc_compl_prepare
(
retval
,
extra_flags
);
desc_compl_prepare
(
retval
,
extra_flags
);
processed
();
processed
();
}
}
void
queue_admin_tx
::
admin_desc_ctx
::
desc_complete_indir
(
uint16_t
retval
,
void
queue_admin_tx
::
admin_desc_ctx
::
desc_complete_indir
(
uint16_t
retval
,
const
void
*
data
,
size_t
len
,
uint16_t
extra_flags
,
bool
ignore_datalen
)
const
void
*
data
,
{
size_t
len
,
if
(
!
ignore_datalen
&&
len
>
d
->
datalen
)
{
uint16_t
extra_flags
,
queue
.
log
<<
"queue_admin_tx::desc_complete_indir: data too long ("
bool
ignore_datalen
)
{
<<
len
<<
") got buffer for ("
<<
d
->
datalen
<<
")"
<<
logger
::
endl
;
if
(
!
ignore_datalen
&&
len
>
d
->
datalen
)
{
abort
();
queue
.
log
<<
"queue_admin_tx::desc_complete_indir: data too long ("
<<
len
}
<<
") got buffer for ("
<<
d
->
datalen
<<
")"
<<
logger
::
endl
;
d
->
datalen
=
len
;
abort
();
}
desc_compl_prepare
(
retval
,
extra_flags
);
d
->
datalen
=
len
;
uint64_t
addr
=
d
->
params
.
external
.
addr_low
|
desc_compl_prepare
(
retval
,
extra_flags
);
(((
uint64_t
)
d
->
params
.
external
.
addr_high
)
<<
32
);
data_write
(
addr
,
len
,
data
);
uint64_t
addr
=
d
->
params
.
external
.
addr_low
|
(((
uint64_t
)
d
->
params
.
external
.
addr_high
)
<<
32
);
data_write
(
addr
,
len
,
data
);
}
}
void
queue_admin_tx
::
admin_desc_ctx
::
prepare
()
void
queue_admin_tx
::
admin_desc_ctx
::
prepare
()
{
{
if
((
d
->
flags
&
I40E_AQ_FLAG_RD
))
{
if
((
d
->
flags
&
I40E_AQ_FLAG_RD
))
{
uint64_t
addr
=
d
->
params
.
external
.
addr_low
|
uint64_t
addr
=
d
->
params
.
external
.
addr_low
|
(((
uint64_t
)
d
->
params
.
external
.
addr_high
)
<<
32
);
(((
uint64_t
)
d
->
params
.
external
.
addr_high
)
<<
32
);
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" desc with buffer opc="
<<
d
->
opcode
<<
" addr="
<<
queue
.
log
<<
" desc with buffer opc="
<<
d
->
opcode
<<
" addr="
<<
addr
addr
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
data_fetch
(
addr
,
d
->
datalen
);
data_fetch
(
addr
,
d
->
datalen
);
}
else
{
}
else
{
prepared
();
prepared
();
}
}
}
}
void
queue_admin_tx
::
admin_desc_ctx
::
process
()
void
queue_admin_tx
::
admin_desc_ctx
::
process
()
{
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" descriptor "
<<
index
<<
" fetched"
<<
logger
::
endl
;
queue
.
log
<<
" descriptor "
<<
index
<<
" fetched"
<<
logger
::
endl
;
#endif
#endif
if
(
d
->
opcode
==
i40e_aqc_opc_get_version
)
{
if
(
d
->
opcode
==
i40e_aqc_opc_get_version
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" get version"
<<
logger
::
endl
;
queue
.
log
<<
" get version"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_get_version
*
gv
=
struct
i40e_aqc_get_version
*
gv
=
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
=
0
;
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
;
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_request_resource
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_request_resource
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" request resource"
<<
logger
::
endl
;
queue
.
log
<<
" request resource"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_request_resource
*
rr
=
struct
i40e_aqc_request_resource
*
rr
=
reinterpret_cast
<
struct
i40e_aqc_request_resource
*>
(
reinterpret_cast
<
struct
i40e_aqc_request_resource
*>
(
d
->
params
.
raw
);
d
->
params
.
raw
);
rr
->
timeout
=
180000
;
rr
->
timeout
=
180000
;
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" res_id="
<<
rr
->
resource_id
<<
logger
::
endl
;
queue
.
log
<<
" res_id="
<<
rr
->
resource_id
<<
logger
::
endl
;
queue
.
log
<<
" res_nu="
<<
rr
->
resource_number
<<
logger
::
endl
;
queue
.
log
<<
" res_nu="
<<
rr
->
resource_number
<<
logger
::
endl
;
#endif
#endif
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_release_resource
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_release_resource
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" release resource"
<<
logger
::
endl
;
queue
.
log
<<
" release resource"
<<
logger
::
endl
;
#endif
#endif
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
struct
i40e_aqc_request_resource
*
rr
=
struct
i40e_aqc_request_resource
*
rr
=
reinterpret_cast
<
struct
i40e_aqc_request_resource
*>
(
reinterpret_cast
<
struct
i40e_aqc_request_resource
*>
(
d
->
params
.
raw
);
d
->
params
.
raw
);
queue
.
log
<<
" res_id="
<<
rr
->
resource_id
<<
logger
::
endl
;
queue
.
log
<<
" res_id="
<<
rr
->
resource_id
<<
logger
::
endl
;
queue
.
log
<<
" res_nu="
<<
rr
->
resource_number
<<
logger
::
endl
;
queue
.
log
<<
" res_nu="
<<
rr
->
resource_number
<<
logger
::
endl
;
#endif
#endif
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_clear_pxe_mode
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_clear_pxe_mode
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" clear PXE mode"
<<
logger
::
endl
;
queue
.
log
<<
" clear PXE mode"
<<
logger
::
endl
;
#endif
#endif
dev
.
regs
.
gllan_rctl_0
&=
~
I40E_GLLAN_RCTL_0_PXE_MODE_MASK
;
dev
.
regs
.
gllan_rctl_0
&=
~
I40E_GLLAN_RCTL_0_PXE_MODE_MASK
;
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_list_func_capabilities
||
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_list_func_capabilities
||
d
->
opcode
==
i40e_aqc_opc_list_dev_capabilities
)
{
d
->
opcode
==
i40e_aqc_opc_list_dev_capabilities
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" get dev/fun caps"
<<
logger
::
endl
;
queue
.
log
<<
" get dev/fun caps"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_list_capabilites
*
lc
=
struct
i40e_aqc_list_capabilites
*
lc
=
reinterpret_cast
<
struct
i40e_aqc_list_capabilites
*>
(
reinterpret_cast
<
struct
i40e_aqc_list_capabilites
*>
(
d
->
params
.
raw
);
d
->
params
.
raw
);
struct
i40e_aqc_list_capabilities_element_resp
caps
[]
=
{
struct
i40e_aqc_list_capabilities_element_resp
caps
[]
=
{
{
I40E_AQ_CAP_ID_RSS
,
1
,
0
,
512
,
6
,
0
,
{}},
{
I40E_AQ_CAP_ID_RSS
,
1
,
0
,
512
,
6
,
0
,
{}
},
{
I40E_AQ_CAP_ID_RXQ
,
1
,
0
,
dev
.
NUM_QUEUES
,
0
,
0
,
{}},
{
I40E_AQ_CAP_ID_RXQ
,
1
,
0
,
dev
.
NUM_QUEUES
,
0
,
0
,
{}
},
{
I40E_AQ_CAP_ID_TXQ
,
1
,
0
,
dev
.
NUM_QUEUES
,
0
,
0
,
{}},
{
I40E_AQ_CAP_ID_TXQ
,
1
,
0
,
dev
.
NUM_QUEUES
,
0
,
0
,
{}
},
{
I40E_AQ_CAP_ID_MSIX
,
1
,
0
,
dev
.
NUM_PFINTS
,
0
,
0
,
{}},
{
I40E_AQ_CAP_ID_MSIX
,
1
,
0
,
dev
.
NUM_PFINTS
,
0
,
0
,
{}
},
{
I40E_AQ_CAP_ID_VSI
,
1
,
0
,
dev
.
NUM_VSIS
,
0
,
0
,
{}},
{
I40E_AQ_CAP_ID_VSI
,
1
,
0
,
dev
.
NUM_VSIS
,
0
,
0
,
{}
},
{
I40E_AQ_CAP_ID_DCB
,
1
,
0
,
1
,
1
,
1
,
{}},
{
I40E_AQ_CAP_ID_DCB
,
1
,
0
,
1
,
1
,
1
,
{}
},
};
};
size_t
num_caps
=
sizeof
(
caps
)
/
sizeof
(
caps
[
0
]);
size_t
num_caps
=
sizeof
(
caps
)
/
sizeof
(
caps
[
0
]);
if
(
sizeof
(
caps
)
<=
d
->
datalen
)
{
if
(
sizeof
(
caps
)
<=
d
->
datalen
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" data fits"
<<
logger
::
endl
;
queue
.
log
<<
" data fits"
<<
logger
::
endl
;
#endif
#endif
// data fits within the buffer
// data fits within the buffer
lc
->
count
=
num_caps
;
lc
->
count
=
num_caps
;
desc_complete_indir
(
0
,
caps
,
sizeof
(
caps
));
desc_complete_indir
(
0
,
caps
,
sizeof
(
caps
));
}
else
{
}
else
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" data doesn't fit"
<<
logger
::
endl
;
queue
.
log
<<
" data doesn't fit"
<<
logger
::
endl
;
#endif
#endif
// data does not fit
// data does not fit
d
->
datalen
=
sizeof
(
caps
);
d
->
datalen
=
sizeof
(
caps
);
desc_complete
(
I40E_AQ_RC_ENOMEM
);
desc_complete
(
I40E_AQ_RC_ENOMEM
);
}
}
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_lldp_stop
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_lldp_stop
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" lldp stop"
<<
logger
::
endl
;
queue
.
log
<<
" lldp stop"
<<
logger
::
endl
;
#endif
#endif
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_mac_address_read
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_mac_address_read
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" read mac"
<<
logger
::
endl
;
queue
.
log
<<
" read mac"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_mac_address_read
*
ar
=
struct
i40e_aqc_mac_address_read
*
ar
=
reinterpret_cast
<
struct
i40e_aqc_mac_address_read
*>
(
reinterpret_cast
<
struct
i40e_aqc_mac_address_read
*>
(
d
->
params
.
raw
);
d
->
params
.
raw
);
struct
i40e_aqc_mac_address_read_data
ard
;
struct
i40e_aqc_mac_address_read_data
ard
;
uint64_t
mac
=
runner
->
get_mac_addr
();
uint64_t
mac
=
runner
->
get_mac_addr
();
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" mac = "
<<
mac
<<
logger
::
endl
;
queue
.
log
<<
" mac = "
<<
mac
<<
logger
::
endl
;
#endif
#endif
memcpy
(
ard
.
pf_lan_mac
,
&
mac
,
6
);
memcpy
(
ard
.
pf_lan_mac
,
&
mac
,
6
);
memcpy
(
ard
.
port_mac
,
&
mac
,
6
);
memcpy
(
ard
.
port_mac
,
&
mac
,
6
);
ar
->
command_flags
=
I40E_AQC_LAN_ADDR_VALID
|
I40E_AQC_PORT_ADDR_VALID
;
ar
->
command_flags
=
I40E_AQC_LAN_ADDR_VALID
|
I40E_AQC_PORT_ADDR_VALID
;
desc_complete_indir
(
0
,
&
ard
,
sizeof
(
ard
));
desc_complete_indir
(
0
,
&
ard
,
sizeof
(
ard
));
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_phy_abilities
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_phy_abilities
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" get phy abilities"
<<
logger
::
endl
;
queue
.
log
<<
" get phy abilities"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aq_get_phy_abilities_resp
par
;
struct
i40e_aq_get_phy_abilities_resp
par
;
memset
(
&
par
,
0
,
sizeof
(
par
));
memset
(
&
par
,
0
,
sizeof
(
par
));
par
.
phy_type
=
(
1ULL
<<
I40E_PHY_TYPE_40GBASE_CR4_CU
);
par
.
phy_type
=
(
1ULL
<<
I40E_PHY_TYPE_40GBASE_CR4_CU
);
par
.
link_speed
=
I40E_LINK_SPEED_40GB
;
par
.
link_speed
=
I40E_LINK_SPEED_40GB
;
par
.
abilities
=
I40E_AQ_PHY_LINK_ENABLED
|
par
.
abilities
=
I40E_AQ_PHY_LINK_ENABLED
|
I40E_AQ_PHY_AN_ENABLED
;
I40E_AQ_PHY_AN_ENABLED
;
par
.
eee_capability
=
0
;
par
.
eee_capability
=
0
;
d
->
params
.
external
.
param0
=
0
;
d
->
params
.
external
.
param0
=
0
;
d
->
params
.
external
.
param1
=
0
;
d
->
params
.
external
.
param1
=
0
;
desc_complete_indir
(
0
,
&
par
,
sizeof
(
par
),
0
,
true
);
desc_complete_indir
(
0
,
&
par
,
sizeof
(
par
),
0
,
true
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_link_status
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_link_status
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" link status"
<<
logger
::
endl
;
queue
.
log
<<
" link status"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_get_link_status
*
gls
=
struct
i40e_aqc_get_link_status
*
gls
=
reinterpret_cast
<
struct
i40e_aqc_get_link_status
*>
(
reinterpret_cast
<
struct
i40e_aqc_get_link_status
*>
(
d
->
params
.
raw
);
d
->
params
.
raw
);
gls
->
command_flags
&=
I40E_AQ_LSE_IS_ENABLED
;
// should actually return
gls
->
command_flags
&=
I40E_AQ_LSE_IS_ENABLED
;
// should actually return
// status of link status
// status of link status
// notification
// notification
gls
->
phy_type
=
I40E_PHY_TYPE_40GBASE_CR4_CU
;
gls
->
phy_type
=
I40E_PHY_TYPE_40GBASE_CR4_CU
;
gls
->
link_speed
=
I40E_LINK_SPEED_40GB
;
gls
->
link_speed
=
I40E_LINK_SPEED_40GB
;
gls
->
link_info
=
I40E_AQ_LINK_UP_FUNCTION
|
I40E_AQ_LINK_UP_PORT
|
gls
->
link_info
=
I40E_AQ_LINK_UP_FUNCTION
|
I40E_AQ_LINK_UP_PORT
|
I40E_AQ_MEDIA_AVAILABLE
|
I40E_AQ_SIGNAL_DETECT
;
I40E_AQ_MEDIA_AVAILABLE
|
I40E_AQ_SIGNAL_DETECT
;
// might need qualified module
// might need qualified module
gls
->
an_info
=
I40E_AQ_AN_COMPLETED
|
I40E_AQ_LP_AN_ABILITY
;
gls
->
an_info
=
I40E_AQ_AN_COMPLETED
|
I40E_AQ_LP_AN_ABILITY
;
gls
->
ext_info
=
0
;
gls
->
ext_info
=
0
;
gls
->
loopback
=
I40E_AQ_LINK_POWER_CLASS_4
<<
I40E_AQ_PWR_CLASS_SHIFT_LB
;
gls
->
loopback
=
I40E_AQ_LINK_POWER_CLASS_4
<<
gls
->
max_frame_size
=
dev
.
MAX_MTU
;
I40E_AQ_PWR_CLASS_SHIFT_LB
;
gls
->
config
=
I40E_AQ_CONFIG_CRC_ENA
;
gls
->
max_frame_size
=
dev
.
MAX_MTU
;
gls
->
config
=
I40E_AQ_CONFIG_CRC_ENA
;
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_switch_config
)
{
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_switch_config
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" get switch config"
<<
logger
::
endl
;
queue
.
log
<<
" get switch config"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_switch_seid
*
sw
=
reinterpret_cast
<
struct
i40e_aqc_switch_seid
*
sw
=
struct
i40e_aqc_switch_seid
*>
(
d
->
params
.
raw
);
reinterpret_cast
<
struct
i40e_aqc_switch_seid
*>
(
d
->
params
.
raw
);
struct
i40e_aqc_get_switch_config_header_resp
hr
;
struct
i40e_aqc_get_switch_config_header_resp
hr
;
/* Not sure why dpdk doesn't like this?
/* Not sure why dpdk doesn't like this?
struct i40e_aqc_switch_config_element_resp els[] = {
struct i40e_aqc_switch_config_element_resp els[] = {
// EMC
// EMC
{ I40E_AQ_SW_ELEM_TYPE_EMP, I40E_AQ_SW_ELEM_REV_1, 1, 513, 0, {},
{ I40E_AQ_SW_ELEM_TYPE_EMP, I40E_AQ_SW_ELEM_REV_1, 1, 513, 0, {},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
// MAC
// MAC
{ I40E_AQ_SW_ELEM_TYPE_MAC, I40E_AQ_SW_ELEM_REV_1, 2, 0, 0, {},
{ I40E_AQ_SW_ELEM_TYPE_MAC, I40E_AQ_SW_ELEM_REV_1, 2, 0, 0, {},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
// PF
// PF
{ I40E_AQ_SW_ELEM_TYPE_PF, I40E_AQ_SW_ELEM_REV_1, 16, 512, 0, {},
{ I40E_AQ_SW_ELEM_TYPE_PF, I40E_AQ_SW_ELEM_REV_1, 16, 512, 0, {},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
// VSI PF
// VSI PF
{ I40E_AQ_SW_ELEM_TYPE_VSI, I40E_AQ_SW_ELEM_REV_1, 512, 2, 16, {},
{ I40E_AQ_SW_ELEM_TYPE_VSI, I40E_AQ_SW_ELEM_REV_1, 512, 2, 16, {},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
// VSI PF
// VSI PF
{ I40E_AQ_SW_ELEM_TYPE_VSI, I40E_AQ_SW_ELEM_REV_1, 513, 2, 1, {},
{ I40E_AQ_SW_ELEM_TYPE_VSI, I40E_AQ_SW_ELEM_REV_1, 513, 2, 1, {},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
I40E_AQ_CONN_TYPE_REGULAR, 0, 0},
};*/
};*/
struct
i40e_aqc_switch_config_element_resp
els
[]
=
{
struct
i40e_aqc_switch_config_element_resp
els
[]
=
{
// VSI PF
// VSI PF
{
I40E_AQ_SW_ELEM_TYPE_VSI
,
I40E_AQ_SW_ELEM_REV_1
,
512
,
2
,
16
,
{},
{
I40E_AQ_SW_ELEM_TYPE_VSI
,
I40E_AQ_CONN_TYPE_REGULAR
,
0
,
0
},
I40E_AQ_SW_ELEM_REV_1
,
};
512
,
2
,
16
,
// find start idx
{},
size_t
cnt
=
sizeof
(
els
)
/
sizeof
(
els
[
0
]);
I40E_AQ_CONN_TYPE_REGULAR
,
size_t
first
=
0
;
0
,
for
(
first
=
0
;
first
<
cnt
&&
els
[
first
].
seid
<
sw
->
seid
;
first
++
)
{}
0
},
};
// figure out how many fit in the buffer
size_t
max
=
(
d
->
datalen
-
sizeof
(
hr
))
/
sizeof
(
els
[
0
]);
// find start idx
size_t
report
=
cnt
-
first
;
size_t
cnt
=
sizeof
(
els
)
/
sizeof
(
els
[
0
]);
if
(
report
>
max
)
{
size_t
first
=
0
;
report
=
max
;
for
(
first
=
0
;
first
<
cnt
&&
els
[
first
].
seid
<
sw
->
seid
;
first
++
)
{
sw
->
seid
=
els
[
first
+
report
].
seid
;
}
}
else
{
sw
->
seid
=
0
;
// figure out how many fit in the buffer
}
size_t
max
=
(
d
->
datalen
-
sizeof
(
hr
))
/
sizeof
(
els
[
0
]);
size_t
report
=
cnt
-
first
;
// prepare header
if
(
report
>
max
)
{
memset
(
&
hr
,
0
,
sizeof
(
hr
));
report
=
max
;
hr
.
num_reported
=
report
;
sw
->
seid
=
els
[
first
+
report
].
seid
;
hr
.
num_total
=
cnt
;
}
else
{
sw
->
seid
=
0
;
}
// prepare header
memset
(
&
hr
,
0
,
sizeof
(
hr
));
hr
.
num_reported
=
report
;
hr
.
num_total
=
cnt
;
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" report="
<<
report
<<
" cnt="
<<
cnt
<<
queue
.
log
<<
" report="
<<
report
<<
" cnt="
<<
cnt
" seid="
<<
sw
->
seid
<<
logger
::
endl
;
<<
" seid="
<<
sw
->
seid
<<
logger
::
endl
;
#endif
#endif
// create temporary contiguous buffer
// create temporary contiguous buffer
size_t
buflen
=
sizeof
(
hr
)
+
sizeof
(
els
[
0
])
*
report
;
size_t
buflen
=
sizeof
(
hr
)
+
sizeof
(
els
[
0
])
*
report
;
uint8_t
buf
[
buflen
];
uint8_t
buf
[
buflen
];
memcpy
(
buf
,
&
hr
,
sizeof
(
hr
));
memcpy
(
buf
,
&
hr
,
sizeof
(
hr
));
memcpy
(
buf
+
sizeof
(
hr
),
els
+
first
,
sizeof
(
els
[
0
])
*
report
);
memcpy
(
buf
+
sizeof
(
hr
),
els
+
first
,
sizeof
(
els
[
0
])
*
report
);
desc_complete_indir
(
0
,
buf
,
buflen
);
desc_complete_indir
(
0
,
buf
,
buflen
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_set_switch_config
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_set_switch_config
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" set switch config"
<<
logger
::
endl
;
queue
.
log
<<
" set switch config"
<<
logger
::
endl
;
#endif
#endif
/* TODO: lots of interesting things here like l2 filtering etc. that are
/* TODO: lots of interesting things here like l2 filtering etc. that are
* relevant.
* relevant.
struct i40e_aqc_set_switch_config *sc =
struct i40e_aqc_set_switch_config *sc =
reinterpret_cast<struct i40e_aqc_set_switch_config *>(
reinterpret_cast<struct i40e_aqc_set_switch_config *>(
d->params.raw);
d->params.raw);
*/
*/
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_vsi_parameters
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_get_vsi_parameters
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" get vsi parameters"
<<
logger
::
endl
;
queue
.
log
<<
" get vsi parameters"
<<
logger
::
endl
;
#endif
#endif
/*struct i40e_aqc_add_get_update_vsi *v =
/*struct i40e_aqc_add_get_update_vsi *v =
reinterpret_cast<struct i40e_aqc_add_get_update_vsi *>(
reinterpret_cast<struct i40e_aqc_add_get_update_vsi *>(
d->params.raw);*/
d->params.raw);*/
struct
i40e_aqc_vsi_properties_data
pd
;
struct
i40e_aqc_vsi_properties_data
pd
;
memset
(
&
pd
,
0
,
sizeof
(
pd
));
memset
(
&
pd
,
0
,
sizeof
(
pd
));
pd
.
valid_sections
|=
I40E_AQ_VSI_PROP_SWITCH_VALID
|
pd
.
valid_sections
|=
I40E_AQ_VSI_PROP_QUEUE_MAP_VALID
|
I40E_AQ_VSI_PROP_SWITCH_VALID
|
I40E_AQ_VSI_PROP_QUEUE_MAP_VALID
|
I40E_AQ_VSI_PROP_QUEUE_OPT_VALID
|
I40E_AQ_VSI_PROP_QUEUE_OPT_VALID
|
I40E_AQ_VSI_PROP_SCHED_VALID
;
I40E_AQ_VSI_PROP_SCHED_VALID
;
desc_complete_indir
(
0
,
&
pd
,
sizeof
(
pd
));
desc_complete_indir
(
0
,
&
pd
,
sizeof
(
pd
));
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_update_vsi_parameters
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_update_vsi_parameters
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" update vsi parameters"
<<
logger
::
endl
;
queue
.
log
<<
" update vsi parameters"
<<
logger
::
endl
;
#endif
#endif
/* TODO */
/* TODO */
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_set_dcb_parameters
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_set_dcb_parameters
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" set dcb parameters"
<<
logger
::
endl
;
queue
.
log
<<
" set dcb parameters"
<<
logger
::
endl
;
#endif
#endif
/* TODO */
/* TODO */
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_configure_vsi_bw_limit
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_configure_vsi_bw_limit
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" configure vsi bw limit"
<<
logger
::
endl
;
queue
.
log
<<
" configure vsi bw limit"
<<
logger
::
endl
;
#endif
#endif
desc_complete
(
0
);
desc_complete
(
0
);
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_query_vsi_bw_config
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_query_vsi_bw_config
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" query vsi bw config"
<<
logger
::
endl
;
queue
.
log
<<
" query vsi bw config"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_query_vsi_bw_config_resp
bwc
;
struct
i40e_aqc_query_vsi_bw_config_resp
bwc
;
memset
(
&
bwc
,
0
,
sizeof
(
bwc
));
memset
(
&
bwc
,
0
,
sizeof
(
bwc
));
for
(
size_t
i
=
0
;
i
<
8
;
i
++
)
for
(
size_t
i
=
0
;
i
<
8
;
i
++
)
bwc
.
qs_handles
[
i
]
=
0xffff
;
bwc
.
qs_handles
[
i
]
=
0xffff
;
desc_complete_indir
(
0
,
&
bwc
,
sizeof
(
bwc
));
desc_complete_indir
(
0
,
&
bwc
,
sizeof
(
bwc
));
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_query_vsi_ets_sla_config
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_query_vsi_ets_sla_config
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" query vsi ets sla config"
<<
logger
::
endl
;
queue
.
log
<<
" query vsi ets sla config"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_query_vsi_ets_sla_config_resp
sla
;
struct
i40e_aqc_query_vsi_ets_sla_config_resp
sla
;
memset
(
&
sla
,
0
,
sizeof
(
sla
));
memset
(
&
sla
,
0
,
sizeof
(
sla
));
for
(
size_t
i
=
0
;
i
<
8
;
i
++
)
for
(
size_t
i
=
0
;
i
<
8
;
i
++
)
sla
.
share_credits
[
i
]
=
127
;
sla
.
share_credits
[
i
]
=
127
;
desc_complete_indir
(
0
,
&
sla
,
sizeof
(
sla
));
desc_complete_indir
(
0
,
&
sla
,
sizeof
(
sla
));
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_remove_macvlan
)
{
}
else
if
(
d
->
opcode
==
i40e_aqc_opc_remove_macvlan
)
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" remove macvlan"
<<
logger
::
endl
;
queue
.
log
<<
" remove macvlan"
<<
logger
::
endl
;
#endif
#endif
struct
i40e_aqc_macvlan
*
m
=
reinterpret_cast
<
struct
i40e_aqc_macvlan
*
m
=
struct
i40e_aqc_macvlan
*>
(
d
->
params
.
raw
);
reinterpret_cast
<
struct
i40e_aqc_macvlan
*>
(
d
->
params
.
raw
);
struct
i40e_aqc_remove_macvlan_element_data
*
rve
=
struct
i40e_aqc_remove_macvlan_element_data
*
rve
=
reinterpret_cast
<
struct
i40e_aqc_remove_macvlan_element_data
*>
(
reinterpret_cast
<
struct
i40e_aqc_remove_macvlan_element_data
*>
(
data
);
data
);
for
(
uint16_t
i
=
0
;
i
<
m
->
num_addresses
;
i
++
)
for
(
uint16_t
i
=
0
;
i
<
m
->
num_addresses
;
i
++
)
rve
[
i
].
error_code
=
I40E_AQC_REMOVE_MACVLAN_SUCCESS
;
rve
[
i
].
error_code
=
I40E_AQC_REMOVE_MACVLAN_SUCCESS
;
desc_complete_indir
(
0
,
data
,
d
->
datalen
);
desc_complete_indir
(
0
,
data
,
d
->
datalen
);
}
else
{
}
else
{
#ifdef DEBUG_ADMINQ
#ifdef DEBUG_ADMINQ
queue
.
log
<<
" uknown opcode="
<<
d
->
opcode
<<
logger
::
endl
;
queue
.
log
<<
" uknown opcode="
<<
d
->
opcode
<<
logger
::
endl
;
#endif
#endif
// desc_complete(I40E_AQ_RC_ESRCH);
// desc_complete(I40E_AQ_RC_ESRCH);
desc_complete
(
0
);
desc_complete
(
0
);
}
}
}
}
sims/nic/i40e_bm/i40e_base_wrapper.h
View file @
d4666c97
...
@@ -17,84 +17,84 @@ typedef uint16_t __le16;
...
@@ -17,84 +17,84 @@ typedef uint16_t __le16;
typedef
uint32_t
__le32
;
typedef
uint32_t
__le32
;
typedef
uint64_t
__le64
;
typedef
uint64_t
__le64
;
#include "sims/nic/i40e_bm/base/i40e_adminq_cmd.h"
#include "sims/nic/i40e_bm/base/i40e_devids.h"
#include "sims/nic/i40e_bm/base/i40e_devids.h"
#include "sims/nic/i40e_bm/base/i40e_register.h"
#include "sims/nic/i40e_bm/base/i40e_register.h"
#include "sims/nic/i40e_bm/base/i40e_adminq_cmd.h"
#include "sims/nic/i40e_bm/base/i40e_rxtxq.h"
#include "sims/nic/i40e_bm/base/i40e_rxtxq.h"
/* from i40e_types.h */
/* from i40e_types.h */
/* Checksum and Shadow RAM pointers */
/* Checksum and Shadow RAM pointers */
#define I40E_SR_NVM_CONTROL_WORD
0x00
#define I40E_SR_NVM_CONTROL_WORD 0x00
#define I40E_SR_PCIE_ANALOG_CONFIG_PTR
0x03
#define I40E_SR_PCIE_ANALOG_CONFIG_PTR 0x03
#define I40E_SR_PHY_ANALOG_CONFIG_PTR
0x04
#define I40E_SR_PHY_ANALOG_CONFIG_PTR 0x04
#define I40E_SR_OPTION_ROM_PTR
0x05
#define I40E_SR_OPTION_ROM_PTR 0x05
#define I40E_SR_RO_PCIR_REGS_AUTO_LOAD_PTR
0x06
#define I40E_SR_RO_PCIR_REGS_AUTO_LOAD_PTR 0x06
#define I40E_SR_AUTO_GENERATED_POINTERS_PTR
0x07
#define I40E_SR_AUTO_GENERATED_POINTERS_PTR 0x07
#define I40E_SR_PCIR_REGS_AUTO_LOAD_PTR
0x08
#define I40E_SR_PCIR_REGS_AUTO_LOAD_PTR 0x08
#define I40E_SR_EMP_GLOBAL_MODULE_PTR
0x09
#define I40E_SR_EMP_GLOBAL_MODULE_PTR 0x09
#define I40E_SR_RO_PCIE_LCB_PTR
0x0A
#define I40E_SR_RO_PCIE_LCB_PTR 0x0A
#define I40E_SR_EMP_IMAGE_PTR
0x0B
#define I40E_SR_EMP_IMAGE_PTR 0x0B
#define I40E_SR_PE_IMAGE_PTR
0x0C
#define I40E_SR_PE_IMAGE_PTR 0x0C
#define I40E_SR_CSR_PROTECTED_LIST_PTR
0x0D
#define I40E_SR_CSR_PROTECTED_LIST_PTR 0x0D
#define I40E_SR_MNG_CONFIG_PTR
0x0E
#define I40E_SR_MNG_CONFIG_PTR 0x0E
#define I40E_EMP_MODULE_PTR
0x0F
#define I40E_EMP_MODULE_PTR 0x0F
#define I40E_SR_EMP_MODULE_PTR
0x48
#define I40E_SR_EMP_MODULE_PTR 0x48
#define I40E_SR_PBA_FLAGS
0x15
#define I40E_SR_PBA_FLAGS 0x15
#define I40E_SR_PBA_BLOCK_PTR
0x16
#define I40E_SR_PBA_BLOCK_PTR 0x16
#define I40E_SR_BOOT_CONFIG_PTR
0x17
#define I40E_SR_BOOT_CONFIG_PTR 0x17
#define I40E_NVM_OEM_VER_OFF
0x83
#define I40E_NVM_OEM_VER_OFF 0x83
#define I40E_SR_NVM_DEV_STARTER_VERSION
0x18
#define I40E_SR_NVM_DEV_STARTER_VERSION 0x18
#define I40E_SR_NVM_WAKE_ON_LAN
0x19
#define I40E_SR_NVM_WAKE_ON_LAN 0x19
#define I40E_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR
0x27
#define I40E_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR 0x27
#define I40E_SR_PERMANENT_SAN_MAC_ADDRESS_PTR
0x28
#define I40E_SR_PERMANENT_SAN_MAC_ADDRESS_PTR 0x28
#define I40E_SR_NVM_MAP_VERSION
0x29
#define I40E_SR_NVM_MAP_VERSION 0x29
#define I40E_SR_NVM_IMAGE_VERSION
0x2A
#define I40E_SR_NVM_IMAGE_VERSION 0x2A
#define I40E_SR_NVM_STRUCTURE_VERSION
0x2B
#define I40E_SR_NVM_STRUCTURE_VERSION 0x2B
#define I40E_SR_NVM_EETRACK_LO
0x2D
#define I40E_SR_NVM_EETRACK_LO 0x2D
#define I40E_SR_NVM_EETRACK_HI
0x2E
#define I40E_SR_NVM_EETRACK_HI 0x2E
#define I40E_SR_VPD_PTR
0x2F
#define I40E_SR_VPD_PTR 0x2F
#define I40E_SR_PXE_SETUP_PTR
0x30
#define I40E_SR_PXE_SETUP_PTR 0x30
#define I40E_SR_PXE_CONFIG_CUST_OPTIONS_PTR
0x31
#define I40E_SR_PXE_CONFIG_CUST_OPTIONS_PTR 0x31
#define I40E_SR_NVM_ORIGINAL_EETRACK_LO
0x34
#define I40E_SR_NVM_ORIGINAL_EETRACK_LO 0x34
#define I40E_SR_NVM_ORIGINAL_EETRACK_HI
0x35
#define I40E_SR_NVM_ORIGINAL_EETRACK_HI 0x35
#define I40E_SR_SW_ETHERNET_MAC_ADDRESS_PTR
0x37
#define I40E_SR_SW_ETHERNET_MAC_ADDRESS_PTR 0x37
#define I40E_SR_POR_REGS_AUTO_LOAD_PTR
0x38
#define I40E_SR_POR_REGS_AUTO_LOAD_PTR 0x38
#define I40E_SR_EMPR_REGS_AUTO_LOAD_PTR
0x3A
#define I40E_SR_EMPR_REGS_AUTO_LOAD_PTR 0x3A
#define I40E_SR_GLOBR_REGS_AUTO_LOAD_PTR
0x3B
#define I40E_SR_GLOBR_REGS_AUTO_LOAD_PTR 0x3B
#define I40E_SR_CORER_REGS_AUTO_LOAD_PTR
0x3C
#define I40E_SR_CORER_REGS_AUTO_LOAD_PTR 0x3C
#define I40E_SR_PHY_ACTIVITY_LIST_PTR
0x3D
#define I40E_SR_PHY_ACTIVITY_LIST_PTR 0x3D
#define I40E_SR_PCIE_ALT_AUTO_LOAD_PTR
0x3E
#define I40E_SR_PCIE_ALT_AUTO_LOAD_PTR 0x3E
#define I40E_SR_SW_CHECKSUM_WORD
0x3F
#define I40E_SR_SW_CHECKSUM_WORD 0x3F
#define I40E_SR_1ST_FREE_PROVISION_AREA_PTR
0x40
#define I40E_SR_1ST_FREE_PROVISION_AREA_PTR 0x40
#define I40E_SR_4TH_FREE_PROVISION_AREA_PTR
0x42
#define I40E_SR_4TH_FREE_PROVISION_AREA_PTR 0x42
#define I40E_SR_3RD_FREE_PROVISION_AREA_PTR
0x44
#define I40E_SR_3RD_FREE_PROVISION_AREA_PTR 0x44
#define I40E_SR_2ND_FREE_PROVISION_AREA_PTR
0x46
#define I40E_SR_2ND_FREE_PROVISION_AREA_PTR 0x46
#define I40E_SR_EMP_SR_SETTINGS_PTR
0x48
#define I40E_SR_EMP_SR_SETTINGS_PTR 0x48
#define I40E_SR_FEATURE_CONFIGURATION_PTR
0x49
#define I40E_SR_FEATURE_CONFIGURATION_PTR 0x49
#define I40E_SR_CONFIGURATION_METADATA_PTR
0x4D
#define I40E_SR_CONFIGURATION_METADATA_PTR 0x4D
#define I40E_SR_IMMEDIATE_VALUES_PTR
0x4E
#define I40E_SR_IMMEDIATE_VALUES_PTR 0x4E
/* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */
/* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */
#define I40E_SR_VPD_MODULE_MAX_SIZE
1024
#define I40E_SR_VPD_MODULE_MAX_SIZE 1024
#define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE
1024
#define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE 1024
#define I40E_SR_CONTROL_WORD_1_SHIFT
0x06
#define I40E_SR_CONTROL_WORD_1_SHIFT 0x06
#define I40E_SR_CONTROL_WORD_1_MASK
(0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
#define I40E_SR_CONTROL_WORD_1_MASK (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
#define I40E_SR_CONTROL_WORD_1_NVM_BANK_VALID
BIT(5)
#define I40E_SR_CONTROL_WORD_1_NVM_BANK_VALID BIT(5)
#define I40E_SR_NVM_MAP_STRUCTURE_TYPE
BIT(12)
#define I40E_SR_NVM_MAP_STRUCTURE_TYPE BIT(12)
#define I40E_PTR_TYPE
BIT(15)
#define I40E_PTR_TYPE BIT(15)
#define I40E_SR_OCP_CFG_WORD0
0x2B
#define I40E_SR_OCP_CFG_WORD0 0x2B
#define I40E_SR_OCP_ENABLED
BIT(15)
#define I40E_SR_OCP_ENABLED BIT(15)
/* Shadow RAM related */
/* Shadow RAM related */
#define I40E_SR_SECTOR_SIZE_IN_WORDS
0x800
#define I40E_SR_SECTOR_SIZE_IN_WORDS 0x800
#define I40E_SR_BUF_ALIGNMENT
4096
#define I40E_SR_BUF_ALIGNMENT 4096
#define I40E_SR_WORDS_IN_1KB
512
#define I40E_SR_WORDS_IN_1KB 512
/* Checksum should be calculated such that after adding all the words,
/* Checksum should be calculated such that after adding all the words,
* including the checksum word itself, the sum should be 0xBABA.
* including the checksum word itself, the sum should be 0xBABA.
*/
*/
#define I40E_SR_SW_CHECKSUM_BASE
0xBABA
#define I40E_SR_SW_CHECKSUM_BASE 0xBABA
#define I40E_SRRD_SRCTL_ATTEMPTS
100000
#define I40E_SRRD_SRCTL_ATTEMPTS 100000
#endif // I40E_BASE_WRAPPER_H_
#endif // I40E_BASE_WRAPPER_H_
sims/nic/i40e_bm/i40e_bm.cc
View file @
d4666c97
...
@@ -22,12 +22,14 @@
...
@@ -22,12 +22,14 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
*/
#include "sims/nic/i40e_bm/i40e_bm.h"
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <cassert>
#include <cassert>
#include <iostream>
#include <iostream>
#include "sims/nic/i40e_bm/i40e_bm.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
nicbm
::
Runner
*
runner
;
nicbm
::
Runner
*
runner
;
...
@@ -36,834 +38,798 @@ namespace i40e {
...
@@ -36,834 +38,798 @@ namespace i40e {
i40e_bm
::
i40e_bm
()
i40e_bm
::
i40e_bm
()
:
log
(
"i40e"
),
:
log
(
"i40e"
),
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
),
shram
(
*
this
),
lanmgr
(
*
this
,
NUM_QUEUES
)
hmc
(
*
this
),
{
shram
(
*
this
),
reset
(
false
);
lanmgr
(
*
this
,
NUM_QUEUES
)
{
reset
(
false
);
}
}
i40e_bm
::~
i40e_bm
()
i40e_bm
::~
i40e_bm
()
{
{
}
}
void
i40e_bm
::
setup_intro
(
struct
cosim_pcie_proto_dev_intro
&
di
)
void
i40e_bm
::
setup_intro
(
struct
cosim_pcie_proto_dev_intro
&
di
)
{
{
di
.
bars
[
BAR_REGS
].
len
=
4
*
1024
*
1024
;
di
.
bars
[
BAR_REGS
].
len
=
4
*
1024
*
1024
;
di
.
bars
[
BAR_REGS
].
flags
=
COSIM_PCIE_PROTO_BAR_64
;
di
.
bars
[
BAR_REGS
].
flags
=
COSIM_PCIE_PROTO_BAR_64
;
di
.
bars
[
BAR_IO
].
len
=
32
;
di
.
bars
[
BAR_IO
].
len
=
32
;
di
.
bars
[
BAR_IO
].
flags
=
COSIM_PCIE_PROTO_BAR_IO
;
di
.
bars
[
BAR_IO
].
flags
=
COSIM_PCIE_PROTO_BAR_IO
;
di
.
bars
[
BAR_MSIX
].
len
=
32
*
1024
;
di
.
bars
[
BAR_MSIX
].
len
=
32
*
1024
;
di
.
bars
[
BAR_MSIX
].
flags
=
di
.
bars
[
BAR_MSIX
].
flags
=
COSIM_PCIE_PROTO_BAR_64
|
COSIM_PCIE_PROTO_BAR_64
|
COSIM_PCIE_PROTO_BAR_DUMMY
;
COSIM_PCIE_PROTO_BAR_DUMMY
;
di
.
pci_vendor_id
=
I40E_INTEL_VENDOR_ID
;
di
.
pci_vendor_id
=
I40E_INTEL_VENDOR_ID
;
di
.
pci_device_id
=
I40E_DEV_ID_QSFP_A
;
di
.
pci_device_id
=
I40E_DEV_ID_QSFP_A
;
di
.
pci_class
=
0x02
;
di
.
pci_class
=
0x02
;
di
.
pci_subclass
=
0x00
;
di
.
pci_subclass
=
0x00
;
di
.
pci_revision
=
0x01
;
di
.
pci_revision
=
0x01
;
di
.
pci_msi_nvecs
=
32
;
di
.
pci_msi_nvecs
=
32
;
di
.
pci_msix_nvecs
=
0x80
;
di
.
pci_msix_nvecs
=
0x80
;
di
.
pci_msix_table_bar
=
BAR_MSIX
;
di
.
pci_msix_table_bar
=
BAR_MSIX
;
di
.
pci_msix_pba_bar
=
BAR_MSIX
;
di
.
pci_msix_pba_bar
=
BAR_MSIX
;
di
.
pci_msix_table_offset
=
0x0
;
di
.
pci_msix_table_offset
=
0x0
;
di
.
pci_msix_pba_offset
=
0x1000
;
di
.
pci_msix_pba_offset
=
0x1000
;
di
.
psi_msix_cap_offset
=
0x70
;
di
.
psi_msix_cap_offset
=
0x70
;
}
}
void
i40e_bm
::
dma_complete
(
nicbm
::
DMAOp
&
op
)
void
i40e_bm
::
dma_complete
(
nicbm
::
DMAOp
&
op
)
{
{
dma_base
&
dma
=
dynamic_cast
<
dma_base
&>
(
op
);
dma_base
&
dma
=
dynamic_cast
<
dma_base
&>
(
op
);
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"dma_complete("
<<
&
op
<<
")"
<<
logger
::
endl
;
log
<<
"dma_complete("
<<
&
op
<<
")"
<<
logger
::
endl
;
#endif
#endif
dma
.
done
();
dma
.
done
();
}
}
void
i40e_bm
::
eth_rx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
)
void
i40e_bm
::
eth_rx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
)
{
{
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"i40e: received packet len="
<<
len
<<
logger
::
endl
;
log
<<
"i40e: received packet len="
<<
len
<<
logger
::
endl
;
#endif
#endif
lanmgr
.
packet_received
(
data
,
len
);
lanmgr
.
packet_received
(
data
,
len
);
}
}
void
i40e_bm
::
reg_read
(
uint8_t
bar
,
uint64_t
addr
,
void
*
dest
,
size_t
len
)
void
i40e_bm
::
reg_read
(
uint8_t
bar
,
uint64_t
addr
,
void
*
dest
,
size_t
len
)
{
{
uint32_t
*
dest_p
=
reinterpret_cast
<
uint32_t
*>
(
dest
);
uint32_t
*
dest_p
=
reinterpret_cast
<
uint32_t
*>
(
dest
);
if
(
len
==
4
)
{
if
(
len
==
4
)
{
dest_p
[
0
]
=
reg_read32
(
bar
,
addr
);
dest_p
[
0
]
=
reg_read32
(
bar
,
addr
);
}
else
if
(
len
==
8
)
{
}
else
if
(
len
==
8
)
{
dest_p
[
0
]
=
reg_read32
(
bar
,
addr
);
dest_p
[
0
]
=
reg_read32
(
bar
,
addr
);
dest_p
[
1
]
=
reg_read32
(
bar
,
addr
+
4
);
dest_p
[
1
]
=
reg_read32
(
bar
,
addr
+
4
);
}
else
{
}
else
{
log
<<
"currently we only support 4/8B reads (got "
<<
len
<<
")"
log
<<
"currently we only support 4/8B reads (got "
<<
len
<<
")"
<<
logger
::
endl
;
<<
logger
::
endl
;
abort
();
abort
();
}
}
}
}
uint32_t
i40e_bm
::
reg_read32
(
uint8_t
bar
,
uint64_t
addr
)
uint32_t
i40e_bm
::
reg_read32
(
uint8_t
bar
,
uint64_t
addr
)
{
{
if
(
bar
==
BAR_REGS
)
{
if
(
bar
==
BAR_REGS
)
{
return
reg_mem_read32
(
addr
);
return
reg_mem_read32
(
addr
);
}
else
if
(
bar
==
BAR_IO
)
{
}
else
if
(
bar
==
BAR_IO
)
{
return
reg_io_read
(
addr
);
return
reg_io_read
(
addr
);
}
else
{
}
else
{
log
<<
"invalid BAR "
<<
(
int
)
bar
<<
logger
::
endl
;
log
<<
"invalid BAR "
<<
(
int
)
bar
<<
logger
::
endl
;
abort
();
abort
();
}
}
}
}
void
i40e_bm
::
reg_write
(
uint8_t
bar
,
uint64_t
addr
,
const
void
*
src
,
size_t
len
)
void
i40e_bm
::
reg_write
(
uint8_t
bar
,
uint64_t
addr
,
const
void
*
src
,
{
size_t
len
)
{
const
uint32_t
*
src_p
=
reinterpret_cast
<
const
uint32_t
*>
(
src
);
const
uint32_t
*
src_p
=
reinterpret_cast
<
const
uint32_t
*>
(
src
);
if
(
len
==
4
)
{
if
(
len
==
4
)
{
reg_write32
(
bar
,
addr
,
src_p
[
0
]);
reg_write32
(
bar
,
addr
,
src_p
[
0
]);
}
else
if
(
len
==
8
)
{
}
else
if
(
len
==
8
)
{
reg_write32
(
bar
,
addr
,
src_p
[
0
]);
reg_write32
(
bar
,
addr
,
src_p
[
0
]);
reg_write32
(
bar
,
addr
+
4
,
src_p
[
1
]);
reg_write32
(
bar
,
addr
+
4
,
src_p
[
1
]);
}
else
{
}
else
{
log
<<
"currently we only support 4/8B writes (got "
<<
len
<<
")"
log
<<
"currently we only support 4/8B writes (got "
<<
len
<<
")"
<<
logger
::
endl
;
<<
logger
::
endl
;
abort
();
abort
();
}
}
}
}
void
i40e_bm
::
reg_write32
(
uint8_t
bar
,
uint64_t
addr
,
uint32_t
val
)
void
i40e_bm
::
reg_write32
(
uint8_t
bar
,
uint64_t
addr
,
uint32_t
val
)
{
{
if
(
bar
==
BAR_REGS
)
{
if
(
bar
==
BAR_REGS
)
{
reg_mem_write32
(
addr
,
val
);
reg_mem_write32
(
addr
,
val
);
}
else
if
(
bar
==
BAR_IO
)
{
}
else
if
(
bar
==
BAR_IO
)
{
reg_io_write
(
addr
,
val
);
reg_io_write
(
addr
,
val
);
}
else
{
}
else
{
log
<<
"invalid BAR "
<<
(
int
)
bar
<<
logger
::
endl
;
log
<<
"invalid BAR "
<<
(
int
)
bar
<<
logger
::
endl
;
abort
();
abort
();
}
}
}
}
uint32_t
i40e_bm
::
reg_io_read
(
uint64_t
addr
)
uint32_t
i40e_bm
::
reg_io_read
(
uint64_t
addr
)
{
{
log
<<
"unhandled io read addr="
<<
addr
<<
logger
::
endl
;
log
<<
"unhandled io read addr="
<<
addr
<<
logger
::
endl
;
return
0
;
return
0
;
}
}
void
i40e_bm
::
reg_io_write
(
uint64_t
addr
,
uint32_t
val
)
void
i40e_bm
::
reg_io_write
(
uint64_t
addr
,
uint32_t
val
)
{
{
log
<<
"unhandled io write addr="
<<
addr
<<
" val="
<<
val
<<
logger
::
endl
;
log
<<
"unhandled io write addr="
<<
addr
<<
" val="
<<
val
<<
logger
::
endl
;
}
}
uint32_t
i40e_bm
::
reg_mem_read32
(
uint64_t
addr
)
uint32_t
i40e_bm
::
reg_mem_read32
(
uint64_t
addr
)
{
{
uint32_t
val
=
0
;
uint32_t
val
=
0
;
if
(
addr
>=
I40E_PFINT_DYN_CTLN
(
0
)
&&
if
(
addr
>=
I40E_PFINT_DYN_CTLN
(
0
)
&&
addr
<
I40E_PFINT_DYN_CTLN
(
NUM_PFINTS
-
1
))
{
addr
<
I40E_PFINT_DYN_CTLN
(
NUM_PFINTS
-
1
))
{
val
=
regs
.
pfint_dyn_ctln
[(
addr
-
I40E_PFINT_DYN_CTLN
(
0
))
/
4
];
val
=
regs
.
pfint_dyn_ctln
[(
addr
-
I40E_PFINT_DYN_CTLN
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_PFINT_LNKLSTN
(
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_LNKLSTN
(
0
)
&&
addr
<=
I40E_PFINT_LNKLSTN
(
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_LNKLSTN
(
NUM_PFINTS
-
1
))
{
val
=
regs
.
pfint_lnklstn
[(
addr
-
I40E_PFINT_LNKLSTN
(
0
))
/
4
];
val
=
regs
.
pfint_lnklstn
[(
addr
-
I40E_PFINT_LNKLSTN
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_PFINT_RATEN
(
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_RATEN
(
0
)
&&
addr
<=
I40E_PFINT_RATEN
(
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_RATEN
(
NUM_PFINTS
-
1
))
{
val
=
regs
.
pfint_raten
[(
addr
-
I40E_PFINT_RATEN
(
0
))
/
4
];
val
=
regs
.
pfint_raten
[(
addr
-
I40E_PFINT_RATEN
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_GLLAN_TXPRE_QDIS
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLLAN_TXPRE_QDIS
(
0
)
&&
addr
<
I40E_GLLAN_TXPRE_QDIS
(
12
))
{
addr
<
I40E_GLLAN_TXPRE_QDIS
(
12
))
{
val
=
regs
.
gllan_txpre_qdis
[(
addr
-
I40E_GLLAN_TXPRE_QDIS
(
0
))
/
4
];
val
=
regs
.
gllan_txpre_qdis
[(
addr
-
I40E_GLLAN_TXPRE_QDIS
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_QINT_TQCTL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QINT_TQCTL
(
0
)
&&
addr
<=
I40E_QINT_TQCTL
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QINT_TQCTL
(
NUM_QUEUES
-
1
))
{
val
=
regs
.
qint_tqctl
[(
addr
-
I40E_QINT_TQCTL
(
0
))
/
4
];
val
=
regs
.
qint_tqctl
[(
addr
-
I40E_QINT_TQCTL
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_QTX_ENA
(
0
)
&&
addr
<=
I40E_QTX_ENA
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QTX_ENA
(
0
)
&&
val
=
regs
.
qtx_ena
[(
addr
-
I40E_QTX_ENA
(
0
))
/
4
];
addr
<=
I40E_QTX_ENA
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QTX_TAIL
(
0
)
&&
val
=
regs
.
qtx_ena
[(
addr
-
I40E_QTX_ENA
(
0
))
/
4
];
addr
<=
I40E_QTX_TAIL
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QTX_TAIL
(
0
)
&&
val
=
regs
.
qtx_tail
[(
addr
-
I40E_QTX_TAIL
(
0
))
/
4
];
addr
<=
I40E_QTX_TAIL
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QTX_CTL
(
0
)
&&
addr
<=
I40E_QTX_CTL
(
NUM_QUEUES
-
1
))
{
val
=
regs
.
qtx_tail
[(
addr
-
I40E_QTX_TAIL
(
0
))
/
4
];
val
=
regs
.
qtx_ctl
[(
addr
-
I40E_QTX_CTL
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_QTX_CTL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QINT_RQCTL
(
0
)
&&
addr
<=
I40E_QTX_CTL
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QINT_RQCTL
(
NUM_QUEUES
-
1
))
{
val
=
regs
.
qtx_ctl
[(
addr
-
I40E_QTX_CTL
(
0
))
/
4
];
val
=
regs
.
qint_rqctl
[(
addr
-
I40E_QINT_RQCTL
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_QINT_RQCTL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QRX_ENA
(
0
)
&&
addr
<=
I40E_QRX_ENA
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QINT_RQCTL
(
NUM_QUEUES
-
1
))
{
val
=
regs
.
qrx_ena
[(
addr
-
I40E_QRX_ENA
(
0
))
/
4
];
val
=
regs
.
qint_rqctl
[(
addr
-
I40E_QINT_RQCTL
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_QRX_TAIL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QRX_ENA
(
0
)
&&
addr
<=
I40E_QRX_TAIL
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QRX_ENA
(
NUM_QUEUES
-
1
))
{
val
=
regs
.
qrx_tail
[(
addr
-
I40E_QRX_TAIL
(
0
))
/
4
];
val
=
regs
.
qrx_ena
[(
addr
-
I40E_QRX_ENA
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_GLHMC_LANTXBASE
(
0
)
&&
}
else
if
(
addr
>=
I40E_QRX_TAIL
(
0
)
&&
addr
<=
I40E_GLHMC_LANTXBASE
(
I40E_GLHMC_LANTXBASE_MAX_INDEX
))
{
addr
<=
I40E_QRX_TAIL
(
NUM_QUEUES
-
1
))
{
val
=
regs
.
glhmc_lantxbase
[(
addr
-
I40E_GLHMC_LANTXBASE
(
0
))
/
4
];
val
=
regs
.
qrx_tail
[(
addr
-
I40E_QRX_TAIL
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_GLHMC_LANTXCNT
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANTXBASE
(
0
)
&&
addr
<=
I40E_GLHMC_LANTXCNT
(
I40E_GLHMC_LANTXCNT_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANTXBASE
(
I40E_GLHMC_LANTXBASE_MAX_INDEX
))
{
val
=
regs
.
glhmc_lantxcnt
[(
addr
-
I40E_GLHMC_LANTXCNT
(
0
))
/
4
];
val
=
regs
.
glhmc_lantxbase
[(
addr
-
I40E_GLHMC_LANTXBASE
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_GLHMC_LANRXBASE
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANTXCNT
(
0
)
&&
addr
<=
I40E_GLHMC_LANRXBASE
(
I40E_GLHMC_LANRXBASE_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANTXCNT
(
I40E_GLHMC_LANTXCNT_MAX_INDEX
))
{
val
=
regs
.
glhmc_lanrxbase
[(
addr
-
I40E_GLHMC_LANRXBASE
(
0
))
/
4
];
val
=
regs
.
glhmc_lantxcnt
[(
addr
-
I40E_GLHMC_LANTXCNT
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_GLHMC_LANRXCNT
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANRXBASE
(
0
)
&&
addr
<=
I40E_GLHMC_LANRXCNT
(
I40E_GLHMC_LANRXCNT_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANRXBASE
(
I40E_GLHMC_LANRXBASE_MAX_INDEX
))
{
val
=
regs
.
glhmc_lanrxcnt
[(
addr
-
I40E_GLHMC_LANRXCNT
(
0
))
/
4
];
val
=
regs
.
glhmc_lanrxbase
[(
addr
-
I40E_GLHMC_LANRXBASE
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_PFQF_HKEY
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANRXCNT
(
0
)
&&
addr
<=
I40E_PFQF_HKEY
(
I40E_PFQF_HKEY_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANRXCNT
(
I40E_GLHMC_LANRXCNT_MAX_INDEX
))
{
val
=
regs
.
pfqf_hkey
[(
addr
-
I40E_PFQF_HKEY
(
0
))
/
128
];
val
=
regs
.
glhmc_lanrxcnt
[(
addr
-
I40E_GLHMC_LANRXCNT
(
0
))
/
4
];
}
else
if
(
addr
>=
I40E_PFQF_HLUT
(
0
)
&&
}
else
if
(
addr
>=
I40E_PFQF_HKEY
(
0
)
&&
addr
<=
I40E_PFQF_HLUT
(
I40E_PFQF_HLUT_MAX_INDEX
))
{
addr
<=
I40E_PFQF_HKEY
(
I40E_PFQF_HKEY_MAX_INDEX
))
{
val
=
regs
.
pfqf_hlut
[(
addr
-
I40E_PFQF_HLUT
(
0
))
/
128
];
val
=
regs
.
pfqf_hkey
[(
addr
-
I40E_PFQF_HKEY
(
0
))
/
128
];
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
0
,
0
)
&&
}
else
if
(
addr
>=
I40E_PFQF_HLUT
(
0
)
&&
addr
<=
I40E_PFINT_ITRN
(
0
,
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFQF_HLUT
(
I40E_PFQF_HLUT_MAX_INDEX
))
{
val
=
regs
.
pfint_itrn
[
0
][(
addr
-
I40E_PFINT_ITRN
(
0
,
0
))
/
4
];
val
=
regs
.
pfqf_hlut
[(
addr
-
I40E_PFQF_HLUT
(
0
))
/
128
];
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
1
,
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
0
,
0
)
&&
addr
<=
I40E_PFINT_ITRN
(
1
,
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_ITRN
(
0
,
NUM_PFINTS
-
1
))
{
val
=
regs
.
pfint_itrn
[
1
][(
addr
-
I40E_PFINT_ITRN
(
1
,
0
))
/
4
];
val
=
regs
.
pfint_itrn
[
0
][(
addr
-
I40E_PFINT_ITRN
(
0
,
0
))
/
4
];
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
2
,
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
1
,
0
)
&&
addr
<=
I40E_PFINT_ITRN
(
2
,
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_ITRN
(
1
,
NUM_PFINTS
-
1
))
{
val
=
regs
.
pfint_itrn
[
2
][(
addr
-
I40E_PFINT_ITRN
(
2
,
0
))
/
4
];
val
=
regs
.
pfint_itrn
[
1
][(
addr
-
I40E_PFINT_ITRN
(
1
,
0
))
/
4
];
}
else
{
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
2
,
0
)
&&
switch
(
addr
)
{
addr
<=
I40E_PFINT_ITRN
(
2
,
NUM_PFINTS
-
1
))
{
case
I40E_PFGEN_CTRL
:
val
=
regs
.
pfint_itrn
[
2
][(
addr
-
I40E_PFINT_ITRN
(
2
,
0
))
/
4
];
val
=
0
;
/* we always simulate immediate reset */
}
else
{
break
;
switch
(
addr
)
{
case
I40E_PFGEN_CTRL
:
case
I40E_GL_FWSTS
:
val
=
0
;
/* we always simulate immediate reset */
val
=
0
;
break
;
break
;
case
I40E_GL_FWSTS
:
case
I40E_GLPCI_CAPSUP
:
val
=
0
;
val
=
0
;
break
;
break
;
case
I40E_GLPCI_CAPSUP
:
case
I40E_GLNVM_ULD
:
val
=
0
;
val
=
0xffffffff
;
break
;
break
;
case
I40E_GLNVM_ULD
:
case
I40E_GLNVM_GENS
:
val
=
0xffffffff
;
val
=
I40E_GLNVM_GENS_NVM_PRES_MASK
|
break
;
(
6
<<
I40E_GLNVM_GENS_SR_SIZE_SHIFT
);
// shadow ram 64kb
break
;
case
I40E_GLNVM_GENS
:
val
=
I40E_GLNVM_GENS_NVM_PRES_MASK
|
case
I40E_GLNVM_FLA
:
(
6
<<
I40E_GLNVM_GENS_SR_SIZE_SHIFT
);
// shadow ram 64kb
val
=
I40E_GLNVM_FLA_LOCKED_MASK
;
// normal flash programming
break
;
// mode
break
;
case
I40E_GLNVM_FLA
:
val
=
I40E_GLNVM_FLA_LOCKED_MASK
;
// normal flash programming
case
I40E_GLGEN_RSTCTL
:
// mode
val
=
regs
.
glgen_rstctl
;
break
;
break
;
case
I40E_GLGEN_STAT
:
case
I40E_GLGEN_RSTCTL
:
val
=
regs
.
glgen_stat
;
val
=
regs
.
glgen_rstctl
;
break
;
break
;
case
I40E_GLGEN_STAT
:
case
I40E_GLVFGEN_TIMER
:
val
=
regs
.
glgen_stat
;
val
=
runner
->
time_ps
()
/
1000000
;
break
;
break
;
case
I40E_GLVFGEN_TIMER
:
case
I40E_PFINT_LNKLST0
:
val
=
runner
->
time_ps
()
/
1000000
;
val
=
regs
.
pfint_lnklst0
;
break
;
break
;
case
I40E_PFINT_LNKLST0
:
case
I40E_PFINT_ICR0_ENA
:
val
=
regs
.
pfint_lnklst0
;
val
=
regs
.
pfint_icr0_ena
;
break
;
break
;
case
I40E_PFINT_ICR0_ENA
:
case
I40E_PFINT_ICR0
:
val
=
regs
.
pfint_icr0_ena
;
val
=
regs
.
pfint_icr0
;
break
;
// read clears
regs
.
pfint_icr0
=
0
;
case
I40E_PFINT_ICR0
:
break
;
val
=
regs
.
pfint_icr0
;
// read clears
case
I40E_PFINT_STAT_CTL0
:
regs
.
pfint_icr0
=
0
;
val
=
regs
.
pfint_stat_ctl0
;
break
;
break
;
case
I40E_PFINT_STAT_CTL0
:
case
I40E_PFINT_DYN_CTL0
:
val
=
regs
.
pfint_stat_ctl0
;
val
=
regs
.
pfint_dyn_ctl0
;
break
;
break
;
case
I40E_PFINT_DYN_CTL0
:
case
I40E_PFINT_ITR0
(
0
):
val
=
regs
.
pfint_dyn_ctl0
;
val
=
regs
.
pfint_itr0
[
0
];
break
;
break
;
case
I40E_PFINT_ITR0
(
1
):
case
I40E_PFINT_ITR0
(
0
):
val
=
regs
.
pfint_itr0
[
1
];
val
=
regs
.
pfint_itr0
[
0
];
break
;
break
;
case
I40E_PFINT_ITR0
(
2
):
case
I40E_PFINT_ITR0
(
1
):
val
=
regs
.
pfint_itr0
[
2
];
val
=
regs
.
pfint_itr0
[
1
];
break
;
break
;
case
I40E_PFINT_ITR0
(
2
):
case
I40E_GLPCI_CNF2
:
val
=
regs
.
pfint_itr0
[
2
];
// that is ugly, but linux driver needs this not to crash
break
;
val
=
((
NUM_PFINTS
-
2
)
<<
I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT
)
|
(
2
<<
I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT
);
case
I40E_GLPCI_CNF2
:
break
;
// that is ugly, but linux driver needs this not to crash
val
=
((
NUM_PFINTS
-
2
)
<<
I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT
)
|
case
I40E_GLNVM_SRCTL
:
(
2
<<
I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT
);
val
=
regs
.
glnvm_srctl
;
break
;
break
;
case
I40E_GLNVM_SRDATA
:
case
I40E_GLNVM_SRCTL
:
val
=
regs
.
glnvm_srdata
;
val
=
regs
.
glnvm_srctl
;
break
;
break
;
case
I40E_GLNVM_SRDATA
:
case
I40E_PFLAN_QALLOC
:
val
=
regs
.
glnvm_srdata
;
val
=
(
0
<<
I40E_PFLAN_QALLOC_FIRSTQ_SHIFT
)
|
break
;
((
NUM_QUEUES
-
1
)
<<
I40E_PFLAN_QALLOC_LASTQ_SHIFT
)
|
(
1
<<
I40E_PFLAN_QALLOC_VALID_SHIFT
);
case
I40E_PFLAN_QALLOC
:
break
;
val
=
(
0
<<
I40E_PFLAN_QALLOC_FIRSTQ_SHIFT
)
|
((
NUM_QUEUES
-
1
)
<<
I40E_PFLAN_QALLOC_LASTQ_SHIFT
)
|
case
I40E_PF_VT_PFALLOC
:
(
1
<<
I40E_PFLAN_QALLOC_VALID_SHIFT
);
val
=
0
;
// we don't currently support VFs
break
;
break
;
case
I40E_PF_VT_PFALLOC
:
case
I40E_PFGEN_PORTNUM
:
val
=
0
;
// we don't currently support VFs
val
=
(
0
<<
I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT
);
break
;
break
;
case
I40E_PFGEN_PORTNUM
:
case
I40E_GLLAN_RCTL_0
:
val
=
(
0
<<
I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT
);
val
=
regs
.
gllan_rctl_0
;
break
;
break
;
case
I40E_GLLAN_RCTL_0
:
case
I40E_GLHMC_LANTXOBJSZ
:
val
=
regs
.
gllan_rctl_0
;
val
=
7
;
// 128 B
break
;
break
;
case
I40E_GLHMC_LANQMAX
:
case
I40E_GLHMC_LANTXOBJSZ
:
val
=
NUM_QUEUES
;
val
=
7
;
// 128 B
break
;
break
;
case
I40E_GLHMC_LANRXOBJSZ
:
val
=
5
;
// 32 B
case
I40E_GLHMC_LANQMAX
:
break
;
val
=
NUM_QUEUES
;
break
;
case
I40E_GLHMC_FCOEMAX
:
case
I40E_GLHMC_LANRXOBJSZ
:
val
=
0
;
val
=
5
;
// 32 B
break
;
break
;
case
I40E_GLHMC_FCOEDDPOBJSZ
:
val
=
0
;
case
I40E_GLHMC_FCOEMAX
:
break
;
val
=
0
;
case
I40E_GLHMC_FCOEFMAX
:
break
;
// needed to make linux driver happy
case
I40E_GLHMC_FCOEDDPOBJSZ
:
val
=
0x1000
<<
I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT
;
val
=
0
;
break
;
break
;
case
I40E_GLHMC_FCOEFOBJSZ
:
case
I40E_GLHMC_FCOEFMAX
:
val
=
0
;
// needed to make linux driver happy
break
;
val
=
0x1000
<<
I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT
;
break
;
case
I40E_PFHMC_SDCMD
:
case
I40E_GLHMC_FCOEFOBJSZ
:
val
=
regs
.
pfhmc_sdcmd
;
val
=
0
;
break
;
break
;
case
I40E_PFHMC_SDDATALOW
:
val
=
regs
.
pfhmc_sddatalow
;
case
I40E_PFHMC_SDCMD
:
break
;
val
=
regs
.
pfhmc_sdcmd
;
case
I40E_PFHMC_SDDATAHIGH
:
break
;
val
=
regs
.
pfhmc_sddatahigh
;
case
I40E_PFHMC_SDDATALOW
:
break
;
val
=
regs
.
pfhmc_sddatalow
;
case
I40E_PFHMC_PDINV
:
break
;
val
=
regs
.
pfhmc_pdinv
;
case
I40E_PFHMC_SDDATAHIGH
:
break
;
val
=
regs
.
pfhmc_sddatahigh
;
case
I40E_PFHMC_ERRORINFO
:
break
;
val
=
regs
.
pfhmc_errorinfo
;
case
I40E_PFHMC_PDINV
:
break
;
val
=
regs
.
pfhmc_pdinv
;
case
I40E_PFHMC_ERRORDATA
:
break
;
val
=
regs
.
pfhmc_errordata
;
case
I40E_PFHMC_ERRORINFO
:
break
;
val
=
regs
.
pfhmc_errorinfo
;
break
;
case
I40E_PF_ATQBAL
:
case
I40E_PFHMC_ERRORDATA
:
val
=
regs
.
pf_atqba
;
val
=
regs
.
pfhmc_errordata
;
break
;
break
;
case
I40E_PF_ATQBAH
:
val
=
regs
.
pf_atqba
>>
32
;
case
I40E_PF_ATQBAL
:
break
;
val
=
regs
.
pf_atqba
;
case
I40E_PF_ATQLEN
:
break
;
val
=
regs
.
pf_atqlen
;
case
I40E_PF_ATQBAH
:
break
;
val
=
regs
.
pf_atqba
>>
32
;
case
I40E_PF_ATQH
:
break
;
val
=
regs
.
pf_atqh
;
case
I40E_PF_ATQLEN
:
break
;
val
=
regs
.
pf_atqlen
;
case
I40E_PF_ATQT
:
break
;
val
=
regs
.
pf_atqt
;
case
I40E_PF_ATQH
:
break
;
val
=
regs
.
pf_atqh
;
break
;
case
I40E_PF_ARQBAL
:
case
I40E_PF_ATQT
:
val
=
regs
.
pf_arqba
;
val
=
regs
.
pf_atqt
;
break
;
break
;
case
I40E_PF_ARQBAH
:
val
=
regs
.
pf_arqba
>>
32
;
case
I40E_PF_ARQBAL
:
break
;
val
=
regs
.
pf_arqba
;
case
I40E_PF_ARQLEN
:
break
;
val
=
regs
.
pf_arqlen
;
case
I40E_PF_ARQBAH
:
break
;
val
=
regs
.
pf_arqba
>>
32
;
case
I40E_PF_ARQH
:
break
;
val
=
regs
.
pf_arqh
;
case
I40E_PF_ARQLEN
:
break
;
val
=
regs
.
pf_arqlen
;
case
I40E_PF_ARQT
:
break
;
val
=
regs
.
pf_arqt
;
case
I40E_PF_ARQH
:
break
;
val
=
regs
.
pf_arqh
;
break
;
case
I40E_PRTMAC_LINKSTA
:
case
I40E_PF_ARQT
:
val
=
I40E_REG_LINK_UP
|
I40E_REG_SPEED_25_40GB
;
val
=
regs
.
pf_arqt
;
break
;
break
;
case
I40E_PRTMAC_MACC
:
case
I40E_PRTMAC_LINKSTA
:
val
=
0
;
val
=
I40E_REG_LINK_UP
|
I40E_REG_SPEED_25_40GB
;
break
;
break
;
case
I40E_PFQF_CTL_0
:
case
I40E_PRTMAC_MACC
:
val
=
regs
.
pfqf_ctl_0
;
val
=
0
;
break
;
break
;
case
I40E_PRTDCB_FCCFG
:
case
I40E_PFQF_CTL_0
:
val
=
regs
.
prtdcb_fccfg
;
val
=
regs
.
pfqf_ctl_0
;
break
;
break
;
case
I40E_PRTDCB_MFLCN
:
val
=
regs
.
prtdcb_mflcn
;
case
I40E_PRTDCB_FCCFG
:
break
;
val
=
regs
.
prtdcb_fccfg
;
case
I40E_PRT_L2TAGSEN
:
break
;
val
=
regs
.
prt_l2tagsen
;
case
I40E_PRTDCB_MFLCN
:
break
;
val
=
regs
.
prtdcb_mflcn
;
case
I40E_PRTQF_CTL_0
:
break
;
val
=
regs
.
prtqf_ctl_0
;
case
I40E_PRT_L2TAGSEN
:
break
;
val
=
regs
.
prt_l2tagsen
;
break
;
case
I40E_GLRPB_GHW
:
case
I40E_PRTQF_CTL_0
:
val
=
regs
.
glrpb_ghw
;
val
=
regs
.
prtqf_ctl_0
;
break
;
break
;
case
I40E_GLRPB_GLW
:
val
=
regs
.
glrpb_glw
;
case
I40E_GLRPB_GHW
:
break
;
val
=
regs
.
glrpb_ghw
;
case
I40E_GLRPB_PHW
:
break
;
val
=
regs
.
glrpb_phw
;
case
I40E_GLRPB_GLW
:
break
;
val
=
regs
.
glrpb_glw
;
case
I40E_GLRPB_PLW
:
break
;
val
=
regs
.
glrpb_plw
;
case
I40E_GLRPB_PHW
:
break
;
val
=
regs
.
glrpb_phw
;
break
;
default:
case
I40E_GLRPB_PLW
:
val
=
regs
.
glrpb_plw
;
break
;
default:
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"unhandled mem read addr="
<<
addr
log
<<
"unhandled mem read addr="
<<
addr
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
break
;
break
;
}
}
}
}
return
val
;
return
val
;
}
}
void
i40e_bm
::
reg_mem_write32
(
uint64_t
addr
,
uint32_t
val
)
void
i40e_bm
::
reg_mem_write32
(
uint64_t
addr
,
uint32_t
val
)
{
{
if
(
addr
>=
I40E_PFINT_DYN_CTLN
(
0
)
&&
if
(
addr
>=
I40E_PFINT_DYN_CTLN
(
0
)
&&
addr
<=
I40E_PFINT_DYN_CTLN
(
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_DYN_CTLN
(
NUM_PFINTS
-
1
))
{
regs
.
pfint_dyn_ctln
[(
addr
-
I40E_PFINT_DYN_CTLN
(
0
))
/
4
]
=
val
;
regs
.
pfint_dyn_ctln
[(
addr
-
I40E_PFINT_DYN_CTLN
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_PFINT_LNKLSTN
(
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_LNKLSTN
(
0
)
&&
addr
<=
I40E_PFINT_LNKLSTN
(
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_LNKLSTN
(
NUM_PFINTS
-
1
))
{
regs
.
pfint_lnklstn
[(
addr
-
I40E_PFINT_LNKLSTN
(
0
))
/
4
]
=
val
;
regs
.
pfint_lnklstn
[(
addr
-
I40E_PFINT_LNKLSTN
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_PFINT_RATEN
(
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_RATEN
(
0
)
&&
addr
<=
I40E_PFINT_RATEN
(
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_RATEN
(
NUM_PFINTS
-
1
))
{
regs
.
pfint_raten
[(
addr
-
I40E_PFINT_RATEN
(
0
))
/
4
]
=
val
;
regs
.
pfint_raten
[(
addr
-
I40E_PFINT_RATEN
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_GLLAN_TXPRE_QDIS
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLLAN_TXPRE_QDIS
(
0
)
&&
addr
<=
I40E_GLLAN_TXPRE_QDIS
(
11
))
{
addr
<=
I40E_GLLAN_TXPRE_QDIS
(
11
))
{
regs
.
gllan_txpre_qdis
[(
addr
-
I40E_GLLAN_TXPRE_QDIS
(
0
))
/
4
]
=
val
;
regs
.
gllan_txpre_qdis
[(
addr
-
I40E_GLLAN_TXPRE_QDIS
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_QINT_TQCTL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QINT_TQCTL
(
0
)
&&
addr
<=
I40E_QINT_TQCTL
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QINT_TQCTL
(
NUM_QUEUES
-
1
))
{
regs
.
qint_tqctl
[(
addr
-
I40E_QINT_TQCTL
(
0
))
/
4
]
=
val
;
regs
.
qint_tqctl
[(
addr
-
I40E_QINT_TQCTL
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_QTX_ENA
(
0
)
&&
addr
<=
I40E_QTX_ENA
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QTX_ENA
(
0
)
&&
size_t
idx
=
(
addr
-
I40E_QTX_ENA
(
0
))
/
4
;
addr
<=
I40E_QTX_ENA
(
NUM_QUEUES
-
1
))
{
regs
.
qtx_ena
[
idx
]
=
val
;
size_t
idx
=
(
addr
-
I40E_QTX_ENA
(
0
))
/
4
;
lanmgr
.
qena_updated
(
idx
,
false
);
regs
.
qtx_ena
[
idx
]
=
val
;
}
else
if
(
addr
>=
I40E_QTX_TAIL
(
0
)
&&
lanmgr
.
qena_updated
(
idx
,
false
);
addr
<=
I40E_QTX_TAIL
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QTX_TAIL
(
0
)
&&
size_t
idx
=
(
addr
-
I40E_QTX_TAIL
(
0
))
/
4
;
addr
<=
I40E_QTX_TAIL
(
NUM_QUEUES
-
1
))
{
regs
.
qtx_tail
[
idx
]
=
val
;
size_t
idx
=
(
addr
-
I40E_QTX_TAIL
(
0
))
/
4
;
lanmgr
.
tail_updated
(
idx
,
false
);
regs
.
qtx_tail
[
idx
]
=
val
;
}
else
if
(
addr
>=
I40E_QTX_CTL
(
0
)
&&
addr
<=
I40E_QTX_CTL
(
NUM_QUEUES
-
1
))
{
lanmgr
.
tail_updated
(
idx
,
false
);
regs
.
qtx_ctl
[(
addr
-
I40E_QTX_CTL
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_QTX_CTL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QINT_RQCTL
(
0
)
&&
addr
<=
I40E_QTX_CTL
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QINT_RQCTL
(
NUM_QUEUES
-
1
))
{
regs
.
qtx_ctl
[(
addr
-
I40E_QTX_CTL
(
0
))
/
4
]
=
val
;
regs
.
qint_rqctl
[(
addr
-
I40E_QINT_RQCTL
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_QINT_RQCTL
(
0
)
&&
}
else
if
(
addr
>=
I40E_QRX_ENA
(
0
)
&&
addr
<=
I40E_QRX_ENA
(
NUM_QUEUES
-
1
))
{
addr
<=
I40E_QINT_RQCTL
(
NUM_QUEUES
-
1
))
{
size_t
idx
=
(
addr
-
I40E_QRX_ENA
(
0
))
/
4
;
regs
.
qint_rqctl
[(
addr
-
I40E_QINT_RQCTL
(
0
))
/
4
]
=
val
;
regs
.
qrx_ena
[
idx
]
=
val
;
}
else
if
(
addr
>=
I40E_QRX_ENA
(
0
)
&&
lanmgr
.
qena_updated
(
idx
,
true
);
addr
<=
I40E_QRX_ENA
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_QRX_TAIL
(
0
)
&&
size_t
idx
=
(
addr
-
I40E_QRX_ENA
(
0
))
/
4
;
addr
<=
I40E_QRX_TAIL
(
NUM_QUEUES
-
1
))
{
regs
.
qrx_ena
[
idx
]
=
val
;
size_t
idx
=
(
addr
-
I40E_QRX_TAIL
(
0
))
/
4
;
lanmgr
.
qena_updated
(
idx
,
true
);
regs
.
qrx_tail
[
idx
]
=
val
;
}
else
if
(
addr
>=
I40E_QRX_TAIL
(
0
)
&&
lanmgr
.
tail_updated
(
idx
,
true
);
addr
<=
I40E_QRX_TAIL
(
NUM_QUEUES
-
1
))
{
}
else
if
(
addr
>=
I40E_GLHMC_LANTXBASE
(
0
)
&&
size_t
idx
=
(
addr
-
I40E_QRX_TAIL
(
0
))
/
4
;
addr
<=
I40E_GLHMC_LANTXBASE
(
I40E_GLHMC_LANTXBASE_MAX_INDEX
))
{
regs
.
qrx_tail
[
idx
]
=
val
;
regs
.
glhmc_lantxbase
[(
addr
-
I40E_GLHMC_LANTXBASE
(
0
))
/
4
]
=
val
;
lanmgr
.
tail_updated
(
idx
,
true
);
}
else
if
(
addr
>=
I40E_GLHMC_LANTXCNT
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANTXBASE
(
0
)
&&
addr
<=
I40E_GLHMC_LANTXCNT
(
I40E_GLHMC_LANTXCNT_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANTXBASE
(
I40E_GLHMC_LANTXBASE_MAX_INDEX
))
{
regs
.
glhmc_lantxcnt
[(
addr
-
I40E_GLHMC_LANTXCNT
(
0
))
/
4
]
=
val
;
regs
.
glhmc_lantxbase
[(
addr
-
I40E_GLHMC_LANTXBASE
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_GLHMC_LANRXBASE
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANTXCNT
(
0
)
&&
addr
<=
I40E_GLHMC_LANRXBASE
(
I40E_GLHMC_LANRXBASE_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANTXCNT
(
I40E_GLHMC_LANTXCNT_MAX_INDEX
))
{
regs
.
glhmc_lanrxbase
[(
addr
-
I40E_GLHMC_LANRXBASE
(
0
))
/
4
]
=
val
;
regs
.
glhmc_lantxcnt
[(
addr
-
I40E_GLHMC_LANTXCNT
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_GLHMC_LANRXCNT
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANRXBASE
(
0
)
&&
addr
<=
I40E_GLHMC_LANRXCNT
(
I40E_GLHMC_LANRXCNT_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANRXBASE
(
I40E_GLHMC_LANRXBASE_MAX_INDEX
))
{
regs
.
glhmc_lanrxcnt
[(
addr
-
I40E_GLHMC_LANRXCNT
(
0
))
/
4
]
=
val
;
regs
.
glhmc_lanrxbase
[(
addr
-
I40E_GLHMC_LANRXBASE
(
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_PFQF_HKEY
(
0
)
&&
}
else
if
(
addr
>=
I40E_GLHMC_LANRXCNT
(
0
)
&&
addr
<=
I40E_PFQF_HKEY
(
I40E_PFQF_HKEY_MAX_INDEX
))
{
addr
<=
I40E_GLHMC_LANRXCNT
(
I40E_GLHMC_LANRXCNT_MAX_INDEX
))
{
regs
.
pfqf_hkey
[(
addr
-
I40E_PFQF_HKEY
(
0
))
/
128
]
=
val
;
regs
.
glhmc_lanrxcnt
[(
addr
-
I40E_GLHMC_LANRXCNT
(
0
))
/
4
]
=
val
;
lanmgr
.
rss_key_updated
();
}
else
if
(
addr
>=
I40E_PFQF_HKEY
(
0
)
&&
}
else
if
(
addr
>=
I40E_PFQF_HLUT
(
0
)
&&
addr
<=
I40E_PFQF_HKEY
(
I40E_PFQF_HKEY_MAX_INDEX
))
{
addr
<=
I40E_PFQF_HLUT
(
I40E_PFQF_HLUT_MAX_INDEX
))
{
regs
.
pfqf_hkey
[(
addr
-
I40E_PFQF_HKEY
(
0
))
/
128
]
=
val
;
regs
.
pfqf_hlut
[(
addr
-
I40E_PFQF_HLUT
(
0
))
/
128
]
=
val
;
lanmgr
.
rss_key_updated
();
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
0
,
0
)
&&
}
else
if
(
addr
>=
I40E_PFQF_HLUT
(
0
)
&&
addr
<=
I40E_PFINT_ITRN
(
0
,
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFQF_HLUT
(
I40E_PFQF_HLUT_MAX_INDEX
))
{
regs
.
pfint_itrn
[
0
][(
addr
-
I40E_PFINT_ITRN
(
0
,
0
))
/
4
]
=
val
;
regs
.
pfqf_hlut
[(
addr
-
I40E_PFQF_HLUT
(
0
))
/
128
]
=
val
;
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
1
,
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
0
,
0
)
&&
addr
<=
I40E_PFINT_ITRN
(
1
,
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_ITRN
(
0
,
NUM_PFINTS
-
1
))
{
regs
.
pfint_itrn
[
1
][(
addr
-
I40E_PFINT_ITRN
(
1
,
0
))
/
4
]
=
val
;
regs
.
pfint_itrn
[
0
][(
addr
-
I40E_PFINT_ITRN
(
0
,
0
))
/
4
]
=
val
;
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
2
,
0
)
&&
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
1
,
0
)
&&
addr
<=
I40E_PFINT_ITRN
(
2
,
NUM_PFINTS
-
1
))
{
addr
<=
I40E_PFINT_ITRN
(
1
,
NUM_PFINTS
-
1
))
{
regs
.
pfint_itrn
[
2
][(
addr
-
I40E_PFINT_ITRN
(
2
,
0
))
/
4
]
=
val
;
regs
.
pfint_itrn
[
1
][(
addr
-
I40E_PFINT_ITRN
(
1
,
0
))
/
4
]
=
val
;
}
else
{
}
else
if
(
addr
>=
I40E_PFINT_ITRN
(
2
,
0
)
&&
switch
(
addr
)
{
addr
<=
I40E_PFINT_ITRN
(
2
,
NUM_PFINTS
-
1
))
{
case
I40E_PFGEN_CTRL
:
regs
.
pfint_itrn
[
2
][(
addr
-
I40E_PFINT_ITRN
(
2
,
0
))
/
4
]
=
val
;
if
((
val
&
I40E_PFGEN_CTRL_PFSWR_MASK
)
==
I40E_PFGEN_CTRL_PFSWR_MASK
)
}
else
{
reset
(
true
);
switch
(
addr
)
{
break
;
case
I40E_PFGEN_CTRL
:
if
((
val
&
I40E_PFGEN_CTRL_PFSWR_MASK
)
==
case
I40E_GL_FWSTS
:
I40E_PFGEN_CTRL_PFSWR_MASK
)
break
;
reset
(
true
);
break
;
case
I40E_GLGEN_RSTCTL
:
regs
.
glgen_rstctl
=
val
;
case
I40E_GL_FWSTS
:
break
;
break
;
case
I40E_GLLAN_RCTL_0
:
case
I40E_GLGEN_RSTCTL
:
if
((
val
&
I40E_GLLAN_RCTL_0_PXE_MODE_MASK
))
regs
.
glgen_rstctl
=
val
;
regs
.
gllan_rctl_0
&=
~
I40E_GLLAN_RCTL_0_PXE_MODE_MASK
;
break
;
break
;
case
I40E_GLLAN_RCTL_0
:
case
I40E_GLNVM_SRCTL
:
if
((
val
&
I40E_GLLAN_RCTL_0_PXE_MODE_MASK
))
regs
.
glnvm_srctl
=
val
;
regs
.
gllan_rctl_0
&=
~
I40E_GLLAN_RCTL_0_PXE_MODE_MASK
;
shram
.
reg_updated
();
break
;
break
;
case
I40E_GLNVM_SRDATA
:
case
I40E_GLNVM_SRCTL
:
regs
.
glnvm_srdata
=
val
;
regs
.
glnvm_srctl
=
val
;
shram
.
reg_updated
();
shram
.
reg_updated
();
break
;
break
;
case
I40E_GLNVM_SRDATA
:
case
I40E_PFINT_LNKLST0
:
regs
.
glnvm_srdata
=
val
;
regs
.
pfint_lnklst0
=
val
;
shram
.
reg_updated
();
break
;
break
;
case
I40E_PFINT_ICR0_ENA
:
case
I40E_PFINT_LNKLST0
:
regs
.
pfint_icr0_ena
=
val
;
regs
.
pfint_lnklst0
=
val
;
break
;
break
;
case
I40E_PFINT_ICR0
:
regs
.
pfint_icr0
=
val
;
case
I40E_PFINT_ICR0_ENA
:
break
;
regs
.
pfint_icr0_ena
=
val
;
case
I40E_PFINT_STAT_CTL0
:
break
;
regs
.
pfint_stat_ctl0
=
val
;
case
I40E_PFINT_ICR0
:
break
;
regs
.
pfint_icr0
=
val
;
case
I40E_PFINT_DYN_CTL0
:
break
;
regs
.
pfint_dyn_ctl0
=
val
;
case
I40E_PFINT_STAT_CTL0
:
break
;
regs
.
pfint_stat_ctl0
=
val
;
case
I40E_PFINT_ITR0
(
0
):
break
;
regs
.
pfint_itr0
[
0
]
=
val
;
case
I40E_PFINT_DYN_CTL0
:
break
;
regs
.
pfint_dyn_ctl0
=
val
;
case
I40E_PFINT_ITR0
(
1
):
break
;
regs
.
pfint_itr0
[
1
]
=
val
;
case
I40E_PFINT_ITR0
(
0
):
break
;
regs
.
pfint_itr0
[
0
]
=
val
;
case
I40E_PFINT_ITR0
(
2
):
break
;
regs
.
pfint_itr0
[
2
]
=
val
;
case
I40E_PFINT_ITR0
(
1
):
break
;
regs
.
pfint_itr0
[
1
]
=
val
;
break
;
case
I40E_PFHMC_SDCMD
:
case
I40E_PFINT_ITR0
(
2
):
regs
.
pfhmc_sdcmd
=
val
;
regs
.
pfint_itr0
[
2
]
=
val
;
hmc
.
reg_updated
(
addr
);
break
;
break
;
case
I40E_PFHMC_SDDATALOW
:
case
I40E_PFHMC_SDCMD
:
regs
.
pfhmc_sddatalow
=
val
;
regs
.
pfhmc_sdcmd
=
val
;
hmc
.
reg_updated
(
addr
);
hmc
.
reg_updated
(
addr
);
break
;
break
;
case
I40E_PFHMC_SDDATAHIGH
:
case
I40E_PFHMC_SDDATALOW
:
regs
.
pfhmc_sddatahigh
=
val
;
regs
.
pfhmc_sddatalow
=
val
;
hmc
.
reg_updated
(
addr
);
hmc
.
reg_updated
(
addr
);
break
;
break
;
case
I40E_PFHMC_PDINV
:
case
I40E_PFHMC_SDDATAHIGH
:
regs
.
pfhmc_pdinv
=
val
;
regs
.
pfhmc_sddatahigh
=
val
;
hmc
.
reg_updated
(
addr
);
hmc
.
reg_updated
(
addr
);
break
;
break
;
case
I40E_PFHMC_PDINV
:
case
I40E_PF_ATQBAL
:
regs
.
pfhmc_pdinv
=
val
;
regs
.
pf_atqba
=
val
|
(
regs
.
pf_atqba
&
0xffffffff00000000ULL
);
hmc
.
reg_updated
(
addr
);
pf_atq
.
reg_updated
();
break
;
break
;
case
I40E_PF_ATQBAH
:
case
I40E_PF_ATQBAL
:
regs
.
pf_atqba
=
((
uint64_t
)
val
<<
32
)
|
(
regs
.
pf_atqba
&
0xffffffffULL
);
regs
.
pf_atqba
=
val
|
(
regs
.
pf_atqba
&
0xffffffff00000000ULL
);
pf_atq
.
reg_updated
();
pf_atq
.
reg_updated
();
break
;
break
;
case
I40E_PF_ATQLEN
:
case
I40E_PF_ATQBAH
:
regs
.
pf_atqlen
=
val
;
regs
.
pf_atqba
=
((
uint64_t
)
val
<<
32
)
|
pf_atq
.
reg_updated
();
(
regs
.
pf_atqba
&
0xffffffffULL
);
break
;
pf_atq
.
reg_updated
();
case
I40E_PF_ATQH
:
break
;
regs
.
pf_atqh
=
val
;
case
I40E_PF_ATQLEN
:
pf_atq
.
reg_updated
();
regs
.
pf_atqlen
=
val
;
break
;
pf_atq
.
reg_updated
();
case
I40E_PF_ATQT
:
break
;
regs
.
pf_atqt
=
val
;
case
I40E_PF_ATQH
:
pf_atq
.
reg_updated
();
regs
.
pf_atqh
=
val
;
break
;
pf_atq
.
reg_updated
();
break
;
case
I40E_PF_ARQBAL
:
case
I40E_PF_ATQT
:
regs
.
pf_arqba
=
val
|
(
regs
.
pf_atqba
&
0xffffffff00000000ULL
);
regs
.
pf_atqt
=
val
;
break
;
pf_atq
.
reg_updated
();
case
I40E_PF_ARQBAH
:
break
;
regs
.
pf_arqba
=
((
uint64_t
)
val
<<
32
)
|
(
regs
.
pf_arqba
&
0xffffffffULL
);
break
;
case
I40E_PF_ARQBAL
:
case
I40E_PF_ARQLEN
:
regs
.
pf_arqba
=
val
|
(
regs
.
pf_atqba
&
0xffffffff00000000ULL
);
regs
.
pf_arqlen
=
val
;
break
;
break
;
case
I40E_PF_ARQBAH
:
case
I40E_PF_ARQH
:
regs
.
pf_arqba
=
((
uint64_t
)
val
<<
32
)
|
regs
.
pf_arqh
=
val
;
(
regs
.
pf_arqba
&
0xffffffffULL
);
break
;
break
;
case
I40E_PF_ARQT
:
case
I40E_PF_ARQLEN
:
regs
.
pf_arqt
=
val
;
regs
.
pf_arqlen
=
val
;
break
;
break
;
case
I40E_PF_ARQH
:
case
I40E_PFQF_CTL_0
:
regs
.
pf_arqh
=
val
;
regs
.
pfqf_ctl_0
=
val
;
break
;
break
;
case
I40E_PF_ARQT
:
regs
.
pf_arqt
=
val
;
case
I40E_PRTDCB_FCCFG
:
break
;
regs
.
prtdcb_fccfg
=
val
;
break
;
case
I40E_PFQF_CTL_0
:
case
I40E_PRTDCB_MFLCN
:
regs
.
pfqf_ctl_0
=
val
;
regs
.
prtdcb_mflcn
=
val
;
break
;
break
;
case
I40E_PRT_L2TAGSEN
:
case
I40E_PRTDCB_FCCFG
:
regs
.
prt_l2tagsen
=
val
;
regs
.
prtdcb_fccfg
=
val
;
break
;
break
;
case
I40E_PRTQF_CTL_0
:
case
I40E_PRTDCB_MFLCN
:
regs
.
prtqf_ctl_0
=
val
;
regs
.
prtdcb_mflcn
=
val
;
break
;
break
;
case
I40E_PRT_L2TAGSEN
:
case
I40E_GLRPB_GHW
:
regs
.
prt_l2tagsen
=
val
;
regs
.
glrpb_ghw
=
val
;
break
;
break
;
case
I40E_PRTQF_CTL_0
:
case
I40E_GLRPB_GLW
:
regs
.
prtqf_ctl_0
=
val
;
regs
.
glrpb_glw
=
val
;
break
;
break
;
case
I40E_GLRPB_PHW
:
case
I40E_GLRPB_GHW
:
regs
.
glrpb_phw
=
val
;
regs
.
glrpb_ghw
=
val
;
break
;
break
;
case
I40E_GLRPB_PLW
:
case
I40E_GLRPB_GLW
:
regs
.
glrpb_plw
=
val
;
regs
.
glrpb_glw
=
val
;
break
;
break
;
default:
case
I40E_GLRPB_PHW
:
regs
.
glrpb_phw
=
val
;
break
;
case
I40E_GLRPB_PLW
:
regs
.
glrpb_plw
=
val
;
break
;
default:
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"unhandled mem write addr="
<<
addr
log
<<
"unhandled mem write addr="
<<
addr
<<
" val="
<<
val
<<
" val="
<<
val
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
break
;
break
;
}
}
}
}
}
}
void
i40e_bm
::
timed_event
(
nicbm
::
TimedEvent
&
ev
)
void
i40e_bm
::
timed_event
(
nicbm
::
TimedEvent
&
ev
)
{
{
int_ev
&
iev
=
*
((
int_ev
*
)
&
ev
);
int_ev
&
iev
=
*
((
int_ev
*
)
&
ev
);
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"timed_event: triggering interrupt ("
<<
iev
.
vec
<<
")"
<<
log
<<
"timed_event: triggering interrupt ("
<<
iev
.
vec
<<
")"
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
iev
.
armed
=
false
;
iev
.
armed
=
false
;
if
(
int_msix_en
)
{
if
(
int_msix_en
)
{
runner
->
msix_issue
(
iev
.
vec
);
runner
->
msix_issue
(
iev
.
vec
);
}
else
if
(
iev
.
vec
>
0
)
{
}
else
if
(
iev
.
vec
>
0
)
{
log
<<
"timed_event: MSI-X disabled, but vec != 0"
<<
logger
::
endl
;
log
<<
"timed_event: MSI-X disabled, but vec != 0"
<<
logger
::
endl
;
abort
();
abort
();
}
else
{
}
else
{
runner
->
msi_issue
(
0
);
runner
->
msi_issue
(
0
);
}
}
}
}
void
i40e_bm
::
signal_interrupt
(
uint16_t
vec
,
uint8_t
itr
)
void
i40e_bm
::
signal_interrupt
(
uint16_t
vec
,
uint8_t
itr
)
{
{
int_ev
&
iev
=
intevs
[
vec
];
int_ev
&
iev
=
intevs
[
vec
];
uint64_t
mindelay
;
uint64_t
mindelay
;
if
(
itr
<=
2
)
{
if
(
itr
<=
2
)
{
// itr 0-2
// itr 0-2
if
(
vec
==
0
)
if
(
vec
==
0
)
mindelay
=
regs
.
pfint_itr0
[
itr
];
mindelay
=
regs
.
pfint_itr0
[
itr
];
else
else
mindelay
=
regs
.
pfint_itrn
[
itr
][
vec
];
mindelay
=
regs
.
pfint_itrn
[
itr
][
vec
];
mindelay
*=
2000000ULL
;
mindelay
*=
2000000ULL
;
}
else
if
(
itr
==
3
)
{
}
else
if
(
itr
==
3
)
{
// noitr
// noitr
mindelay
=
0
;
mindelay
=
0
;
}
else
{
}
else
{
log
<<
"signal_interrupt() invalid itr ("
<<
itr
<<
")"
<<
logger
::
endl
;
log
<<
"signal_interrupt() invalid itr ("
<<
itr
<<
")"
<<
logger
::
endl
;
abort
();
abort
();
}
}
uint64_t
curtime
=
runner
->
time_ps
();
uint64_t
curtime
=
runner
->
time_ps
();
uint64_t
newtime
=
curtime
+
mindelay
;
uint64_t
newtime
=
curtime
+
mindelay
;
if
(
iev
.
armed
&&
iev
.
time
<=
newtime
)
{
if
(
iev
.
armed
&&
iev
.
time
<=
newtime
)
{
// already armed and this is not scheduled sooner
// already armed and this is not scheduled sooner
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"signal_interrupt: vec "
<<
vec
<<
" already scheduled"
<<
log
<<
"signal_interrupt: vec "
<<
vec
<<
" already scheduled"
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
return
;
return
;
}
else
if
(
iev
.
armed
)
{
}
else
if
(
iev
.
armed
)
{
// need to reschedule
// need to reschedule
runner
->
event_cancel
(
iev
);
runner
->
event_cancel
(
iev
);
}
}
iev
.
armed
=
true
;
iev
.
armed
=
true
;
iev
.
time
=
newtime
;
iev
.
time
=
newtime
;
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"signal_interrupt: scheduled vec "
<<
vec
<<
" for time="
<<
log
<<
"signal_interrupt: scheduled vec "
<<
vec
<<
" for time="
<<
newtime
newtime
<<
" (itr "
<<
itr
<<
")"
<<
logger
::
endl
;
<<
" (itr "
<<
itr
<<
")"
<<
logger
::
endl
;
#endif
#endif
runner
->
event_schedule
(
iev
);
runner
->
event_schedule
(
iev
);
}
}
void
i40e_bm
::
reset
(
bool
indicate_done
)
void
i40e_bm
::
reset
(
bool
indicate_done
)
{
{
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
std
::
cout
<<
"reset triggered"
<<
logger
::
endl
;
std
::
cout
<<
"reset triggered"
<<
logger
::
endl
;
#endif
#endif
pf_atq
.
reset
();
pf_atq
.
reset
();
hmc
.
reset
();
hmc
.
reset
();
lanmgr
.
reset
();
lanmgr
.
reset
();
memset
(
&
regs
,
0
,
sizeof
(
regs
));
if
(
indicate_done
)
regs
.
glnvm_srctl
=
I40E_GLNVM_SRCTL_DONE_MASK
;
for
(
uint16_t
i
=
0
;
i
<
NUM_PFINTS
;
i
++
)
{
intevs
[
i
].
vec
=
i
;
if
(
intevs
[
i
].
armed
)
{
runner
->
event_cancel
(
intevs
[
i
]);
intevs
[
i
].
armed
=
false
;
}
intevs
[
i
].
time
=
0
;
}
// add default hash key
memset
(
&
regs
,
0
,
sizeof
(
regs
));
regs
.
pfqf_hkey
[
0
]
=
0xda565a6d
;
if
(
indicate_done
)
regs
.
pfqf_hkey
[
1
]
=
0xc20e5b25
;
regs
.
glnvm_srctl
=
I40E_GLNVM_SRCTL_DONE_MASK
;
regs
.
pfqf_hkey
[
2
]
=
0x3d256741
;
regs
.
pfqf_hkey
[
3
]
=
0xb08fa343
;
for
(
uint16_t
i
=
0
;
i
<
NUM_PFINTS
;
i
++
)
{
regs
.
pfqf_hkey
[
4
]
=
0xcb2bcad0
;
intevs
[
i
].
vec
=
i
;
regs
.
pfqf_hkey
[
5
]
=
0xb4307bae
;
if
(
intevs
[
i
].
armed
)
{
regs
.
pfqf_hkey
[
6
]
=
0xa32dcb77
;
runner
->
event_cancel
(
intevs
[
i
]);
regs
.
pfqf_hkey
[
7
]
=
0x0cf23080
;
intevs
[
i
].
armed
=
false
;
regs
.
pfqf_hkey
[
8
]
=
0x3bb7426a
;
}
regs
.
pfqf_hkey
[
9
]
=
0xfa01acbe
;
intevs
[
i
].
time
=
0
;
regs
.
pfqf_hkey
[
10
]
=
0x0
;
}
regs
.
pfqf_hkey
[
11
]
=
0x0
;
regs
.
pfqf_hkey
[
12
]
=
0x0
;
// add default hash key
regs
.
pfqf_hkey
[
0
]
=
0xda565a6d
;
regs
.
glrpb_ghw
=
0xF2000
;
regs
.
pfqf_hkey
[
1
]
=
0xc20e5b25
;
regs
.
glrpb_phw
=
0x1246
;
regs
.
pfqf_hkey
[
2
]
=
0x3d256741
;
regs
.
glrpb_plw
=
0x0846
;
regs
.
pfqf_hkey
[
3
]
=
0xb08fa343
;
regs
.
pfqf_hkey
[
4
]
=
0xcb2bcad0
;
regs
.
pfqf_hkey
[
5
]
=
0xb4307bae
;
regs
.
pfqf_hkey
[
6
]
=
0xa32dcb77
;
regs
.
pfqf_hkey
[
7
]
=
0x0cf23080
;
regs
.
pfqf_hkey
[
8
]
=
0x3bb7426a
;
regs
.
pfqf_hkey
[
9
]
=
0xfa01acbe
;
regs
.
pfqf_hkey
[
10
]
=
0x0
;
regs
.
pfqf_hkey
[
11
]
=
0x0
;
regs
.
pfqf_hkey
[
12
]
=
0x0
;
regs
.
glrpb_ghw
=
0xF2000
;
regs
.
glrpb_phw
=
0x1246
;
regs
.
glrpb_plw
=
0x0846
;
}
}
shadow_ram
::
shadow_ram
(
i40e_bm
&
dev_
)
shadow_ram
::
shadow_ram
(
i40e_bm
&
dev_
)
:
dev
(
dev_
),
log
(
"sram"
)
{
:
dev
(
dev_
),
log
(
"sram"
)
{
}
}
void
shadow_ram
::
reg_updated
()
void
shadow_ram
::
reg_updated
()
{
{
uint32_t
val
=
dev
.
regs
.
glnvm_srctl
;
uint32_t
val
=
dev
.
regs
.
glnvm_srctl
;
uint32_t
addr
;
uint32_t
addr
;
bool
is_write
;
bool
is_write
;
if
(
!
(
val
&
I40E_GLNVM_SRCTL_START_MASK
))
if
(
!
(
val
&
I40E_GLNVM_SRCTL_START_MASK
))
return
;
return
;
addr
=
(
val
&
I40E_GLNVM_SRCTL_ADDR_MASK
)
addr
=
(
val
&
I40E_GLNVM_SRCTL_ADDR_MASK
)
>>
I40E_GLNVM_SRCTL_ADDR_SHIFT
;
>>
I40E_GLNVM_SRCTL_ADDR_SHIFT
;
is_write
=
(
val
&
I40E_GLNVM_SRCTL_WRITE_MASK
);
is_write
=
(
val
&
I40E_GLNVM_SRCTL_WRITE_MASK
);
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"shadow ram op addr="
<<
addr
<<
" w="
<<
is_write
log
<<
"shadow ram op addr="
<<
addr
<<
" w="
<<
is_write
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
if
(
is_write
)
{
if
(
is_write
)
{
write
(
addr
,
write
(
addr
,
(
dev
.
regs
.
glnvm_srdata
&
I40E_GLNVM_SRDATA_WRDATA_MASK
)
>>
(
dev
.
regs
.
glnvm_srdata
&
I40E_GLNVM_SRDATA_WRDATA_MASK
)
I40E_GLNVM_SRDATA_WRDATA_SHIFT
);
>>
I40E_GLNVM_SRDATA_WRDATA_SHIFT
);
}
else
{
}
else
{
dev
.
regs
.
glnvm_srdata
&=
~
I40E_GLNVM_SRDATA_RDDATA_MASK
;
dev
.
regs
.
glnvm_srdata
&=
~
I40E_GLNVM_SRDATA_RDDATA_MASK
;
dev
.
regs
.
glnvm_srdata
|=
((
uint32_t
)
read
(
addr
))
dev
.
regs
.
glnvm_srdata
|=
((
uint32_t
)
read
(
addr
))
<<
<<
I40E_GLNVM_SRDATA_RDDATA_SHIFT
;
I40E_GLNVM_SRDATA_RDDATA_SHIFT
;
}
}
dev
.
regs
.
glnvm_srctl
&=
~
I40E_GLNVM_SRCTL_START_MASK
;
dev
.
regs
.
glnvm_srctl
&=
~
I40E_GLNVM_SRCTL_START_MASK
;
dev
.
regs
.
glnvm_srctl
|=
I40E_GLNVM_SRCTL_DONE_MASK
;
dev
.
regs
.
glnvm_srctl
|=
I40E_GLNVM_SRCTL_DONE_MASK
;
}
}
uint16_t
shadow_ram
::
read
(
uint16_t
addr
)
uint16_t
shadow_ram
::
read
(
uint16_t
addr
)
{
{
switch
(
addr
)
{
switch
(
addr
)
{
/* for any of these hopefully return 0 should be fine */
/* for any of these hopefully return 0 should be fine */
/* they are read by drivers but not used */
/* they are read by drivers but not used */
case
I40E_SR_NVM_DEV_STARTER_VERSION
:
case
I40E_SR_NVM_DEV_STARTER_VERSION
:
case
I40E_SR_NVM_EETRACK_LO
:
case
I40E_SR_NVM_EETRACK_LO
:
case
I40E_SR_NVM_EETRACK_HI
:
case
I40E_SR_NVM_EETRACK_HI
:
case
I40E_SR_BOOT_CONFIG_PTR
:
case
I40E_SR_BOOT_CONFIG_PTR
:
return
0
;
return
0
;
case
I40E_SR_NVM_CONTROL_WORD
:
case
I40E_SR_NVM_CONTROL_WORD
:
return
(
1
<<
I40E_SR_CONTROL_WORD_1_SHIFT
);
return
(
1
<<
I40E_SR_CONTROL_WORD_1_SHIFT
);
case
I40E_SR_SW_CHECKSUM_WORD
:
case
I40E_SR_SW_CHECKSUM_WORD
:
return
0xbaba
;
return
0xbaba
;
default:
default:
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"TODO shadow memory read addr="
<<
addr
log
<<
"TODO shadow memory read addr="
<<
addr
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
break
;
break
;
}
}
return
0
;
return
0
;
}
}
void
shadow_ram
::
write
(
uint16_t
addr
,
uint16_t
val
)
void
shadow_ram
::
write
(
uint16_t
addr
,
uint16_t
val
)
{
{
#ifdef DEBUG_DEV
#ifdef DEBUG_DEV
log
<<
"TODO shadow memory write addr="
<<
addr
<<
log
<<
"TODO shadow memory write addr="
<<
addr
<<
" val="
<<
val
" val="
<<
val
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
}
}
int_ev
::
int_ev
()
int_ev
::
int_ev
()
{
{
armed
=
false
;
armed
=
false
;
time
=
0
;
time
=
0
;
}
}
}
// namespace i40e
}
// namespace i40e
using
namespace
i40e
;
using
namespace
i40e
;
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
i40e_bm
dev
;
i40e_bm
dev
;
runner
=
new
nicbm
::
Runner
(
dev
);
runner
=
new
nicbm
::
Runner
(
dev
);
return
runner
->
runMain
(
argc
,
argv
);
return
runner
->
runMain
(
argc
,
argv
);
}
}
sims/nic/i40e_bm/i40e_bm.h
View file @
d4666c97
...
@@ -24,10 +24,11 @@
...
@@ -24,10 +24,11 @@
#pragma once
#pragma once
#include <stdint.h>
#include <deque>
#include <deque>
#include <sstream>
#include <sstream>
#include <string>
#include <string>
#include <stdint.h>
extern
"C"
{
extern
"C"
{
#include <simbricks/proto/pcie.h>
#include <simbricks/proto/pcie.h>
}
}
...
@@ -48,39 +49,38 @@ class i40e_bm;
...
@@ -48,39 +49,38 @@ class i40e_bm;
class
lan
;
class
lan
;
class
dma_base
:
public
nicbm
::
DMAOp
{
class
dma_base
:
public
nicbm
::
DMAOp
{
public:
public:
/** i40e_bm will call this when dma is done */
/** i40e_bm will call this when dma is done */
virtual
void
done
()
=
0
;
virtual
void
done
()
=
0
;
};
};
class
int_ev
:
public
nicbm
::
TimedEvent
{
class
int_ev
:
public
nicbm
::
TimedEvent
{
public:
public:
uint16_t
vec
;
uint16_t
vec
;
bool
armed
;
bool
armed
;
int_ev
();
int_ev
();
};
};
class
logger
:
public
std
::
ostream
{
class
logger
:
public
std
::
ostream
{
public:
public:
static
const
char
endl
=
'\n'
;
static
const
char
endl
=
'\n'
;
protected:
protected:
std
::
string
label
;
std
::
string
label
;
std
::
stringstream
ss
;
std
::
stringstream
ss
;
public:
public:
logger
(
const
std
::
string
&
label_
);
logger
(
const
std
::
string
&
label_
);
logger
&
operator
<<
(
char
c
);
logger
&
operator
<<
(
char
c
);
logger
&
operator
<<
(
int32_t
c
);
logger
&
operator
<<
(
int32_t
c
);
logger
&
operator
<<
(
uint8_t
i
);
logger
&
operator
<<
(
uint8_t
i
);
logger
&
operator
<<
(
uint16_t
i
);
logger
&
operator
<<
(
uint16_t
i
);
logger
&
operator
<<
(
uint32_t
i
);
logger
&
operator
<<
(
uint32_t
i
);
logger
&
operator
<<
(
uint64_t
i
);
logger
&
operator
<<
(
uint64_t
i
);
logger
&
operator
<<
(
bool
c
);
logger
&
operator
<<
(
bool
c
);
logger
&
operator
<<
(
const
char
*
str
);
logger
&
operator
<<
(
const
char
*
str
);
logger
&
operator
<<
(
void
*
str
);
logger
&
operator
<<
(
void
*
str
);
};
};
/**
/**
...
@@ -106,515 +106,516 @@ class logger : public std::ostream {
...
@@ -106,515 +106,516 @@ class logger : public std::ostream {
* capacity
* capacity
*/
*/
class
queue_base
{
class
queue_base
{
protected:
protected:
static
const
uint32_t
MAX_ACTIVE_DESCS
=
128
;
static
const
uint32_t
MAX_ACTIVE_DESCS
=
128
;
class
desc_ctx
{
class
desc_ctx
{
friend
class
queue_base
;
friend
class
queue_base
;
public:
enum
state
{
public:
DESC_EMPTY
,
enum
state
DESC_FETCHING
,
{
DESC_PREPARING
,
DESC_EMPTY
,
DESC_PREPARED
,
DESC_FETCHING
,
DESC_PROCESSING
,
DESC_PREPARING
,
DESC_PROCESSED
,
DESC_PREPARED
,
DESC_WRITING_BACK
,
DESC_PROCESSING
,
DESC_WRITTEN_BACK
,
DESC_PROCESSED
,
};
DESC_WRITING_BACK
,
DESC_WRITTEN_BACK
,
protected:
};
queue_base
&
queue
;
protected:
public:
queue_base
&
queue
;
enum
state
state
;
uint32_t
index
;
public:
void
*
desc
;
enum
state
state
;
void
*
data
;
uint32_t
index
;
size_t
data_len
;
void
*
desc
;
size_t
data_capacity
;
void
*
data
;
size_t
data_len
;
virtual
void
prepared
();
size_t
data_capacity
;
virtual
void
processed
();
virtual
void
prepared
();
protected:
virtual
void
processed
();
void
data_fetch
(
uint64_t
addr
,
size_t
len
);
virtual
void
data_fetched
(
uint64_t
addr
,
size_t
len
);
protected:
void
data_write
(
uint64_t
addr
,
size_t
len
,
const
void
*
buf
);
void
data_fetch
(
uint64_t
addr
,
size_t
len
);
virtual
void
data_written
(
uint64_t
addr
,
size_t
len
);
virtual
void
data_fetched
(
uint64_t
addr
,
size_t
len
);
void
data_write
(
uint64_t
addr
,
size_t
len
,
const
void
*
buf
);
public:
virtual
void
data_written
(
uint64_t
addr
,
size_t
len
);
desc_ctx
(
queue_base
&
queue_
);
virtual
~
desc_ctx
();
public:
desc_ctx
(
queue_base
&
queue_
);
virtual
void
prepare
();
virtual
~
desc_ctx
();
virtual
void
process
()
=
0
;
};
virtual
void
prepare
();
virtual
void
process
()
=
0
;
class
dma_fetch
:
public
dma_base
{
};
protected:
queue_base
&
queue
;
class
dma_fetch
:
public
dma_base
{
public:
protected:
uint32_t
pos
;
queue_base
&
queue
;
dma_fetch
(
queue_base
&
queue_
,
size_t
len
);
virtual
~
dma_fetch
();
public:
virtual
void
done
();
uint32_t
pos
;
};
dma_fetch
(
queue_base
&
queue_
,
size_t
len
);
virtual
~
dma_fetch
();
class
dma_wb
:
public
dma_base
{
virtual
void
done
();
protected:
};
queue_base
&
queue
;
public:
class
dma_wb
:
public
dma_base
{
uint32_t
pos
;
protected:
dma_wb
(
queue_base
&
queue_
,
size_t
len
);
queue_base
&
queue
;
virtual
~
dma_wb
();
virtual
void
done
();
public:
};
uint32_t
pos
;
dma_wb
(
queue_base
&
queue_
,
size_t
len
);
class
dma_data_fetch
:
public
dma_base
{
virtual
~
dma_wb
();
protected:
virtual
void
done
();
desc_ctx
&
ctx
;
};
public:
class
dma_data_fetch
:
public
dma_base
{
size_t
total_len
;
protected:
size_t
part_offset
;
desc_ctx
&
ctx
;
dma_data_fetch
(
desc_ctx
&
ctx_
,
size_t
len
,
void
*
buffer
);
virtual
~
dma_data_fetch
();
public:
virtual
void
done
();
size_t
total_len
;
};
size_t
part_offset
;
dma_data_fetch
(
desc_ctx
&
ctx_
,
size_t
len
,
void
*
buffer
);
class
dma_data_wb
:
public
dma_base
{
virtual
~
dma_data_fetch
();
protected:
virtual
void
done
();
desc_ctx
&
ctx
;
};
public:
size_t
total_len
;
class
dma_data_wb
:
public
dma_base
{
size_t
part_offset
;
protected:
dma_data_wb
(
desc_ctx
&
ctx_
,
size_t
len
);
desc_ctx
&
ctx
;
virtual
~
dma_data_wb
();
virtual
void
done
();
public:
};
size_t
total_len
;
size_t
part_offset
;
public:
dma_data_wb
(
desc_ctx
&
ctx_
,
size_t
len
);
std
::
string
qname
;
virtual
~
dma_data_wb
();
logger
log
;
virtual
void
done
();
};
protected:
desc_ctx
*
desc_ctxs
[
MAX_ACTIVE_DESCS
];
public:
uint32_t
active_first_pos
;
std
::
string
qname
;
uint32_t
active_first_idx
;
logger
log
;
uint32_t
active_cnt
;
protected:
uint64_t
base
;
desc_ctx
*
desc_ctxs
[
MAX_ACTIVE_DESCS
];
uint32_t
len
;
uint32_t
active_first_pos
;
uint32_t
&
reg_head
;
uint32_t
active_first_idx
;
uint32_t
&
reg_tail
;
uint32_t
active_cnt
;
bool
enabled
;
uint64_t
base
;
size_t
desc_len
;
uint32_t
len
;
uint32_t
&
reg_head
;
void
ctxs_init
();
uint32_t
&
reg_tail
;
void
trigger_fetch
();
bool
enabled
;
void
trigger_process
();
size_t
desc_len
;
void
trigger_writeback
();
void
trigger
();
void
ctxs_init
();
// returns how many descriptors the queue can fetch max during the next
void
trigger_fetch
();
// fetch: default UINT32_MAX, but can be overriden by child classes
void
trigger_process
();
virtual
uint32_t
max_fetch_capacity
();
void
trigger_writeback
();
virtual
uint32_t
max_writeback_capacity
();
void
trigger
();
virtual
uint32_t
max_active_capacity
();
// returns how many descriptors the queue can fetch max during the next
virtual
desc_ctx
&
desc_ctx_create
()
=
0
;
// fetch: default UINT32_MAX, but can be overriden by child classes
virtual
uint32_t
max_fetch_capacity
();
// dummy function, needs to be overriden if interrupts are required
virtual
uint32_t
max_writeback_capacity
();
virtual
void
interrupt
();
virtual
uint32_t
max_active_capacity
();
// this does the actual write-back. Can be overridden
virtual
desc_ctx
&
desc_ctx_create
()
=
0
;
virtual
void
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
uint32_t
cnt
);
// dummy function, needs to be overriden if interrupts are required
virtual
void
interrupt
();
// called by dma op when writeback has completed
void
writeback_done
(
uint32_t
first_pos
,
uint32_t
cnt
);
// this does the actual write-back. Can be overridden
virtual
void
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
public:
uint32_t
cnt
);
queue_base
(
const
std
::
string
&
qname_
,
uint32_t
&
reg_head_
,
uint32_t
&
reg_tail_
);
// called by dma op when writeback has completed
virtual
void
reset
();
void
writeback_done
(
uint32_t
first_pos
,
uint32_t
cnt
);
void
reg_updated
();
bool
is_enabled
();
public:
queue_base
(
const
std
::
string
&
qname_
,
uint32_t
&
reg_head_
,
uint32_t
&
reg_tail_
);
virtual
void
reset
();
void
reg_updated
();
bool
is_enabled
();
};
};
class
queue_admin_tx
:
public
queue_base
{
class
queue_admin_tx
:
public
queue_base
{
protected:
protected:
class
admin_desc_ctx
:
public
desc_ctx
{
class
admin_desc_ctx
:
public
desc_ctx
{
protected:
protected:
queue_admin_tx
&
aq
;
queue_admin_tx
&
aq
;
i40e_bm
&
dev
;
i40e_bm
&
dev
;
struct
i40e_aq_desc
*
d
;
struct
i40e_aq_desc
*
d
;
virtual
void
data_written
(
uint64_t
addr
,
size_t
len
);
virtual
void
data_written
(
uint64_t
addr
,
size_t
len
);
// prepare completion descriptor (fills flags, and return value)
// prepare completion descriptor (fills flags, and return value)
void
desc_compl_prepare
(
uint16_t
retval
,
uint16_t
extra_flags
);
void
desc_compl_prepare
(
uint16_t
retval
,
uint16_t
extra_flags
);
// complete direct response
// complete direct response
void
desc_complete
(
uint16_t
retval
,
uint16_t
extra_flags
=
0
);
void
desc_complete
(
uint16_t
retval
,
uint16_t
extra_flags
=
0
);
// complete indirect response
// complete indirect response
void
desc_complete_indir
(
uint16_t
retval
,
const
void
*
data
,
void
desc_complete_indir
(
uint16_t
retval
,
const
void
*
data
,
size_t
len
,
size_t
len
,
uint16_t
extra_flags
=
0
,
uint16_t
extra_flags
=
0
,
bool
ignore_datalen
=
false
);
bool
ignore_datalen
=
false
);
public:
public:
admin_desc_ctx
(
queue_admin_tx
&
queue_
,
i40e_bm
&
dev
);
admin_desc_ctx
(
queue_admin_tx
&
queue_
,
i40e_bm
&
dev
);
virtual
void
prepare
();
virtual
void
prepare
();
virtual
void
process
();
virtual
void
process
();
};
};
i40e_bm
&
dev
;
i40e_bm
&
dev
;
uint64_t
&
reg_base
;
uint64_t
&
reg_base
;
uint32_t
&
reg_len
;
uint32_t
&
reg_len
;
virtual
desc_ctx
&
desc_ctx_create
();
virtual
desc_ctx
&
desc_ctx_create
();
public:
public:
queue_admin_tx
(
i40e_bm
&
dev_
,
uint64_t
&
reg_base_
,
queue_admin_tx
(
i40e_bm
&
dev_
,
uint64_t
&
reg_base_
,
uint32_t
&
reg_len_
,
uint32_t
&
reg_len_
,
uint32_t
&
reg_head_
,
uint32_t
&
reg_tail_
);
uint32_t
&
reg_head_
,
uint32_t
&
reg_tail_
);
void
reg_updated
();
void
reg_updated
();
};
};
// host memory cache
// host memory cache
class
host_mem_cache
{
class
host_mem_cache
{
protected:
protected:
static
const
uint16_t
MAX_SEGMENTS
=
0x1000
;
static
const
uint16_t
MAX_SEGMENTS
=
0x1000
;
struct
segment
{
struct
segment
{
uint64_t
addr
;
uint64_t
addr
;
uint16_t
pgcount
;
uint16_t
pgcount
;
bool
valid
;
bool
valid
;
bool
direct
;
bool
direct
;
};
};
i40e_bm
&
dev
;
i40e_bm
&
dev
;
segment
segs
[
MAX_SEGMENTS
];
segment
segs
[
MAX_SEGMENTS
];
public:
public:
class
mem_op
:
public
dma_base
{
class
mem_op
:
public
dma_base
{
public:
public:
bool
failed
;
bool
failed
;
};
};
host_mem_cache
(
i40e_bm
&
dev
);
host_mem_cache
(
i40e_bm
&
dev
);
void
reset
();
void
reset
();
void
reg_updated
(
uint64_t
addr
);
void
reg_updated
(
uint64_t
addr
);
// issue a hmc memory operation (address is in the context
// issue a hmc memory operation (address is in the context
void
issue_mem_op
(
mem_op
&
op
);
void
issue_mem_op
(
mem_op
&
op
);
};
};
class
lan_queue_base
:
public
queue_base
{
class
lan_queue_base
:
public
queue_base
{
protected:
protected:
class
qctx_fetch
:
public
host_mem_cache
::
mem_op
{
class
qctx_fetch
:
public
host_mem_cache
::
mem_op
{
public:
public:
lan_queue_base
&
lq
;
lan_queue_base
&
lq
;
qctx_fetch
(
lan_queue_base
&
lq_
);
qctx_fetch
(
lan_queue_base
&
lq_
);
virtual
void
done
();
virtual
void
done
();
};
};
lan
&
lanmgr
;
lan
&
lanmgr
;
void
ctx_fetched
();
void
ctx_fetched
();
void
ctx_written_back
();
void
ctx_written_back
();
virtual
void
interrupt
();
virtual
void
interrupt
();
virtual
void
initialize
()
=
0
;
virtual
void
initialize
()
=
0
;
public:
public:
bool
enabling
;
bool
enabling
;
size_t
idx
;
size_t
idx
;
uint32_t
&
reg_ena
;
uint32_t
&
reg_ena
;
uint32_t
&
fpm_basereg
;
uint32_t
&
fpm_basereg
;
uint32_t
&
reg_intqctl
;
uint32_t
&
reg_intqctl
;
size_t
ctx_size
;
size_t
ctx_size
;
void
*
ctx
;
void
*
ctx
;
uint32_t
reg_dummy_head
;
uint32_t
reg_dummy_head
;
lan_queue_base
(
lan
&
lanmgr_
,
const
std
::
string
&
qtype
,
uint32_t
&
reg_tail
,
lan_queue_base
(
lan
&
lanmgr_
,
const
std
::
string
&
qtype
,
size_t
idx_
,
uint32_t
&
reg_ena_
,
uint32_t
&
fpm_basereg
,
uint32_t
&
reg_tail
,
size_t
idx_
,
uint32_t
&
reg_ena_
,
uint32_t
&
reg_intqctl
,
uint16_t
ctx_size
);
uint32_t
&
fpm_basereg
,
uint32_t
&
reg_intqctl
,
virtual
void
reset
();
uint16_t
ctx_size
);
void
enable
();
virtual
void
reset
();
void
disable
();
void
enable
();
void
disable
();
};
};
class
lan_queue_tx
:
public
lan_queue_base
{
class
lan_queue_tx
:
public
lan_queue_base
{
protected:
protected:
static
const
uint16_t
MTU
=
9024
;
static
const
uint16_t
MTU
=
9024
;
class
tx_desc_ctx
:
public
desc_ctx
{
class
tx_desc_ctx
:
public
desc_ctx
{
protected:
protected:
lan_queue_tx
&
tq
;
lan_queue_tx
&
tq
;
public:
public:
i40e_tx_desc
*
d
;
i40e_tx_desc
*
d
;
tx_desc_ctx
(
lan_queue_tx
&
queue_
);
tx_desc_ctx
(
lan_queue_tx
&
queue_
);
virtual
void
prepare
();
virtual
void
prepare
();
virtual
void
process
();
virtual
void
process
();
virtual
void
processed
();
virtual
void
processed
();
};
};
class
dma_hwb
:
public
dma_base
{
class
dma_hwb
:
public
dma_base
{
protected:
protected:
lan_queue_tx
&
queue
;
lan_queue_tx
&
queue
;
public:
public:
uint32_t
pos
;
uint32_t
pos
;
uint32_t
cnt
;
uint32_t
cnt
;
uint32_t
next_head
;
uint32_t
next_head
;
dma_hwb
(
lan_queue_tx
&
queue_
,
uint32_t
pos
,
uint32_t
cnt
,
dma_hwb
(
lan_queue_tx
&
queue_
,
uint32_t
pos
,
uint32_t
cnt
,
uint32_t
next_head
);
uint32_t
next_head
);
virtual
~
dma_hwb
();
virtual
~
dma_hwb
();
virtual
void
done
();
virtual
void
done
();
};
};
uint8_t
pktbuf
[
MTU
];
uint8_t
pktbuf
[
MTU
];
uint32_t
tso_off
;
uint32_t
tso_off
;
uint32_t
tso_len
;
uint32_t
tso_len
;
std
::
deque
<
tx_desc_ctx
*>
ready_segments
;
std
::
deque
<
tx_desc_ctx
*>
ready_segments
;
bool
hwb
;
bool
hwb
;
uint64_t
hwb_addr
;
uint64_t
hwb_addr
;
virtual
void
initialize
();
virtual
void
initialize
();
virtual
desc_ctx
&
desc_ctx_create
();
virtual
desc_ctx
&
desc_ctx_create
();
virtual
void
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
virtual
void
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
uint32_t
cnt
);
uint32_t
cnt
);
bool
trigger_tx_packet
();
bool
trigger_tx_packet
();
void
trigger_tx
();
void
trigger_tx
();
public:
public:
lan_queue_tx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail
,
size_t
idx
,
lan_queue_tx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail
,
size_t
idx
,
uint32_t
&
reg_ena
,
uint32_t
&
reg_ena
,
uint32_t
&
fpm_basereg
,
uint32_t
&
fpm_basereg
,
uint32_t
&
reg_intqctl
);
uint32_t
&
reg_intqctl
);
virtual
void
reset
();
virtual
void
reset
();
};
};
class
lan_queue_rx
:
public
lan_queue_base
{
class
lan_queue_rx
:
public
lan_queue_base
{
protected:
protected:
class
rx_desc_ctx
:
public
desc_ctx
{
class
rx_desc_ctx
:
public
desc_ctx
{
protected:
protected:
lan_queue_rx
&
rq
;
lan_queue_rx
&
rq
;
virtual
void
data_written
(
uint64_t
addr
,
size_t
len
);
virtual
void
data_written
(
uint64_t
addr
,
size_t
len
);
public:
public:
rx_desc_ctx
(
lan_queue_rx
&
queue_
);
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
);
};
};
uint16_t
dbuff_size
;
uint16_t
dbuff_size
;
uint16_t
hbuff_size
;
uint16_t
hbuff_size
;
uint16_t
rxmax
;
uint16_t
rxmax
;
bool
crc_strip
;
bool
crc_strip
;
std
::
deque
<
rx_desc_ctx
*>
dcache
;
std
::
deque
<
rx_desc_ctx
*>
dcache
;
virtual
void
initialize
();
virtual
void
initialize
();
virtual
desc_ctx
&
desc_ctx_create
();
virtual
desc_ctx
&
desc_ctx_create
();
public:
public:
lan_queue_rx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail
,
size_t
idx
,
lan_queue_rx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail
,
size_t
idx
,
uint32_t
&
reg_ena
,
uint32_t
&
reg_ena
,
uint32_t
&
fpm_basereg
,
uint32_t
&
fpm_basereg
,
uint32_t
&
reg_intqctl
);
uint32_t
&
reg_intqctl
);
virtual
void
reset
();
virtual
void
reset
();
void
packet_received
(
const
void
*
data
,
size_t
len
,
uint32_t
hash
);
void
packet_received
(
const
void
*
data
,
size_t
len
,
uint32_t
hash
);
};
};
class
rss_key_cache
{
class
rss_key_cache
{
protected:
protected:
static
const
size_t
key_len
=
52
;
static
const
size_t
key_len
=
52
;
// big enough for 2x ipv6 (2x128 + 2x16)
// big enough for 2x ipv6 (2x128 + 2x16)
static
const
size_t
cache_len
=
288
;
static
const
size_t
cache_len
=
288
;
bool
cache_dirty
;
bool
cache_dirty
;
const
uint32_t
(
&
key
)[
key_len
/
4
];
const
uint32_t
(
&
key
)[
key_len
/
4
];
uint32_t
cache
[
cache_len
];
uint32_t
cache
[
cache_len
];
void
build
();
void
build
();
public:
public:
rss_key_cache
(
const
uint32_t
(
&
key_
)[
key_len
/
4
]);
rss_key_cache
(
const
uint32_t
(
&
key_
)[
key_len
/
4
]);
void
set_dirty
();
void
set_dirty
();
uint32_t
hash_ipv4
(
uint32_t
sip
,
uint32_t
dip
,
uint16_t
sp
,
uint32_t
hash_ipv4
(
uint32_t
sip
,
uint32_t
dip
,
uint16_t
sp
,
uint16_t
dp
);
uint16_t
dp
);
};
};
// rx tx management
// rx tx management
class
lan
{
class
lan
{
protected:
protected:
friend
class
lan_queue_base
;
friend
class
lan_queue_base
;
friend
class
lan_queue_tx
;
friend
class
lan_queue_tx
;
friend
class
lan_queue_rx
;
friend
class
lan_queue_rx
;
i40e_bm
&
dev
;
i40e_bm
&
dev
;
logger
log
;
logger
log
;
rss_key_cache
rss_kc
;
rss_key_cache
rss_kc
;
const
size_t
num_qs
;
const
size_t
num_qs
;
lan_queue_rx
**
rxqs
;
lan_queue_rx
**
rxqs
;
lan_queue_tx
**
txqs
;
lan_queue_tx
**
txqs
;
bool
rss_steering
(
const
void
*
data
,
size_t
len
,
uint16_t
&
queue
,
bool
rss_steering
(
const
void
*
data
,
size_t
len
,
uint16_t
&
queue
,
uint32_t
&
hash
);
uint32_t
&
hash
);
public:
lan
(
i40e_bm
&
dev
,
size_t
num_qs
);
public:
void
reset
();
lan
(
i40e_bm
&
dev
,
size_t
num_qs
);
void
qena_updated
(
uint16_t
idx
,
bool
rx
);
void
reset
();
void
tail_updated
(
uint16_t
idx
,
bool
rx
);
void
qena_updated
(
uint16_t
idx
,
bool
rx
);
void
rss_key_updated
();
void
tail_updated
(
uint16_t
idx
,
bool
rx
);
void
packet_received
(
const
void
*
data
,
size_t
len
);
void
rss_key_updated
();
void
packet_received
(
const
void
*
data
,
size_t
len
);
};
};
class
shadow_ram
{
class
shadow_ram
{
protected:
protected:
i40e_bm
&
dev
;
i40e_bm
&
dev
;
logger
log
;
logger
log
;
public:
public:
shadow_ram
(
i40e_bm
&
dev
);
shadow_ram
(
i40e_bm
&
dev
);
void
reg_updated
();
void
reg_updated
();
uint16_t
read
(
uint16_t
addr
);
uint16_t
read
(
uint16_t
addr
);
void
write
(
uint16_t
addr
,
uint16_t
val
);
void
write
(
uint16_t
addr
,
uint16_t
val
);
};
};
class
i40e_bm
:
public
nicbm
::
Runner
::
Device
{
class
i40e_bm
:
public
nicbm
::
Runner
::
Device
{
protected:
protected:
friend
class
queue_admin_tx
;
friend
class
queue_admin_tx
;
friend
class
host_mem_cache
;
friend
class
host_mem_cache
;
friend
class
lan
;
friend
class
lan
;
friend
class
lan_queue_base
;
friend
class
lan_queue_base
;
friend
class
lan_queue_rx
;
friend
class
lan_queue_rx
;
friend
class
lan_queue_tx
;
friend
class
lan_queue_tx
;
friend
class
shadow_ram
;
friend
class
shadow_ram
;
static
const
unsigned
BAR_REGS
=
0
;
static
const
unsigned
BAR_REGS
=
0
;
static
const
unsigned
BAR_IO
=
2
;
static
const
unsigned
BAR_IO
=
2
;
static
const
unsigned
BAR_MSIX
=
3
;
static
const
unsigned
BAR_MSIX
=
3
;
static
const
uint32_t
NUM_QUEUES
=
1536
;
static
const
uint32_t
NUM_QUEUES
=
1536
;
static
const
uint32_t
NUM_PFINTS
=
128
;
static
const
uint32_t
NUM_PFINTS
=
128
;
static
const
uint32_t
NUM_VSIS
=
384
;
static
const
uint32_t
NUM_VSIS
=
384
;
static
const
uint16_t
MAX_MTU
=
2048
;
static
const
uint16_t
MAX_MTU
=
2048
;
static
const
uint8_t
NUM_ITR
=
3
;
static
const
uint8_t
NUM_ITR
=
3
;
struct
i40e_regs
{
struct
i40e_regs
{
uint32_t
glgen_rstctl
;
uint32_t
glgen_rstctl
;
uint32_t
glgen_stat
;
uint32_t
glgen_stat
;
uint32_t
gllan_rctl_0
;
uint32_t
gllan_rctl_0
;
uint32_t
pfint_lnklst0
;
uint32_t
pfint_lnklst0
;
uint32_t
pfint_icr0_ena
;
uint32_t
pfint_icr0_ena
;
uint32_t
pfint_icr0
;
uint32_t
pfint_icr0
;
uint32_t
pfint_itr0
[
NUM_ITR
];
uint32_t
pfint_itr0
[
NUM_ITR
];
uint32_t
pfint_itrn
[
NUM_ITR
][
NUM_PFINTS
];
uint32_t
pfint_itrn
[
NUM_ITR
][
NUM_PFINTS
];
uint32_t
pfint_stat_ctl0
;
uint32_t
pfint_stat_ctl0
;
uint32_t
pfint_dyn_ctl0
;
uint32_t
pfint_dyn_ctl0
;
uint32_t
pfint_dyn_ctln
[
NUM_PFINTS
-
1
];
uint32_t
pfint_dyn_ctln
[
NUM_PFINTS
-
1
];
uint32_t
pfint_lnklstn
[
NUM_PFINTS
-
1
];
uint32_t
pfint_lnklstn
[
NUM_PFINTS
-
1
];
uint32_t
pfint_raten
[
NUM_PFINTS
-
1
];
uint32_t
pfint_raten
[
NUM_PFINTS
-
1
];
uint32_t
gllan_txpre_qdis
[
12
];
uint32_t
gllan_txpre_qdis
[
12
];
uint32_t
glnvm_srctl
;
uint32_t
glnvm_srctl
;
uint32_t
glnvm_srdata
;
uint32_t
glnvm_srdata
;
uint32_t
qint_tqctl
[
NUM_QUEUES
];
uint32_t
qint_tqctl
[
NUM_QUEUES
];
uint32_t
qtx_ena
[
NUM_QUEUES
];
uint32_t
qtx_ena
[
NUM_QUEUES
];
uint32_t
qtx_tail
[
NUM_QUEUES
];
uint32_t
qtx_tail
[
NUM_QUEUES
];
uint32_t
qtx_ctl
[
NUM_QUEUES
];
uint32_t
qtx_ctl
[
NUM_QUEUES
];
uint32_t
qint_rqctl
[
NUM_QUEUES
];
uint32_t
qint_rqctl
[
NUM_QUEUES
];
uint32_t
qrx_ena
[
NUM_QUEUES
];
uint32_t
qrx_ena
[
NUM_QUEUES
];
uint32_t
qrx_tail
[
NUM_QUEUES
];
uint32_t
qrx_tail
[
NUM_QUEUES
];
uint32_t
glhmc_lantxbase
[
16
];
uint32_t
glhmc_lantxbase
[
16
];
uint32_t
glhmc_lantxcnt
[
16
];
uint32_t
glhmc_lantxcnt
[
16
];
uint32_t
glhmc_lanrxbase
[
16
];
uint32_t
glhmc_lanrxbase
[
16
];
uint32_t
glhmc_lanrxcnt
[
16
];
uint32_t
glhmc_lanrxcnt
[
16
];
uint32_t
pfhmc_sdcmd
;
uint32_t
pfhmc_sdcmd
;
uint32_t
pfhmc_sddatalow
;
uint32_t
pfhmc_sddatalow
;
uint32_t
pfhmc_sddatahigh
;
uint32_t
pfhmc_sddatahigh
;
uint32_t
pfhmc_pdinv
;
uint32_t
pfhmc_pdinv
;
uint32_t
pfhmc_errorinfo
;
uint32_t
pfhmc_errorinfo
;
uint32_t
pfhmc_errordata
;
uint32_t
pfhmc_errordata
;
uint64_t
pf_atqba
;
uint64_t
pf_atqba
;
uint32_t
pf_atqlen
;
uint32_t
pf_atqlen
;
uint32_t
pf_atqh
;
uint32_t
pf_atqh
;
uint32_t
pf_atqt
;
uint32_t
pf_atqt
;
uint64_t
pf_arqba
;
uint64_t
pf_arqba
;
uint32_t
pf_arqlen
;
uint32_t
pf_arqlen
;
uint32_t
pf_arqh
;
uint32_t
pf_arqh
;
uint32_t
pf_arqt
;
uint32_t
pf_arqt
;
uint32_t
pfqf_ctl_0
;
uint32_t
pfqf_ctl_0
;
uint32_t
pfqf_hkey
[
13
];
uint32_t
pfqf_hkey
[
13
];
uint32_t
pfqf_hlut
[
128
];
uint32_t
pfqf_hlut
[
128
];
uint32_t
prtdcb_fccfg
;
uint32_t
prtdcb_fccfg
;
uint32_t
prtdcb_mflcn
;
uint32_t
prtdcb_mflcn
;
uint32_t
prt_l2tagsen
;
uint32_t
prt_l2tagsen
;
uint32_t
prtqf_ctl_0
;
uint32_t
prtqf_ctl_0
;
uint32_t
glrpb_ghw
;
uint32_t
glrpb_ghw
;
uint32_t
glrpb_glw
;
uint32_t
glrpb_glw
;
uint32_t
glrpb_phw
;
uint32_t
glrpb_phw
;
uint32_t
glrpb_plw
;
uint32_t
glrpb_plw
;
};
};
public:
public:
i40e_bm
();
i40e_bm
();
~
i40e_bm
();
~
i40e_bm
();
virtual
void
setup_intro
(
struct
cosim_pcie_proto_dev_intro
&
di
);
virtual
void
setup_intro
(
struct
cosim_pcie_proto_dev_intro
&
di
);
virtual
void
reg_read
(
uint8_t
bar
,
uint64_t
addr
,
void
*
dest
,
size_t
len
);
virtual
void
reg_read
(
uint8_t
bar
,
uint64_t
addr
,
void
*
dest
,
size_t
len
);
virtual
uint32_t
reg_read32
(
uint8_t
bar
,
uint64_t
addr
);
virtual
uint32_t
reg_read32
(
uint8_t
bar
,
uint64_t
addr
);
virtual
void
reg_write
(
uint8_t
bar
,
uint64_t
addr
,
const
void
*
src
,
virtual
void
reg_write
(
uint8_t
bar
,
uint64_t
addr
,
const
void
*
src
,
size_t
len
);
size_t
len
);
virtual
void
reg_write32
(
uint8_t
bar
,
uint64_t
addr
,
uint32_t
val
);
virtual
void
reg_write32
(
uint8_t
bar
,
uint64_t
addr
,
uint32_t
val
);
virtual
void
dma_complete
(
nicbm
::
DMAOp
&
op
);
virtual
void
dma_complete
(
nicbm
::
DMAOp
&
op
);
virtual
void
eth_rx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
);
virtual
void
eth_rx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
);
virtual
void
timed_event
(
nicbm
::
TimedEvent
&
ev
);
virtual
void
timed_event
(
nicbm
::
TimedEvent
&
ev
);
void
signal_interrupt
(
uint16_t
vector
,
uint8_t
itr
);
void
signal_interrupt
(
uint16_t
vector
,
uint8_t
itr
);
protected:
protected:
logger
log
;
logger
log
;
i40e_regs
regs
;
i40e_regs
regs
;
queue_admin_tx
pf_atq
;
queue_admin_tx
pf_atq
;
host_mem_cache
hmc
;
host_mem_cache
hmc
;
shadow_ram
shram
;
shadow_ram
shram
;
lan
lanmgr
;
lan
lanmgr
;
int_ev
intevs
[
NUM_PFINTS
];
int_ev
intevs
[
NUM_PFINTS
];
/** Read from the I/O bar */
/** Read from the I/O bar */
virtual
uint32_t
reg_io_read
(
uint64_t
addr
);
virtual
uint32_t
reg_io_read
(
uint64_t
addr
);
/** Write to the I/O bar */
/** Write to the I/O bar */
virtual
void
reg_io_write
(
uint64_t
addr
,
uint32_t
val
);
virtual
void
reg_io_write
(
uint64_t
addr
,
uint32_t
val
);
/** 32-bit read from the memory bar (should be the default) */
/** 32-bit read from the memory bar (should be the default) */
virtual
uint32_t
reg_mem_read32
(
uint64_t
addr
);
virtual
uint32_t
reg_mem_read32
(
uint64_t
addr
);
/** 32-bit write to the memory bar (should be the default) */
/** 32-bit write to the memory bar (should be the default) */
virtual
void
reg_mem_write32
(
uint64_t
addr
,
uint32_t
val
);
virtual
void
reg_mem_write32
(
uint64_t
addr
,
uint32_t
val
);
void
reset
(
bool
indicate_done
);
void
reset
(
bool
indicate_done
);
};
};
// places the tcp checksum in the packet (assuming ipv4)
// places the tcp checksum in the packet (assuming ipv4)
...
@@ -622,10 +623,9 @@ void xsum_tcp(void *tcphdr, size_t l4len);
...
@@ -622,10 +623,9 @@ void xsum_tcp(void *tcphdr, size_t l4len);
// calculates the full ipv4 & tcp checksum without assuming any pseudo header
// calculates the full ipv4 & tcp checksum without assuming any pseudo header
// xsums
// xsums
void
xsum_tcpip_tso
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
void
xsum_tcpip_tso
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
uint16_t
paylen
);
uint16_t
paylen
);
void
tso_postupdate_header
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
void
tso_postupdate_header
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
uint16_t
paylen
);
uint16_t
paylen
);
}
// namespace i40e
}
// namespace i40e
sims/nic/i40e_bm/i40e_hmc.cc
View file @
d4666c97
...
@@ -24,122 +24,118 @@
...
@@ -24,122 +24,118 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <cassert>
#include <cassert>
#include <iostream>
#include <iostream>
#include "sims/nic/i40e_bm/i40e_bm.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_bm.h"
using
namespace
i40e
;
using
namespace
i40e
;
extern
nicbm
::
Runner
*
runner
;
extern
nicbm
::
Runner
*
runner
;
host_mem_cache
::
host_mem_cache
(
i40e_bm
&
dev_
)
host_mem_cache
::
host_mem_cache
(
i40e_bm
&
dev_
)
:
dev
(
dev_
)
{
:
dev
(
dev_
)
reset
();
{
reset
();
}
}
void
host_mem_cache
::
reset
()
void
host_mem_cache
::
reset
()
{
{
for
(
size_t
i
=
0
;
i
<
MAX_SEGMENTS
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
MAX_SEGMENTS
;
i
++
)
{
segs
[
i
].
addr
=
0
;
segs
[
i
].
addr
=
0
;
segs
[
i
].
pgcount
=
0
;
segs
[
i
].
pgcount
=
0
;
segs
[
i
].
valid
=
false
;
segs
[
i
].
valid
=
false
;
segs
[
i
].
direct
=
false
;
segs
[
i
].
direct
=
false
;
}
}
}
}
void
host_mem_cache
::
reg_updated
(
uint64_t
addr
)
void
host_mem_cache
::
reg_updated
(
uint64_t
addr
)
{
{
if
(
addr
==
I40E_PFHMC_SDCMD
)
{
if
(
addr
==
I40E_PFHMC_SDCMD
)
{
// read/write command for descriptor
// read/write command for descriptor
uint32_t
cmd
=
dev
.
regs
.
pfhmc_sdcmd
;
uint32_t
cmd
=
dev
.
regs
.
pfhmc_sdcmd
;
uint16_t
idx
=
uint16_t
idx
=
(
cmd
&
I40E_PFHMC_SDCMD_PMSDIDX_MASK
)
>>
(
cmd
&
I40E_PFHMC_SDCMD_PMSDIDX_MASK
)
>>
I40E_PFHMC_SDCMD_PMSDIDX_SHIFT
;
I40E_PFHMC_SDCMD_PMSDIDX_SHIFT
;
uint32_t
lo
=
dev
.
regs
.
pfhmc_sddatalow
;
uint32_t
lo
=
dev
.
regs
.
pfhmc_sddatalow
;
uint32_t
hi
=
dev
.
regs
.
pfhmc_sddatahigh
;
uint32_t
hi
=
dev
.
regs
.
pfhmc_sddatahigh
;
if
((
cmd
&
I40E_PFHMC_SDCMD_PMSDWR_MASK
))
{
if
((
cmd
&
I40E_PFHMC_SDCMD_PMSDWR_MASK
))
{
// write
// write
#ifdef DEBUG_HMC
#ifdef DEBUG_HMC
std
::
cerr
<<
"hmc: writing descriptor "
<<
idx
<<
std
::
endl
;
std
::
cerr
<<
"hmc: writing descriptor "
<<
idx
<<
std
::
endl
;
#endif
#endif
segs
[
idx
].
addr
=
((
lo
&
I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK
)
>>
segs
[
idx
].
addr
=
((
lo
&
I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK
)
>>
I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT
)
<<
12
;
I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT
)
segs
[
idx
].
addr
|=
((
uint64_t
)
hi
)
<<
32
;
<<
12
;
segs
[
idx
].
pgcount
=
(
lo
&
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK
)
>>
segs
[
idx
].
addr
|=
((
uint64_t
)
hi
)
<<
32
;
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT
;
segs
[
idx
].
pgcount
=
(
lo
&
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK
)
>>
segs
[
idx
].
valid
=
!!
(
lo
&
I40E_PFHMC_SDDATALOW_PMSDVALID_MASK
);
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT
;
segs
[
idx
].
direct
=
!!
(
lo
&
I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK
);
segs
[
idx
].
valid
=
!!
(
lo
&
I40E_PFHMC_SDDATALOW_PMSDVALID_MASK
);
segs
[
idx
].
direct
=
!!
(
lo
&
I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK
);
#ifdef DEBUG_HMC
#ifdef DEBUG_HMC
std
::
cerr
<<
" addr="
<<
segs
[
idx
].
addr
<<
" pgcount="
<<
std
::
cerr
<<
" addr="
<<
segs
[
idx
].
addr
segs
[
idx
].
pgcount
<<
" valid="
<<
segs
[
idx
].
valid
<<
<<
" pgcount="
<<
segs
[
idx
].
pgcount
" direct="
<<
segs
[
idx
].
direct
<<
std
::
endl
;
<<
" valid="
<<
segs
[
idx
].
valid
<<
" direct="
<<
segs
[
idx
].
direct
<<
std
::
endl
;
#endif
#endif
}
else
{
}
else
{
// read
// read
#ifdef DEBUG_HMC
#ifdef DEBUG_HMC
std
::
cerr
<<
"hmc: reading descriptor "
<<
idx
<<
std
::
endl
;
std
::
cerr
<<
"hmc: reading descriptor "
<<
idx
<<
std
::
endl
;
#endif
#endif
dev
.
regs
.
pfhmc_sddatalow
=
((
segs
[
idx
].
addr
>>
12
)
<<
dev
.
regs
.
pfhmc_sddatalow
=
I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT
)
&
((
segs
[
idx
].
addr
>>
12
)
<<
I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT
)
&
I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK
;
I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK
;
dev
.
regs
.
pfhmc_sddatalow
|=
(
segs
[
idx
].
pgcount
<<
dev
.
regs
.
pfhmc_sddatalow
|=
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT
)
&
(
segs
[
idx
].
pgcount
<<
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT
)
&
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK
;
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK
;
if
(
segs
[
idx
].
valid
)
if
(
segs
[
idx
].
valid
)
dev
.
regs
.
pfhmc_sddatalow
|=
I40E_PFHMC_SDDATALOW_PMSDVALID_MASK
;
dev
.
regs
.
pfhmc_sddatalow
|=
I40E_PFHMC_SDDATALOW_PMSDVALID_MASK
;
if
(
segs
[
idx
].
direct
)
if
(
segs
[
idx
].
direct
)
dev
.
regs
.
pfhmc_sddatalow
|=
I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK
;
dev
.
regs
.
pfhmc_sddatalow
|=
I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK
;
dev
.
regs
.
pfhmc_sddatahigh
=
segs
[
idx
].
addr
>>
32
;
dev
.
regs
.
pfhmc_sddatahigh
=
segs
[
idx
].
addr
>>
32
;
}
}
}
}
}
}
void
host_mem_cache
::
issue_mem_op
(
mem_op
&
op
)
void
host_mem_cache
::
issue_mem_op
(
mem_op
&
op
)
{
{
uint64_t
addr
=
op
.
dma_addr
;
uint64_t
addr
=
op
.
dma_addr
;
uint16_t
seg_idx
=
addr
>>
21
;
uint16_t
seg_idx
=
addr
>>
21
;
uint16_t
seg_idx_last
=
(
addr
+
op
.
len
-
1
)
>>
21
;
uint16_t
seg_idx_last
=
(
addr
+
op
.
len
-
1
)
>>
21
;
uint32_t
dir_off
=
addr
&
((
1
<<
21
)
-
1
);
uint32_t
dir_off
=
addr
&
((
1
<<
21
)
-
1
);
struct
segment
*
seg
=
&
segs
[
seg_idx
];
struct
segment
*
seg
=
&
segs
[
seg_idx
];
if
(
seg_idx
>=
MAX_SEGMENTS
)
{
if
(
seg_idx
>=
MAX_SEGMENTS
)
{
std
::
cerr
<<
"hmc issue_mem_op: seg index too high "
<<
seg_idx
std
::
cerr
<<
"hmc issue_mem_op: seg index too high "
<<
seg_idx
<<
<<
std
::
endl
;
std
::
endl
;
abort
();
abort
();
}
}
if
(
!
seg
->
valid
)
{
if
(
!
seg
->
valid
)
{
// TODO(antoinek): errorinfo and data registers
// TODO(antoinek): errorinfo and data registers
std
::
cerr
<<
"hmc issue_mem_op: segment invalid addr="
<<
addr
<<
std
::
endl
;
std
::
cerr
<<
"hmc issue_mem_op: segment invalid addr="
<<
addr
<<
op
.
failed
=
true
;
std
::
endl
;
return
;
op
.
failed
=
true
;
}
return
;
}
if
(
seg_idx
!=
seg_idx_last
)
{
std
::
cerr
<<
"hmc issue_mem_op: operation crosses segs addr="
<<
addr
if
(
seg_idx
!=
seg_idx_last
)
{
<<
" len="
<<
op
.
len
<<
std
::
endl
;
std
::
cerr
<<
"hmc issue_mem_op: operation crosses segs addr="
<<
abort
();
addr
<<
" len="
<<
op
.
len
<<
std
::
endl
;
}
abort
();
}
if
(
!
seg
->
direct
)
{
std
::
cerr
<<
"hmc issue_mem_op: TODO paged ops addr="
<<
addr
<<
std
::
endl
;
if
(
!
seg
->
direct
)
{
abort
();
std
::
cerr
<<
"hmc issue_mem_op: TODO paged ops addr="
<<
addr
<<
}
std
::
endl
;
abort
();
op
.
failed
=
false
;
}
op
.
dma_addr
=
seg
->
addr
+
dir_off
;
op
.
failed
=
false
;
op
.
dma_addr
=
seg
->
addr
+
dir_off
;
#ifdef DEBUG_HMC
#ifdef DEBUG_HMC
std
::
cerr
<<
"hmc issue_mem_op: hmc_addr="
<<
addr
<<
" dma_addr="
<<
std
::
cerr
<<
"hmc issue_mem_op: hmc_addr="
<<
addr
op
.
dma_addr
<<
" len="
<<
op
.
len
<<
std
::
endl
;
<<
" dma_addr="
<<
op
.
dma_addr
<<
" len="
<<
op
.
len
<<
std
::
endl
;
#endif
#endif
runner
->
issue_dma
(
op
);
runner
->
issue_dma
(
op
);
}
}
sims/nic/i40e_bm/i40e_lan.cc
View file @
d4666c97
...
@@ -22,726 +22,690 @@
...
@@ -22,726 +22,690 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
*/
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <cassert>
#include <cassert>
#include <iostream>
#include <iostream>
#include <arpa/inet.h>
#include "sims/nic/i40e_bm/i40e_bm.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/headers.h"
#include "sims/nic/i40e_bm/headers.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_bm.h"
using
namespace
i40e
;
using
namespace
i40e
;
extern
nicbm
::
Runner
*
runner
;
extern
nicbm
::
Runner
*
runner
;
lan
::
lan
(
i40e_bm
&
dev_
,
size_t
num_qs_
)
lan
::
lan
(
i40e_bm
&
dev_
,
size_t
num_qs_
)
:
dev
(
dev_
),
log
(
"lan"
),
rss_kc
(
dev_
.
regs
.
pfqf_hkey
),
num_qs
(
num_qs_
)
:
dev
(
dev_
),
log
(
"lan"
),
rss_kc
(
dev_
.
regs
.
pfqf_hkey
),
num_qs
(
num_qs_
)
{
{
rxqs
=
new
lan_queue_rx
*
[
num_qs
];
rxqs
=
new
lan_queue_rx
*
[
num_qs
];
txqs
=
new
lan_queue_tx
*
[
num_qs
];
txqs
=
new
lan_queue_tx
*
[
num_qs
];
for
(
size_t
i
=
0
;
i
<
num_qs
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
num_qs
;
i
++
)
{
rxqs
[
i
]
=
rxqs
[
i
]
=
new
lan_queue_rx
(
*
this
,
dev
.
regs
.
qrx_tail
[
i
],
i
,
new
lan_queue_rx
(
*
this
,
dev
.
regs
.
qrx_tail
[
i
],
i
,
dev
.
regs
.
qrx_ena
[
i
],
dev
.
regs
.
qrx_ena
[
i
],
dev
.
regs
.
glhmc_lanrxbase
[
0
],
dev
.
regs
.
glhmc_lanrxbase
[
0
],
dev
.
regs
.
qint_rqctl
[
i
]);
dev
.
regs
.
qint_rqctl
[
i
]);
txqs
[
i
]
=
txqs
[
i
]
=
new
lan_queue_tx
(
*
this
,
dev
.
regs
.
qtx_tail
[
i
],
i
,
new
lan_queue_tx
(
*
this
,
dev
.
regs
.
qtx_tail
[
i
],
i
,
dev
.
regs
.
qtx_ena
[
i
],
dev
.
regs
.
qtx_ena
[
i
],
dev
.
regs
.
glhmc_lantxbase
[
0
],
dev
.
regs
.
glhmc_lantxbase
[
0
],
dev
.
regs
.
qint_tqctl
[
i
]);
dev
.
regs
.
qint_tqctl
[
i
]);
}
}
}
}
void
lan
::
reset
()
{
void
lan
::
reset
()
rss_kc
.
set_dirty
();
{
for
(
size_t
i
=
0
;
i
<
num_qs
;
i
++
)
{
rss_kc
.
set_dirty
();
rxqs
[
i
]
->
reset
();
for
(
size_t
i
=
0
;
i
<
num_qs
;
i
++
)
{
txqs
[
i
]
->
reset
();
rxqs
[
i
]
->
reset
();
}
txqs
[
i
]
->
reset
();
}
}
}
void
lan
::
qena_updated
(
uint16_t
idx
,
bool
rx
)
{
uint32_t
&
reg
=
(
rx
?
dev
.
regs
.
qrx_ena
[
idx
]
:
dev
.
regs
.
qtx_ena
[
idx
]);
void
lan
::
qena_updated
(
uint16_t
idx
,
bool
rx
)
{
uint32_t
&
reg
=
(
rx
?
dev
.
regs
.
qrx_ena
[
idx
]
:
dev
.
regs
.
qtx_ena
[
idx
]);
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" qena updated idx="
<<
idx
<<
" rx="
<<
rx
<<
" reg="
<<
reg
<<
log
<<
" qena updated idx="
<<
idx
<<
" rx="
<<
rx
<<
" reg="
<<
reg
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
lan_queue_base
&
q
=
(
rx
?
static_cast
<
lan_queue_base
&>
(
*
rxqs
[
idx
])
:
lan_queue_base
&
q
=
(
rx
?
static_cast
<
lan_queue_base
&>
(
*
rxqs
[
idx
])
static_cast
<
lan_queue_base
&>
(
*
txqs
[
idx
]));
:
static_cast
<
lan_queue_base
&>
(
*
txqs
[
idx
]));
if
((
reg
&
I40E_QRX_ENA_QENA_REQ_MASK
)
&&
!
q
.
is_enabled
())
{
if
((
reg
&
I40E_QRX_ENA_QENA_REQ_MASK
)
&&
!
q
.
is_enabled
())
{
q
.
enable
();
q
.
enable
();
}
else
if
(
!
(
reg
&
I40E_QRX_ENA_QENA_REQ_MASK
)
&&
q
.
is_enabled
())
{
}
else
if
(
!
(
reg
&
I40E_QRX_ENA_QENA_REQ_MASK
)
&&
q
.
is_enabled
())
{
q
.
disable
();
q
.
disable
();
}
}
}
}
void
lan
::
tail_updated
(
uint16_t
idx
,
bool
rx
)
void
lan
::
tail_updated
(
uint16_t
idx
,
bool
rx
)
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" tail updated idx="
<<
idx
<<
" rx="
<<
rx
<<
logger
::
endl
;
log
<<
" tail updated idx="
<<
idx
<<
" rx="
<<
rx
<<
logger
::
endl
;
#endif
#endif
lan_queue_base
&
q
=
(
rx
?
static_cast
<
lan_queue_base
&>
(
*
rxqs
[
idx
])
:
lan_queue_base
&
q
=
(
rx
?
static_cast
<
lan_queue_base
&>
(
*
rxqs
[
idx
])
static_cast
<
lan_queue_base
&>
(
*
txqs
[
idx
]));
:
static_cast
<
lan_queue_base
&>
(
*
txqs
[
idx
]));
if
(
q
.
is_enabled
())
if
(
q
.
is_enabled
())
q
.
reg_updated
();
q
.
reg_updated
();
}
}
void
lan
::
rss_key_updated
()
void
lan
::
rss_key_updated
()
{
{
rss_kc
.
set_dirty
();
rss_kc
.
set_dirty
();
}
}
bool
lan
::
rss_steering
(
const
void
*
data
,
size_t
len
,
uint16_t
&
queue
,
bool
lan
::
rss_steering
(
const
void
*
data
,
size_t
len
,
uint16_t
&
queue
,
uint32_t
&
hash
)
uint32_t
&
hash
)
{
{
hash
=
0
;
hash
=
0
;
const
headers
::
pkt_tcp
*
tcp
=
const
headers
::
pkt_tcp
*
tcp
=
reinterpret_cast
<
const
headers
::
pkt_tcp
*>
(
data
);
reinterpret_cast
<
const
headers
::
pkt_tcp
*>
(
data
);
const
headers
::
pkt_udp
*
udp
=
const
headers
::
pkt_udp
*
udp
=
reinterpret_cast
<
const
headers
::
pkt_udp
*>
(
data
);
reinterpret_cast
<
const
headers
::
pkt_udp
*>
(
data
);
// should actually determine packet type and mask with enabled packet types
// should actually determine packet type and mask with enabled packet types
// TODO(antoinek): ipv6
// TODO(antoinek): ipv6
if
(
tcp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
)
&&
tcp
->
ip
.
proto
==
IP_PROTO_TCP
)
{
if
(
tcp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
)
&&
hash
=
rss_kc
.
hash_ipv4
(
ntohl
(
tcp
->
ip
.
src
),
ntohl
(
tcp
->
ip
.
dest
),
tcp
->
ip
.
proto
==
IP_PROTO_TCP
)
{
ntohs
(
tcp
->
tcp
.
src
),
ntohs
(
tcp
->
tcp
.
dest
));
hash
=
rss_kc
.
hash_ipv4
(
ntohl
(
tcp
->
ip
.
src
),
ntohl
(
tcp
->
ip
.
dest
),
}
else
if
(
udp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
)
&&
ntohs
(
tcp
->
tcp
.
src
),
ntohs
(
tcp
->
tcp
.
dest
));
udp
->
ip
.
proto
==
IP_PROTO_UDP
)
{
}
else
if
(
udp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
)
&&
hash
=
rss_kc
.
hash_ipv4
(
ntohl
(
udp
->
ip
.
src
),
ntohl
(
udp
->
ip
.
dest
),
udp
->
ip
.
proto
==
IP_PROTO_UDP
)
{
ntohs
(
udp
->
udp
.
src
),
ntohs
(
udp
->
udp
.
dest
));
hash
=
rss_kc
.
hash_ipv4
(
ntohl
(
udp
->
ip
.
src
),
ntohl
(
udp
->
ip
.
dest
),
}
else
if
(
udp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
))
{
ntohs
(
udp
->
udp
.
src
),
ntohs
(
udp
->
udp
.
dest
));
hash
=
rss_kc
.
hash_ipv4
(
ntohl
(
udp
->
ip
.
src
),
ntohl
(
udp
->
ip
.
dest
),
0
,
0
);
}
else
if
(
udp
->
eth
.
type
==
htons
(
ETH_TYPE_IP
))
{
}
else
{
hash
=
rss_kc
.
hash_ipv4
(
ntohl
(
udp
->
ip
.
src
),
ntohl
(
udp
->
ip
.
dest
),
0
,
0
);
return
false
;
}
else
{
}
return
false
;
}
uint16_t
luts
=
(
!
(
dev
.
regs
.
pfqf_ctl_0
&
I40E_PFQF_CTL_0_HASHLUTSIZE_MASK
)
?
128
:
512
);
uint16_t
luts
=
(
!
(
dev
.
regs
.
pfqf_ctl_0
&
I40E_PFQF_CTL_0_HASHLUTSIZE_MASK
)
?
uint16_t
idx
=
hash
%
luts
;
128
:
512
);
queue
=
(
dev
.
regs
.
pfqf_hlut
[
idx
/
4
]
>>
(
8
*
(
idx
%
4
)))
&
0x3f
;
uint16_t
idx
=
hash
%
luts
;
queue
=
(
dev
.
regs
.
pfqf_hlut
[
idx
/
4
]
>>
(
8
*
(
idx
%
4
)))
&
0x3f
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" q="
<<
queue
<<
" h="
<<
hash
<<
" i="
<<
idx
<<
logger
::
endl
;
log
<<
" q="
<<
queue
<<
" h="
<<
hash
<<
" i="
<<
idx
<<
logger
::
endl
;
#endif
#endif
return
true
;
return
true
;
}
}
void
lan
::
packet_received
(
const
void
*
data
,
size_t
len
)
void
lan
::
packet_received
(
const
void
*
data
,
size_t
len
)
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" packet received len="
<<
len
<<
logger
::
endl
;
log
<<
" packet received len="
<<
len
<<
logger
::
endl
;
#endif
#endif
uint32_t
hash
=
0
;
uint32_t
hash
=
0
;
uint16_t
queue
=
0
;
uint16_t
queue
=
0
;
rss_steering
(
data
,
len
,
queue
,
hash
);
rss_steering
(
data
,
len
,
queue
,
hash
);
rxqs
[
queue
]
->
packet_received
(
data
,
len
,
hash
);
rxqs
[
queue
]
->
packet_received
(
data
,
len
,
hash
);
}
}
lan_queue_base
::
lan_queue_base
(
lan
&
lanmgr_
,
const
std
::
string
&
qtype
,
lan_queue_base
::
lan_queue_base
(
lan
&
lanmgr_
,
const
std
::
string
&
qtype
,
uint32_t
&
reg_tail_
,
size_t
idx_
,
uint32_t
&
reg_tail_
,
size_t
idx_
,
uint32_t
&
reg_ena_
,
uint32_t
&
fpm_basereg_
,
uint32_t
&
reg_intqctl_
,
uint32_t
&
reg_ena_
,
uint32_t
&
fpm_basereg_
,
uint16_t
ctx_size_
)
uint32_t
&
reg_intqctl_
,
uint16_t
ctx_size_
)
:
queue_base
(
qtype
+
std
::
to_string
(
idx_
),
reg_dummy_head
,
reg_tail_
),
:
queue_base
(
qtype
+
std
::
to_string
(
idx_
),
reg_dummy_head
,
reg_tail_
),
lanmgr
(
lanmgr_
),
enabling
(
false
),
lanmgr
(
lanmgr_
),
idx
(
idx_
),
reg_ena
(
reg_ena_
),
fpm_basereg
(
fpm_basereg_
),
enabling
(
false
),
reg_intqctl
(
reg_intqctl_
),
ctx_size
(
ctx_size_
)
idx
(
idx_
),
{
reg_ena
(
reg_ena_
),
ctx
=
new
uint8_t
[
ctx_size_
];
fpm_basereg
(
fpm_basereg_
),
reg_intqctl
(
reg_intqctl_
),
ctx_size
(
ctx_size_
)
{
ctx
=
new
uint8_t
[
ctx_size_
];
}
}
void
lan_queue_base
::
reset
()
void
lan_queue_base
::
reset
()
{
{
enabling
=
false
;
enabling
=
false
;
queue_base
::
reset
();
queue_base
::
reset
();
}
}
void
lan_queue_base
::
enable
()
void
lan_queue_base
::
enable
()
{
{
if
(
enabling
||
enabled
)
if
(
enabling
||
enabled
)
return
;
return
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" lan enabling queue "
<<
idx
<<
logger
::
endl
;
log
<<
" lan enabling queue "
<<
idx
<<
logger
::
endl
;
#endif
#endif
enabling
=
true
;
enabling
=
true
;
qctx_fetch
*
qf
=
new
qctx_fetch
(
*
this
);
qctx_fetch
*
qf
=
new
qctx_fetch
(
*
this
);
qf
->
write
=
false
;
qf
->
write
=
false
;
qf
->
dma_addr
=
((
fpm_basereg
&
I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK
)
>>
qf
->
dma_addr
=
((
fpm_basereg
&
I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK
)
>>
I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT
)
*
512
;
I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT
)
*
qf
->
dma_addr
+=
ctx_size
*
idx
;
512
;
qf
->
len
=
ctx_size
;
qf
->
dma_addr
+=
ctx_size
*
idx
;
qf
->
data
=
ctx
;
qf
->
len
=
ctx_size
;
qf
->
data
=
ctx
;
lanmgr
.
dev
.
hmc
.
issue_mem_op
(
*
qf
);
lanmgr
.
dev
.
hmc
.
issue_mem_op
(
*
qf
);
}
}
void
lan_queue_base
::
ctx_fetched
()
void
lan_queue_base
::
ctx_fetched
()
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" lan ctx fetched "
<<
idx
<<
logger
::
endl
;
log
<<
" lan ctx fetched "
<<
idx
<<
logger
::
endl
;
#endif
#endif
initialize
();
initialize
();
enabling
=
false
;
enabling
=
false
;
enabled
=
true
;
enabled
=
true
;
reg_ena
|=
I40E_QRX_ENA_QENA_STAT_MASK
;
reg_ena
|=
I40E_QRX_ENA_QENA_STAT_MASK
;
reg_updated
();
reg_updated
();
}
}
void
lan_queue_base
::
disable
()
void
lan_queue_base
::
disable
()
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" lan disabling queue "
<<
idx
<<
logger
::
endl
;
log
<<
" lan disabling queue "
<<
idx
<<
logger
::
endl
;
#endif
#endif
enabled
=
false
;
enabled
=
false
;
// TODO(antoinek): write back
// TODO(antoinek): write back
reg_ena
&=
~
I40E_QRX_ENA_QENA_STAT_MASK
;
reg_ena
&=
~
I40E_QRX_ENA_QENA_STAT_MASK
;
}
}
void
lan_queue_base
::
interrupt
()
void
lan_queue_base
::
interrupt
()
{
{
uint32_t
qctl
=
reg_intqctl
;
uint32_t
qctl
=
reg_intqctl
;
uint32_t
gctl
=
lanmgr
.
dev
.
regs
.
pfint_dyn_ctl0
;
uint32_t
gctl
=
lanmgr
.
dev
.
regs
.
pfint_dyn_ctl0
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" interrupt qctl="
<<
qctl
<<
" gctl="
<<
gctl
<<
logger
::
endl
;
log
<<
" interrupt qctl="
<<
qctl
<<
" gctl="
<<
gctl
<<
logger
::
endl
;
#endif
#endif
uint16_t
msix_idx
=
(
qctl
&
I40E_QINT_TQCTL_MSIX_INDX_MASK
)
>>
uint16_t
msix_idx
=
(
qctl
&
I40E_QINT_TQCTL_MSIX_INDX_MASK
)
>>
I40E_QINT_TQCTL_MSIX_INDX_SHIFT
;
I40E_QINT_TQCTL_MSIX_INDX_SHIFT
;
uint8_t
msix0_idx
=
(
qctl
&
I40E_QINT_TQCTL_MSIX0_INDX_MASK
)
>>
uint8_t
msix0_idx
=
(
qctl
&
I40E_QINT_TQCTL_MSIX0_INDX_MASK
)
>>
I40E_QINT_TQCTL_MSIX0_INDX_SHIFT
;
I40E_QINT_TQCTL_MSIX0_INDX_SHIFT
;
bool
cause_ena
=
!!
(
qctl
&
I40E_QINT_TQCTL_CAUSE_ENA_MASK
)
&&
bool
cause_ena
=
!!
(
qctl
&
I40E_QINT_TQCTL_CAUSE_ENA_MASK
)
&&
!!
(
gctl
&
I40E_PFINT_DYN_CTL0_INTENA_MASK
);
!!
(
gctl
&
I40E_PFINT_DYN_CTL0_INTENA_MASK
);
if
(
!
cause_ena
)
{
if
(
!
cause_ena
)
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" interrupt cause disabled"
<<
logger
::
endl
;
log
<<
" interrupt cause disabled"
<<
logger
::
endl
;
#endif
#endif
return
;
return
;
}
}
if
(
msix_idx
==
0
)
{
if
(
msix_idx
==
0
)
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" setting int0.qidx="
<<
msix0_idx
<<
logger
::
endl
;
log
<<
" setting int0.qidx="
<<
msix0_idx
<<
logger
::
endl
;
#endif
#endif
lanmgr
.
dev
.
regs
.
pfint_icr0
|=
I40E_PFINT_ICR0_INTEVENT_MASK
|
lanmgr
.
dev
.
regs
.
pfint_icr0
|=
(
1
<<
(
I40E_PFINT_ICR0_QUEUE_0_SHIFT
+
msix0_idx
));
I40E_PFINT_ICR0_INTEVENT_MASK
|
}
(
1
<<
(
I40E_PFINT_ICR0_QUEUE_0_SHIFT
+
msix0_idx
));
}
uint8_t
itr
=
(
qctl
&
I40E_QINT_TQCTL_ITR_INDX_MASK
)
>>
uint8_t
itr
=
I40E_QINT_TQCTL_ITR_INDX_SHIFT
;
(
qctl
&
I40E_QINT_TQCTL_ITR_INDX_MASK
)
>>
I40E_QINT_TQCTL_ITR_INDX_SHIFT
;
lanmgr
.
dev
.
signal_interrupt
(
msix_idx
,
itr
);
lanmgr
.
dev
.
signal_interrupt
(
msix_idx
,
itr
);
}
}
lan_queue_base
::
qctx_fetch
::
qctx_fetch
(
lan_queue_base
&
lq_
)
lan_queue_base
::
qctx_fetch
::
qctx_fetch
(
lan_queue_base
&
lq_
)
:
lq
(
lq_
)
{
:
lq
(
lq_
)
{
}
}
void
lan_queue_base
::
qctx_fetch
::
done
()
void
lan_queue_base
::
qctx_fetch
::
done
()
{
{
lq
.
ctx_fetched
();
lq
.
ctx_fetched
();
delete
this
;
delete
this
;
}
}
lan_queue_rx
::
lan_queue_rx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail_
,
size_t
idx_
,
lan_queue_rx
::
lan_queue_rx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail_
,
size_t
idx_
,
uint32_t
&
reg_ena_
,
uint32_t
&
reg_fpmbase_
,
uint32_t
&
reg_intqctl_
)
uint32_t
&
reg_ena_
,
uint32_t
&
reg_fpmbase_
,
uint32_t
&
reg_intqctl_
)
:
lan_queue_base
(
lanmgr_
,
"rxq"
,
reg_tail_
,
idx_
,
reg_ena_
,
reg_fpmbase_
,
:
lan_queue_base
(
lanmgr_
,
"rxq"
,
reg_tail_
,
idx_
,
reg_ena_
,
reg_fpmbase_
,
reg_intqctl_
,
32
)
reg_intqctl_
,
32
)
{
{
// use larger value for initialization
// use larger value for initialization
desc_len
=
32
;
desc_len
=
32
;
ctxs_init
();
ctxs_init
();
}
}
void
lan_queue_rx
::
reset
()
void
lan_queue_rx
::
reset
()
{
{
dcache
.
clear
();
dcache
.
clear
();
queue_base
::
reset
();
queue_base
::
reset
();
}
}
void
lan_queue_rx
::
initialize
()
void
lan_queue_rx
::
initialize
()
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" initialize()"
<<
logger
::
endl
;
log
<<
" initialize()"
<<
logger
::
endl
;
#endif
#endif
uint8_t
*
ctx_p
=
reinterpret_cast
<
uint8_t
*>
(
ctx
);
uint8_t
*
ctx_p
=
reinterpret_cast
<
uint8_t
*>
(
ctx
);
uint16_t
*
head_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
0
);
uint16_t
*
head_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
0
);
uint64_t
*
base_p
=
reinterpret_cast
<
uint64_t
*>
(
ctx_p
+
4
);
uint64_t
*
base_p
=
reinterpret_cast
<
uint64_t
*>
(
ctx_p
+
4
);
uint16_t
*
qlen_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
11
);
uint16_t
*
qlen_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
11
);
uint16_t
*
dbsz_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
12
);
uint16_t
*
dbsz_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
12
);
uint16_t
*
hbsz_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
13
);
uint16_t
*
hbsz_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
13
);
uint32_t
*
rxmax_p
=
reinterpret_cast
<
uint32_t
*>
(
ctx_p
+
21
);
uint32_t
*
rxmax_p
=
reinterpret_cast
<
uint32_t
*>
(
ctx_p
+
21
);
reg_dummy_head
=
(
*
head_p
)
&
((
1
<<
13
)
-
1
);
reg_dummy_head
=
(
*
head_p
)
&
((
1
<<
13
)
-
1
);
base
=
((
*
base_p
)
&
((
1ULL
<<
57
)
-
1
))
*
128
;
base
=
((
*
base_p
)
&
((
1ULL
<<
57
)
-
1
))
*
128
;
len
=
(
*
qlen_p
>>
1
)
&
((
1
<<
13
)
-
1
);
len
=
(
*
qlen_p
>>
1
)
&
((
1
<<
13
)
-
1
);
dbuff_size
=
(((
*
dbsz_p
)
>>
6
)
&
((
1
<<
7
)
-
1
))
*
128
;
dbuff_size
=
(((
*
dbsz_p
)
>>
6
)
&
((
1
<<
7
)
-
1
))
*
128
;
hbuff_size
=
(((
*
hbsz_p
)
>>
5
)
&
((
1
<<
5
)
-
1
))
*
64
;
hbuff_size
=
(((
*
hbsz_p
)
>>
5
)
&
((
1
<<
5
)
-
1
))
*
64
;
uint8_t
dtype
=
((
*
hbsz_p
)
>>
10
)
&
((
1
<<
2
)
-
1
);
uint8_t
dtype
=
((
*
hbsz_p
)
>>
10
)
&
((
1
<<
2
)
-
1
);
bool
longdesc
=
!!
(((
*
hbsz_p
)
>>
12
)
&
0x1
);
bool
longdesc
=
!!
(((
*
hbsz_p
)
>>
12
)
&
0x1
);
desc_len
=
(
longdesc
?
32
:
16
);
desc_len
=
(
longdesc
?
32
:
16
);
crc_strip
=
!!
(((
*
hbsz_p
)
>>
13
)
&
0x1
);
crc_strip
=
!!
(((
*
hbsz_p
)
>>
13
)
&
0x1
);
rxmax
=
(((
*
rxmax_p
)
>>
6
)
&
((
1
<<
14
)
-
1
))
*
128
;
rxmax
=
(((
*
rxmax_p
)
>>
6
)
&
((
1
<<
14
)
-
1
))
*
128
;
if
(
!
longdesc
)
{
if
(
!
longdesc
)
{
log
<<
"lan_queue_rx::initialize: currently only 32B descs "
log
<<
"lan_queue_rx::initialize: currently only 32B descs "
" supported"
<<
logger
::
endl
;
" supported"
abort
();
<<
logger
::
endl
;
}
abort
();
if
(
dtype
!=
0
)
{
}
log
<<
"lan_queue_rx::initialize: no header split supported"
if
(
dtype
!=
0
)
{
<<
logger
::
endl
;
log
<<
"lan_queue_rx::initialize: no header split supported"
abort
();
<<
logger
::
endl
;
}
abort
();
}
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" head="
<<
reg_dummy_head
<<
" base="
<<
base
<<
log
<<
" head="
<<
reg_dummy_head
<<
" base="
<<
base
<<
" len="
<<
len
" len="
<<
len
<<
" dbsz="
<<
dbuff_size
<<
" hbsz="
<<
hbuff_size
<<
<<
" dbsz="
<<
dbuff_size
<<
" hbsz="
<<
hbuff_size
" dtype="
<<
(
unsigned
)
dtype
<<
" longdesc="
<<
longdesc
<<
<<
" dtype="
<<
(
unsigned
)
dtype
<<
" longdesc="
<<
longdesc
" crcstrip="
<<
crc_strip
<<
" rxmax="
<<
rxmax
<<
logger
::
endl
;
<<
" crcstrip="
<<
crc_strip
<<
" rxmax="
<<
rxmax
<<
logger
::
endl
;
#endif
#endif
}
}
queue_base
::
desc_ctx
&
lan_queue_rx
::
desc_ctx_create
()
queue_base
::
desc_ctx
&
lan_queue_rx
::
desc_ctx_create
()
{
{
return
*
new
rx_desc_ctx
(
*
this
);
return
*
new
rx_desc_ctx
(
*
this
);
}
}
void
lan_queue_rx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
uint32_t
h
)
void
lan_queue_rx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
{
uint32_t
h
)
{
size_t
num_descs
=
(
pktlen
+
dbuff_size
-
1
)
/
dbuff_size
;
size_t
num_descs
=
(
pktlen
+
dbuff_size
-
1
)
/
dbuff_size
;
if
(
!
enabled
)
if
(
!
enabled
)
return
;
return
;
if
(
dcache
.
size
()
<
num_descs
)
{
if
(
dcache
.
size
()
<
num_descs
)
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" not enough rx descs ("
<<
num_descs
<<
", dropping packet"
<<
log
<<
" not enough rx descs ("
<<
num_descs
<<
", dropping packet"
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
return
;
return
;
}
}
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
();
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" packet part="
<<
i
<<
" received didx="
<<
ctx
.
index
<<
log
<<
" packet part="
<<
i
<<
" received didx="
<<
ctx
.
index
" cnt="
<<
dcache
.
size
()
<<
logger
::
endl
;
<<
" cnt="
<<
dcache
.
size
()
<<
logger
::
endl
;
#endif
#endif
dcache
.
pop_front
();
dcache
.
pop_front
();
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
);
}
else
{
}
else
{
ctx
.
packet_received
(
buf
,
dbuff_size
,
false
);
ctx
.
packet_received
(
buf
,
dbuff_size
,
false
);
}
}
}
}
}
}
lan_queue_rx
::
rx_desc_ctx
::
rx_desc_ctx
(
lan_queue_rx
&
queue_
)
lan_queue_rx
::
rx_desc_ctx
::
rx_desc_ctx
(
lan_queue_rx
&
queue_
)
:
desc_ctx
(
queue_
),
rq
(
queue_
)
:
desc_ctx
(
queue_
),
rq
(
queue_
)
{
{
}
}
void
lan_queue_rx
::
rx_desc_ctx
::
data_written
(
uint64_t
addr
,
size_t
len
)
void
lan_queue_rx
::
rx_desc_ctx
::
data_written
(
uint64_t
addr
,
size_t
len
)
{
{
processed
();
processed
();
}
}
void
lan_queue_rx
::
rx_desc_ctx
::
process
()
void
lan_queue_rx
::
rx_desc_ctx
::
process
()
{
{
rq
.
dcache
.
push_back
(
this
);
rq
.
dcache
.
push_back
(
this
);
}
}
void
lan_queue_rx
::
rx_desc_ctx
::
packet_received
(
const
void
*
data
,
void
lan_queue_rx
::
rx_desc_ctx
::
packet_received
(
const
void
*
data
,
size_t
pktlen
,
size_t
pktlen
,
bool
last
)
bool
last
)
{
{
union
i40e_32byte_rx_desc
*
rxd
=
union
i40e_32byte_rx_desc
*
rxd
=
reinterpret_cast
<
reinterpret_cast
<
union
i40e_32byte_rx_desc
*>
(
desc
);
union
i40e_32byte_rx_desc
*>
(
desc
);
uint64_t
addr
=
rxd
->
read
.
pkt_addr
;
uint64_t
addr
=
rxd
->
read
.
pkt_addr
;
memset
(
rxd
,
0
,
sizeof
(
*
rxd
));
memset
(
rxd
,
0
,
sizeof
(
*
rxd
));
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_DD_SHIFT
);
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_DD_SHIFT
);
rxd
->
wb
.
qword1
.
status_error_len
|=
rxd
->
wb
.
qword1
.
status_error_len
|=
(
pktlen
<<
I40E_RXD_QW1_LENGTH_PBUF_SHIFT
);
(
pktlen
<<
I40E_RXD_QW1_LENGTH_PBUF_SHIFT
);
if
(
last
)
{
if
(
last
)
{
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
|=
rxd
->
wb
.
qword1
.
status_error_len
|=
(
1
<<
I40E_RX_DESC_STATUS_L3L4P_SHIFT
);
(
1
<<
I40E_RX_DESC_STATUS_L3L4P_SHIFT
);
}
}
data_write
(
addr
,
pktlen
,
data
);
data_write
(
addr
,
pktlen
,
data
);
}
}
lan_queue_tx
::
lan_queue_tx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail_
,
size_t
idx_
,
lan_queue_tx
::
lan_queue_tx
(
lan
&
lanmgr_
,
uint32_t
&
reg_tail_
,
size_t
idx_
,
uint32_t
&
reg_ena_
,
uint32_t
&
reg_fpmbase_
,
uint32_t
&
reg_intqctl
)
uint32_t
&
reg_ena_
,
uint32_t
&
reg_fpmbase_
,
uint32_t
&
reg_intqctl
)
:
lan_queue_base
(
lanmgr_
,
"txq"
,
reg_tail_
,
idx_
,
reg_ena_
,
reg_fpmbase_
,
:
lan_queue_base
(
lanmgr_
,
"txq"
,
reg_tail_
,
idx_
,
reg_ena_
,
reg_fpmbase_
,
reg_intqctl
,
128
)
reg_intqctl
,
128
)
{
{
desc_len
=
16
;
desc_len
=
16
;
ctxs_init
();
ctxs_init
();
}
}
void
lan_queue_tx
::
reset
()
void
lan_queue_tx
::
reset
()
{
{
tso_off
=
0
;
tso_off
=
0
;
tso_len
=
0
;
tso_len
=
0
;
ready_segments
.
clear
();
ready_segments
.
clear
();
queue_base
::
reset
();
queue_base
::
reset
();
}
}
void
lan_queue_tx
::
initialize
()
void
lan_queue_tx
::
initialize
()
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" initialize()"
<<
logger
::
endl
;
log
<<
" initialize()"
<<
logger
::
endl
;
#endif
#endif
uint8_t
*
ctx_p
=
reinterpret_cast
<
uint8_t
*>
(
ctx
);
uint8_t
*
ctx_p
=
reinterpret_cast
<
uint8_t
*>
(
ctx
);
uint16_t
*
head_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
0
);
uint16_t
*
head_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
0
);
uint64_t
*
base_p
=
reinterpret_cast
<
uint64_t
*>
(
ctx_p
+
4
);
uint64_t
*
base_p
=
reinterpret_cast
<
uint64_t
*>
(
ctx_p
+
4
);
uint16_t
*
hwb_qlen_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
20
);
uint16_t
*
hwb_qlen_p
=
reinterpret_cast
<
uint16_t
*>
(
ctx_p
+
20
);
uint64_t
*
hwb_addr_p
=
reinterpret_cast
<
uint64_t
*>
(
ctx_p
+
24
);
uint64_t
*
hwb_addr_p
=
reinterpret_cast
<
uint64_t
*>
(
ctx_p
+
24
);
reg_dummy_head
=
(
*
head_p
)
&
((
1
<<
13
)
-
1
);
reg_dummy_head
=
(
*
head_p
)
&
((
1
<<
13
)
-
1
);
base
=
((
*
base_p
)
&
((
1ULL
<<
57
)
-
1
))
*
128
;
base
=
((
*
base_p
)
&
((
1ULL
<<
57
)
-
1
))
*
128
;
len
=
((
*
hwb_qlen_p
)
>>
1
)
&
((
1
<<
13
)
-
1
);
len
=
((
*
hwb_qlen_p
)
>>
1
)
&
((
1
<<
13
)
-
1
);
hwb
=
!!
(
*
hwb_qlen_p
&
(
1
<<
0
));
hwb
=
!!
(
*
hwb_qlen_p
&
(
1
<<
0
));
hwb_addr
=
*
hwb_addr_p
;
hwb_addr
=
*
hwb_addr_p
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" head="
<<
reg_dummy_head
<<
" base="
<<
base
<<
log
<<
" head="
<<
reg_dummy_head
<<
" base="
<<
base
<<
" len="
<<
len
" len="
<<
len
<<
" hwb="
<<
hwb
<<
" hwb_addr="
<<
hwb_addr
<<
<<
" hwb="
<<
hwb
<<
" hwb_addr="
<<
hwb_addr
<<
logger
::
endl
;
logger
::
endl
;
#endif
#endif
}
}
queue_base
::
desc_ctx
&
lan_queue_tx
::
desc_ctx_create
()
queue_base
::
desc_ctx
&
lan_queue_tx
::
desc_ctx_create
()
{
{
return
*
new
tx_desc_ctx
(
*
this
);
return
*
new
tx_desc_ctx
(
*
this
);
}
}
void
lan_queue_tx
::
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
void
lan_queue_tx
::
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
uint32_t
cnt
)
uint32_t
cnt
)
{
{
if
(
!
hwb
)
{
if
(
!
hwb
)
{
// if head index writeback is disabled we need to write descriptor back
// if head index writeback is disabled we need to write descriptor back
lan_queue_base
::
do_writeback
(
first_idx
,
first_pos
,
cnt
);
lan_queue_base
::
do_writeback
(
first_idx
,
first_pos
,
cnt
);
}
else
{
}
else
{
// else we just need to write the index back
// else we just need to write the index back
dma_hwb
*
dma
=
new
dma_hwb
(
*
this
,
first_pos
,
cnt
,
(
first_idx
+
cnt
)
%
len
);
dma_hwb
*
dma
=
new
dma_hwb
(
*
this
,
first_pos
,
cnt
,
dma
->
dma_addr
=
hwb_addr
;
(
first_idx
+
cnt
)
%
len
);
dma
->
dma_addr
=
hwb_addr
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" hwb="
<<
*
((
uint32_t
*
)
dma
->
data
)
<<
logger
::
endl
;
log
<<
" hwb="
<<
*
((
uint32_t
*
)
dma
->
data
)
<<
logger
::
endl
;
#endif
#endif
runner
->
issue_dma
(
*
dma
);
runner
->
issue_dma
(
*
dma
);
}
}
}
}
bool
lan_queue_tx
::
trigger_tx_packet
()
bool
lan_queue_tx
::
trigger_tx_packet
()
{
{
size_t
n
=
ready_segments
.
size
();
size_t
n
=
ready_segments
.
size
();
size_t
d_skip
=
0
,
dcnt
;
size_t
d_skip
=
0
,
dcnt
;
bool
eop
=
false
;
bool
eop
=
false
;
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
;
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
;
// abort if no queued up descriptors
// abort if no queued up descriptors
if
(
n
==
0
)
if
(
n
==
0
)
return
false
;
return
false
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
"trigger_tx_packet(n="
<<
n
<<
", firstidx="
<<
log
<<
"trigger_tx_packet(n="
<<
n
ready_segments
.
at
(
0
)
->
index
<<
")"
<<
logger
::
endl
;
<<
", firstidx="
<<
ready_segments
.
at
(
0
)
->
index
<<
")"
<<
logger
::
endl
;
log
<<
" tso_off="
<<
tso_off
<<
" tso_len="
<<
tso_len
<<
logger
::
endl
;
log
<<
" tso_off="
<<
tso_off
<<
" tso_len="
<<
tso_len
<<
logger
::
endl
;
#endif
#endif
// check if we have a context descriptor first
tx_desc_ctx
*
rd
=
ready_segments
.
at
(
0
);
uint8_t
dtype
=
(
rd
->
d
->
cmd_type_offset_bsz
&
I40E_TXD_QW1_DTYPE_MASK
)
>>
I40E_TXD_QW1_DTYPE_SHIFT
;
if
(
dtype
==
I40E_TX_DESC_DTYPE_CONTEXT
)
{
struct
i40e_tx_context_desc
*
ctxd
=
reinterpret_cast
<
struct
i40e_tx_context_desc
*>
(
rd
->
d
);
d1
=
ctxd
->
type_cmd_tso_mss
;
// check if we have a context descriptor first
uint16_t
cmd
=
tx_desc_ctx
*
rd
=
ready_segments
.
at
(
0
);
((
d1
&
I40E_TXD_CTX_QW1_CMD_MASK
)
>>
I40E_TXD_CTX_QW1_CMD_SHIFT
);
uint8_t
dtype
=
(
rd
->
d
->
cmd_type_offset_bsz
&
I40E_TXD_QW1_DTYPE_MASK
)
>>
tso
=
!!
(
cmd
&
I40E_TX_CTX_DESC_TSO
);
I40E_TXD_QW1_DTYPE_SHIFT
;
tso_mss
=
(
d1
&
I40E_TXD_CTX_QW1_MSS_MASK
)
>>
I40E_TXD_CTX_QW1_MSS_SHIFT
;
if
(
dtype
==
I40E_TX_DESC_DTYPE_CONTEXT
)
{
struct
i40e_tx_context_desc
*
ctxd
=
reinterpret_cast
<
struct
i40e_tx_context_desc
*>
(
rd
->
d
);
d1
=
ctxd
->
type_cmd_tso_mss
;
uint16_t
cmd
=
((
d1
&
I40E_TXD_CTX_QW1_CMD_MASK
)
>>
I40E_TXD_CTX_QW1_CMD_SHIFT
);
tso
=
!!
(
cmd
&
I40E_TX_CTX_DESC_TSO
);
tso_mss
=
(
d1
&
I40E_TXD_CTX_QW1_MSS_MASK
)
>>
I40E_TXD_CTX_QW1_MSS_SHIFT
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" tso="
<<
tso
<<
" mss="
<<
tso_mss
<<
logger
::
endl
;
log
<<
" tso="
<<
tso
<<
" mss="
<<
tso_mss
<<
logger
::
endl
;
#endif
#endif
d_skip
=
1
;
d_skip
=
1
;
}
}
// find EOP descriptor
// find EOP descriptor
for
(
dcnt
=
d_skip
;
dcnt
<
n
&&
!
eop
;
dcnt
++
)
{
for
(
dcnt
=
d_skip
;
dcnt
<
n
&&
!
eop
;
dcnt
++
)
{
tx_desc_ctx
*
rd
=
ready_segments
.
at
(
dcnt
);
tx_desc_ctx
*
rd
=
ready_segments
.
at
(
dcnt
);
d1
=
rd
->
d
->
cmd_type_offset_bsz
;
d1
=
rd
->
d
->
cmd_type_offset_bsz
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" data fetched didx="
<<
rd
->
index
<<
" d1="
<<
log
<<
" data fetched didx="
<<
rd
->
index
<<
" d1="
<<
d1
<<
logger
::
endl
;
d1
<<
logger
::
endl
;
#endif
#endif
dtype
=
(
d1
&
I40E_TXD_QW1_DTYPE_MASK
)
>>
I40E_TXD_QW1_DTYPE_SHIFT
;
dtype
=
(
d1
&
I40E_TXD_QW1_DTYPE_MASK
)
>>
I40E_TXD_QW1_DTYPE_SHIFT
;
if
(
dtype
!=
I40E_TX_DESC_DTYPE_DATA
)
{
if
(
dtype
!=
I40E_TX_DESC_DTYPE_DATA
)
{
log
<<
"trigger tx desc is not a data descriptor idx="
<<
rd
->
index
log
<<
"trigger tx desc is not a data descriptor idx="
<<
rd
->
index
<<
" d1="
<<
d1
<<
logger
::
endl
;
<<
" d1="
<<
d1
<<
logger
::
endl
;
abort
();
abort
();
}
}
uint16_t
cmd
=
(
d1
&
I40E_TXD_QW1_CMD_MASK
)
>>
I40E_TXD_QW1_CMD_SHIFT
;
uint16_t
cmd
=
(
d1
&
I40E_TXD_QW1_CMD_MASK
)
>>
I40E_TXD_QW1_CMD_SHIFT
;
eop
=
(
cmd
&
I40E_TX_DESC_CMD_EOP
);
eop
=
(
cmd
&
I40E_TX_DESC_CMD_EOP
);
iipt
=
cmd
&
(
I40E_TX_DESC_CMD_IIPT_MASK
);
iipt
=
cmd
&
(
I40E_TX_DESC_CMD_IIPT_MASK
);
l4t
=
(
cmd
&
I40E_TX_DESC_CMD_L4T_EOFT_MASK
);
l4t
=
(
cmd
&
I40E_TX_DESC_CMD_L4T_EOFT_MASK
);
if
(
eop
)
{
if
(
eop
)
{
uint32_t
off
=
(
d1
&
I40E_TXD_QW1_OFFSET_MASK
)
>>
uint32_t
off
=
I40E_TXD_QW1_OFFSET_SHIFT
;
(
d1
&
I40E_TXD_QW1_OFFSET_MASK
)
>>
I40E_TXD_QW1_OFFSET_SHIFT
;
maclen
=
((
off
&
I40E_TXD_QW1_MACLEN_MASK
)
>>
maclen
=
((
off
&
I40E_TXD_QW1_MACLEN_MASK
)
>>
I40E_TX_DESC_LENGTH_MACLEN_SHIFT
)
*
2
;
I40E_TX_DESC_LENGTH_MACLEN_SHIFT
)
*
iplen
=
((
off
&
I40E_TXD_QW1_IPLEN_MASK
)
>>
2
;
I40E_TX_DESC_LENGTH_IPLEN_SHIFT
)
*
4
;
iplen
=
l4len
=
((
off
&
I40E_TXD_QW1_L4LEN_MASK
)
>>
((
off
&
I40E_TXD_QW1_IPLEN_MASK
)
>>
I40E_TX_DESC_LENGTH_IPLEN_SHIFT
)
*
I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT
)
*
4
;
4
;
}
l4len
=
((
off
&
I40E_TXD_QW1_L4LEN_MASK
)
>>
I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT
)
*
pkt_len
=
(
d1
&
I40E_TXD_QW1_TX_BUF_SZ_MASK
)
>>
4
;
I40E_TXD_QW1_TX_BUF_SZ_SHIFT
;
}
total_len
+=
pkt_len
;
pkt_len
=
(
d1
&
I40E_TXD_QW1_TX_BUF_SZ_MASK
)
>>
I40E_TXD_QW1_TX_BUF_SZ_SHIFT
;
total_len
+=
pkt_len
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" eop="
<<
eop
<<
" len="
<<
pkt_len
<<
logger
::
endl
;
log
<<
" eop="
<<
eop
<<
" len="
<<
pkt_len
<<
logger
::
endl
;
#endif
#endif
}
}
// Unit not completely fetched yet
// Unit not completely fetched yet
if
(
!
eop
)
if
(
!
eop
)
return
false
;
return
false
;
if
(
tso
)
{
if
(
tso
)
{
if
(
tso_off
==
0
)
if
(
tso_off
==
0
)
data_limit
=
maclen
+
iplen
+
l4len
+
tso_mss
;
data_limit
=
maclen
+
iplen
+
l4len
+
tso_mss
;
else
else
data_limit
=
tso_off
+
tso_mss
;
data_limit
=
tso_off
+
tso_mss
;
if
(
data_limit
>
total_len
)
{
if
(
data_limit
>
total_len
)
{
data_limit
=
total_len
;
data_limit
=
total_len
;
}
}
}
else
{
}
else
{
if
(
total_len
>
MTU
)
{
if
(
total_len
>
MTU
)
{
log
<<
" packet is longer ("
<<
total_len
<<
") than MTU ("
<<
log
<<
" packet is longer ("
<<
total_len
<<
") than MTU ("
<<
MTU
MTU
<<
")"
<<
logger
::
endl
;
<<
")"
<<
logger
::
endl
;
abort
();
abort
();
}
data_limit
=
total_len
;
}
}
data_limit
=
total_len
;
}
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" iipt="
<<
iipt
<<
" l4t="
<<
l4t
<<
log
<<
" iipt="
<<
iipt
<<
" l4t="
<<
l4t
<<
" maclen="
<<
maclen
" maclen="
<<
maclen
<<
" iplen="
<<
iplen
<<
" l4len="
<<
l4len
<<
<<
" iplen="
<<
iplen
<<
" l4len="
<<
l4len
<<
" total_len="
<<
total_len
" total_len="
<<
total_len
<<
" data_limit="
<<
data_limit
<<
<<
" data_limit="
<<
data_limit
<<
logger
::
endl
;
logger
::
endl
;
#else
#else
(
void
)
iipt
;
(
void
)
iipt
;
#endif
#endif
// copy data for this segment
uint32_t
off
=
0
;
for
(
dcnt
=
d_skip
;
dcnt
<
n
&&
off
<
data_limit
;
dcnt
++
)
{
tx_desc_ctx
*
rd
=
ready_segments
.
at
(
dcnt
);
d1
=
rd
->
d
->
cmd_type_offset_bsz
;
uint16_t
pkt_len
=
(
d1
&
I40E_TXD_QW1_TX_BUF_SZ_MASK
)
>>
I40E_TXD_QW1_TX_BUF_SZ_SHIFT
;
// copy data for this segment
if
(
off
<=
tso_off
&&
off
+
pkt_len
>
tso_off
)
{
uint32_t
off
=
0
;
uint32_t
start
=
tso_off
;
for
(
dcnt
=
d_skip
;
dcnt
<
n
&&
off
<
data_limit
;
dcnt
++
)
{
uint32_t
end
=
off
+
pkt_len
;
tx_desc_ctx
*
rd
=
ready_segments
.
at
(
dcnt
);
if
(
end
>
data_limit
)
d1
=
rd
->
d
->
cmd_type_offset_bsz
;
end
=
data_limit
;
uint16_t
pkt_len
=
(
d1
&
I40E_TXD_QW1_TX_BUF_SZ_MASK
)
>>
I40E_TXD_QW1_TX_BUF_SZ_SHIFT
;
if
(
off
<=
tso_off
&&
off
+
pkt_len
>
tso_off
)
{
uint32_t
start
=
tso_off
;
uint32_t
end
=
off
+
pkt_len
;
if
(
end
>
data_limit
)
end
=
data_limit
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" copying data from off="
<<
off
<<
" idx="
<<
rd
->
index
<<
log
<<
" copying data from off="
<<
off
<<
" idx="
<<
rd
->
index
" start="
<<
start
<<
" end="
<<
end
<<
" tso_len="
<<
tso_len
<<
<<
" start="
<<
start
<<
" end="
<<
end
<<
" tso_len="
<<
tso_len
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
memcpy
(
pktbuf
+
tso_len
,
(
uint8_t
*
)
rd
->
data
+
(
start
-
off
),
memcpy
(
pktbuf
+
tso_len
,
(
uint8_t
*
)
rd
->
data
+
(
start
-
off
),
end
-
start
);
end
-
start
);
tso_off
=
end
;
tso_off
=
end
;
tso_len
+=
end
-
start
;
tso_len
+=
end
-
start
;
}
off
+=
pkt_len
;
}
}
assert
(
tso_len
<=
MTU
);
off
+=
pkt_len
;
}
assert
(
tso_len
<=
MTU
);
if
(
!
tso
)
{
if
(
!
tso
)
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" normal non-tso packet"
<<
logger
::
endl
;
log
<<
" normal non-tso packet"
<<
logger
::
endl
;
#endif
#endif
if
(
l4t
==
I40E_TX_DESC_CMD_L4T_EOFT_TCP
)
{
if
(
l4t
==
I40E_TX_DESC_CMD_L4T_EOFT_TCP
)
{
uint16_t
tcp_off
=
maclen
+
iplen
;
uint16_t
tcp_off
=
maclen
+
iplen
;
xsum_tcp
(
pktbuf
+
tcp_off
,
tso_len
-
tcp_off
);
xsum_tcp
(
pktbuf
+
tcp_off
,
tso_len
-
tcp_off
);
}
}
runner
->
eth_send
(
pktbuf
,
tso_len
);
runner
->
eth_send
(
pktbuf
,
tso_len
);
}
else
{
}
else
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" tso packet off="
<<
tso_off
<<
" len="
<<
tso_len
<<
log
<<
" tso packet off="
<<
tso_off
<<
" len="
<<
tso_len
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
// TSO gets hairier
// TSO gets hairier
uint16_t
hdrlen
=
maclen
+
iplen
+
l4len
;
uint16_t
hdrlen
=
maclen
+
iplen
+
l4len
;
// calculate payload size
// calculate payload size
tso_paylen
=
tso_len
-
hdrlen
;
tso_paylen
=
tso_len
-
hdrlen
;
if
(
tso_paylen
>
tso_mss
)
if
(
tso_paylen
>
tso_mss
)
tso_paylen
=
tso_mss
;
tso_paylen
=
tso_mss
;
xsum_tcpip_tso
(
pktbuf
+
maclen
,
iplen
,
l4len
,
tso_paylen
);
xsum_tcpip_tso
(
pktbuf
+
maclen
,
iplen
,
l4len
,
tso_paylen
);
runner
->
eth_send
(
pktbuf
,
tso_len
);
runner
->
eth_send
(
pktbuf
,
tso_len
);
tso_postupdate_header
(
pktbuf
+
maclen
,
iplen
,
l4len
,
tso_paylen
);
tso_postupdate_header
(
pktbuf
+
maclen
,
iplen
,
l4len
,
tso_paylen
);
// not done yet with this TSO unit
// not done yet with this TSO unit
if
(
tso
&&
tso_off
<
total_len
)
{
if
(
tso
&&
tso_off
<
total_len
)
{
tso_len
=
hdrlen
;
tso_len
=
hdrlen
;
return
true
;
return
true
;
}
}
}
}
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
log
<<
" unit done"
<<
logger
::
endl
;
log
<<
" unit done"
<<
logger
::
endl
;
#endif
#endif
while
(
dcnt
--
>
0
)
{
while
(
dcnt
--
>
0
)
{
ready_segments
.
front
()
->
processed
();
ready_segments
.
front
()
->
processed
();
ready_segments
.
pop_front
();
ready_segments
.
pop_front
();
}
}
tso_len
=
0
;
tso_len
=
0
;
tso_off
=
0
;
tso_off
=
0
;
return
true
;
return
true
;
}
}
void
lan_queue_tx
::
trigger_tx
()
void
lan_queue_tx
::
trigger_tx
()
{
{
while
(
trigger_tx_packet
())
{
while
(
trigger_tx_packet
())
{
}
}
}
}
lan_queue_tx
::
tx_desc_ctx
::
tx_desc_ctx
(
lan_queue_tx
&
queue_
)
lan_queue_tx
::
tx_desc_ctx
::
tx_desc_ctx
(
lan_queue_tx
&
queue_
)
:
desc_ctx
(
queue_
),
tq
(
queue_
)
:
desc_ctx
(
queue_
),
tq
(
queue_
)
{
{
d
=
reinterpret_cast
<
struct
i40e_tx_desc
*>
(
desc
);
d
=
reinterpret_cast
<
struct
i40e_tx_desc
*>
(
desc
);
}
}
void
lan_queue_tx
::
tx_desc_ctx
::
prepare
()
void
lan_queue_tx
::
tx_desc_ctx
::
prepare
()
{
{
uint64_t
d1
=
d
->
cmd_type_offset_bsz
;
uint64_t
d1
=
d
->
cmd_type_offset_bsz
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
queue
.
log
<<
" desc fetched didx="
<<
index
<<
" d1="
<<
queue
.
log
<<
" desc fetched didx="
<<
index
<<
" d1="
<<
d1
<<
logger
::
endl
;
d1
<<
logger
::
endl
;
#endif
#endif
uint8_t
dtype
=
(
d1
&
I40E_TXD_QW1_DTYPE_MASK
)
>>
I40E_TXD_QW1_DTYPE_SHIFT
;
uint8_t
dtype
=
(
d1
&
I40E_TXD_QW1_DTYPE_MASK
)
>>
I40E_TXD_QW1_DTYPE_SHIFT
;
if
(
dtype
==
I40E_TX_DESC_DTYPE_DATA
)
{
if
(
dtype
==
I40E_TX_DESC_DTYPE_DATA
)
{
uint16_t
len
=
(
d1
&
I40E_TXD_QW1_TX_BUF_SZ_MASK
)
>>
uint16_t
len
=
I40E_TXD_QW1_TX_BUF_SZ_SHIFT
;
(
d1
&
I40E_TXD_QW1_TX_BUF_SZ_MASK
)
>>
I40E_TXD_QW1_TX_BUF_SZ_SHIFT
;
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
queue
.
log
<<
" bufaddr="
<<
d
->
buffer_addr
<<
queue
.
log
<<
" bufaddr="
<<
d
->
buffer_addr
<<
" len="
<<
len
" len="
<<
len
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
data_fetch
(
d
->
buffer_addr
,
len
);
data_fetch
(
d
->
buffer_addr
,
len
);
}
else
if
(
dtype
==
I40E_TX_DESC_DTYPE_CONTEXT
)
{
}
else
if
(
dtype
==
I40E_TX_DESC_DTYPE_CONTEXT
)
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
struct
i40e_tx_context_desc
*
ctxd
=
struct
i40e_tx_context_desc
*
ctxd
=
reinterpret_cast
<
struct
i40e_tx_context_desc
*>
(
d
);
reinterpret_cast
<
struct
i40e_tx_context_desc
*>
(
d
);
queue
.
log
<<
" context descriptor: tp="
<<
ctxd
->
tunneling_params
<<
queue
.
log
<<
" context descriptor: tp="
<<
ctxd
->
tunneling_params
" l2t="
<<
ctxd
->
l2tag2
<<
" tctm="
<<
ctxd
->
type_cmd_tso_mss
<<
<<
" l2t="
<<
ctxd
->
l2tag2
<<
" tctm="
<<
ctxd
->
type_cmd_tso_mss
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
prepared
();
prepared
();
}
else
{
}
else
{
queue
.
log
<<
"txq: only support context & data descriptors"
<<
queue
.
log
<<
"txq: only support context & data descriptors"
<<
logger
::
endl
;
logger
::
endl
;
abort
();
abort
();
}
}
}
}
void
lan_queue_tx
::
tx_desc_ctx
::
process
()
void
lan_queue_tx
::
tx_desc_ctx
::
process
()
{
{
tq
.
ready_segments
.
push_back
(
this
);
tq
.
ready_segments
.
push_back
(
this
);
tq
.
trigger_tx
();
tq
.
trigger_tx
();
}
}
void
lan_queue_tx
::
tx_desc_ctx
::
processed
()
void
lan_queue_tx
::
tx_desc_ctx
::
processed
()
{
{
d
->
cmd_type_offset_bsz
=
I40E_TX_DESC_DTYPE_DESC_DONE
d
->
cmd_type_offset_bsz
=
I40E_TX_DESC_DTYPE_DESC_DONE
<<
<<
I40E_TXD_QW1_DTYPE_SHIFT
;
I40E_TXD_QW1_DTYPE_SHIFT
;
desc_ctx
::
processed
();
desc_ctx
::
processed
();
}
}
lan_queue_tx
::
dma_hwb
::
dma_hwb
(
lan_queue_tx
&
queue_
,
uint32_t
pos_
,
lan_queue_tx
::
dma_hwb
::
dma_hwb
(
lan_queue_tx
&
queue_
,
uint32_t
pos_
,
uint32_t
cnt_
,
uint32_t
nh_
)
uint32_t
cnt_
,
uint32_t
nh_
)
:
queue
(
queue_
),
pos
(
pos_
),
cnt
(
cnt_
),
next_head
(
nh_
)
:
queue
(
queue_
),
pos
(
pos_
),
cnt
(
cnt_
),
next_head
(
nh_
)
{
{
data
=
&
next_head
;
data
=
&
next_head
;
len
=
4
;
len
=
4
;
write
=
true
;
write
=
true
;
}
}
lan_queue_tx
::
dma_hwb
::~
dma_hwb
()
lan_queue_tx
::
dma_hwb
::~
dma_hwb
()
{
{
}
}
void
lan_queue_tx
::
dma_hwb
::
done
()
void
lan_queue_tx
::
dma_hwb
::
done
()
{
{
#ifdef DEBUG_LAN
#ifdef DEBUG_LAN
queue
.
log
<<
" tx head written back"
<<
logger
::
endl
;
queue
.
log
<<
" tx head written back"
<<
logger
::
endl
;
#endif
#endif
queue
.
writeback_done
(
pos
,
cnt
);
queue
.
writeback_done
(
pos
,
cnt
);
queue
.
trigger
();
queue
.
trigger
();
delete
this
;
delete
this
;
}
}
sims/nic/i40e_bm/i40e_queues.cc
View file @
d4666c97
...
@@ -24,454 +24,426 @@
...
@@ -24,454 +24,426 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <algorithm>
#include <cassert>
#include <cassert>
#include <iostream>
#include <iostream>
#include <algorithm>
#include "sims/nic/i40e_bm/i40e_bm.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
#include "sims/nic/i40e_bm/i40e_bm.h"
using
namespace
i40e
;
using
namespace
i40e
;
extern
nicbm
::
Runner
*
runner
;
extern
nicbm
::
Runner
*
runner
;
queue_base
::
queue_base
(
const
std
::
string
&
qname_
,
uint32_t
&
reg_head_
,
queue_base
::
queue_base
(
const
std
::
string
&
qname_
,
uint32_t
&
reg_head_
,
uint32_t
&
reg_tail_
)
uint32_t
&
reg_tail_
)
:
qname
(
qname_
),
log
(
qname_
),
active_first_pos
(
0
),
active_first_idx
(
0
),
:
qname
(
qname_
),
active_cnt
(
0
),
base
(
0
),
len
(
0
),
reg_head
(
reg_head_
),
reg_tail
(
reg_tail_
),
log
(
qname_
),
enabled
(
false
),
desc_len
(
0
)
active_first_pos
(
0
),
{
active_first_idx
(
0
),
for
(
size_t
i
=
0
;
i
<
MAX_ACTIVE_DESCS
;
i
++
)
{
active_cnt
(
0
),
desc_ctxs
[
i
]
=
nullptr
;
base
(
0
),
}
len
(
0
),
}
reg_head
(
reg_head_
),
reg_tail
(
reg_tail_
),
void
queue_base
::
ctxs_init
()
enabled
(
false
),
{
desc_len
(
0
)
{
for
(
size_t
i
=
0
;
i
<
MAX_ACTIVE_DESCS
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
MAX_ACTIVE_DESCS
;
i
++
)
{
desc_ctxs
[
i
]
=
&
desc_ctx_create
();
desc_ctxs
[
i
]
=
nullptr
;
}
}
}
}
void
queue_base
::
trigger_fetch
()
void
queue_base
::
ctxs_init
()
{
{
for
(
size_t
i
=
0
;
i
<
MAX_ACTIVE_DESCS
;
i
++
)
{
if
(
!
enabled
)
desc_ctxs
[
i
]
=
&
desc_ctx_create
();
return
;
}
}
// calculate how many we can fetch
uint32_t
next_idx
=
(
active_first_idx
+
active_cnt
)
%
len
;
void
queue_base
::
trigger_fetch
()
{
uint32_t
desc_avail
=
(
reg_tail
-
next_idx
)
%
len
;
if
(
!
enabled
)
uint32_t
fetch_cnt
=
desc_avail
;
return
;
fetch_cnt
=
std
::
min
(
fetch_cnt
,
MAX_ACTIVE_DESCS
-
active_cnt
);
if
(
max_active_capacity
()
<=
active_cnt
)
// calculate how many we can fetch
fetch_cnt
=
std
::
min
(
fetch_cnt
,
max_active_capacity
()
-
active_cnt
);
uint32_t
next_idx
=
(
active_first_idx
+
active_cnt
)
%
len
;
fetch_cnt
=
std
::
min
(
fetch_cnt
,
max_fetch_capacity
());
uint32_t
desc_avail
=
(
reg_tail
-
next_idx
)
%
len
;
uint32_t
fetch_cnt
=
desc_avail
;
if
(
next_idx
+
fetch_cnt
>
len
)
fetch_cnt
=
std
::
min
(
fetch_cnt
,
MAX_ACTIVE_DESCS
-
active_cnt
);
fetch_cnt
=
len
-
next_idx
;
if
(
max_active_capacity
()
<=
active_cnt
)
fetch_cnt
=
std
::
min
(
fetch_cnt
,
max_active_capacity
()
-
active_cnt
);
fetch_cnt
=
std
::
min
(
fetch_cnt
,
max_fetch_capacity
());
if
(
next_idx
+
fetch_cnt
>
len
)
fetch_cnt
=
len
-
next_idx
;
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
"fetching avail="
<<
desc_avail
<<
" cnt="
<<
fetch_cnt
<<
" idx="
<<
log
<<
"fetching avail="
<<
desc_avail
<<
" cnt="
<<
fetch_cnt
next_idx
<<
logger
::
endl
;
<<
" idx="
<<
next_idx
<<
logger
::
endl
;
#endif
#endif
// abort if nothign to fetch
// abort if nothign to fetch
if
(
fetch_cnt
==
0
)
if
(
fetch_cnt
==
0
)
return
;
return
;
// mark descriptor contexts as fetching
// mark descriptor contexts as fetching
uint32_t
first_pos
=
(
active_first_pos
+
active_cnt
)
%
MAX_ACTIVE_DESCS
;
uint32_t
first_pos
=
(
active_first_pos
+
active_cnt
)
%
MAX_ACTIVE_DESCS
;
for
(
uint32_t
i
=
0
;
i
<
fetch_cnt
;
i
++
)
{
for
(
uint32_t
i
=
0
;
i
<
fetch_cnt
;
i
++
)
{
desc_ctx
&
ctx
=
*
desc_ctxs
[(
first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
desc_ctx
&
ctx
=
*
desc_ctxs
[(
first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
assert
(
ctx
.
state
==
desc_ctx
::
DESC_EMPTY
);
assert
(
ctx
.
state
==
desc_ctx
::
DESC_EMPTY
);
ctx
.
state
=
desc_ctx
::
DESC_FETCHING
;
ctx
.
state
=
desc_ctx
::
DESC_FETCHING
;
ctx
.
index
=
(
next_idx
+
i
)
%
len
;
ctx
.
index
=
(
next_idx
+
i
)
%
len
;
}
}
active_cnt
+=
fetch_cnt
;
active_cnt
+=
fetch_cnt
;
// prepare & issue dma
// prepare & issue dma
dma_fetch
*
dma
=
new
dma_fetch
(
*
this
,
desc_len
*
fetch_cnt
);
dma_fetch
*
dma
=
new
dma_fetch
(
*
this
,
desc_len
*
fetch_cnt
);
dma
->
write
=
false
;
dma
->
write
=
false
;
dma
->
dma_addr
=
base
+
next_idx
*
desc_len
;
dma
->
dma_addr
=
base
+
next_idx
*
desc_len
;
dma
->
pos
=
first_pos
;
dma
->
pos
=
first_pos
;
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
" dma = "
<<
dma
<<
logger
::
endl
;
log
<<
" dma = "
<<
dma
<<
logger
::
endl
;
#endif
#endif
runner
->
issue_dma
(
*
dma
);
runner
->
issue_dma
(
*
dma
);
}
}
void
queue_base
::
trigger_process
()
void
queue_base
::
trigger_process
()
{
{
if
(
!
enabled
)
if
(
!
enabled
)
return
;
return
;
// first skip over descriptors that are already done processing
// first skip over descriptors that are already done processing
uint32_t
i
;
uint32_t
i
;
for
(
i
=
0
;
i
<
active_cnt
;
i
++
)
for
(
i
=
0
;
i
<
active_cnt
;
i
++
)
if
(
desc_ctxs
[(
active_first_pos
+
i
)
%
MAX_ACTIVE_DESCS
]
->
state
<=
if
(
desc_ctxs
[(
active_first_pos
+
i
)
%
MAX_ACTIVE_DESCS
]
->
state
desc_ctx
::
DESC_PREPARED
)
<=
desc_ctx
::
DESC_PREPARED
)
break
;
break
;
// then run all prepared contexts
// then run all prepared contexts
uint32_t
j
;
uint32_t
j
;
for
(
j
=
0
;
i
+
j
<
active_cnt
;
j
++
)
{
for
(
j
=
0
;
i
+
j
<
active_cnt
;
j
++
)
{
desc_ctx
&
ctx
=
*
desc_ctxs
[(
active_first_pos
+
i
+
j
)
%
MAX_ACTIVE_DESCS
];
desc_ctx
&
ctx
=
*
desc_ctxs
[(
active_first_pos
+
i
+
j
)
if
(
ctx
.
state
!=
desc_ctx
::
DESC_PREPARED
)
%
MAX_ACTIVE_DESCS
];
break
;
if
(
ctx
.
state
!=
desc_ctx
::
DESC_PREPARED
)
break
;
ctx
.
state
=
desc_ctx
::
DESC_PROCESSING
;
ctx
.
state
=
desc_ctx
::
DESC_PROCESSING
;
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
"processing desc "
<<
ctx
.
index
<<
logger
::
endl
;
log
<<
"processing desc "
<<
ctx
.
index
<<
logger
::
endl
;
#endif
#endif
ctx
.
process
();
ctx
.
process
();
}
}
}
}
void
queue_base
::
trigger_writeback
()
void
queue_base
::
trigger_writeback
()
{
{
if
(
!
enabled
)
if
(
!
enabled
)
return
;
return
;
// from first pos count number of processed descriptors
// from first pos count number of processed descriptors
uint32_t
avail
;
uint32_t
avail
;
for
(
avail
=
0
;
avail
<
active_cnt
;
avail
++
)
for
(
avail
=
0
;
avail
<
active_cnt
;
avail
++
)
if
(
desc_ctxs
[(
active_first_pos
+
avail
)
%
MAX_ACTIVE_DESCS
]
->
state
if
(
desc_ctxs
[(
active_first_pos
+
avail
)
%
MAX_ACTIVE_DESCS
]
->
state
!=
!=
desc_ctx
::
DESC_PROCESSED
)
desc_ctx
::
DESC_PROCESSED
)
break
;
break
;
uint32_t
cnt
=
std
::
min
(
avail
,
max_writeback_capacity
());
uint32_t
cnt
=
std
::
min
(
avail
,
max_writeback_capacity
());
if
(
active_first_idx
+
cnt
>
len
)
if
(
active_first_idx
+
cnt
>
len
)
cnt
=
len
-
active_first_idx
;
cnt
=
len
-
active_first_idx
;
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
"writing back avail="
<<
avail
<<
" cnt="
<<
cnt
<<
log
<<
"writing back avail="
<<
avail
<<
" cnt="
<<
cnt
" idx="
<<
active_first_idx
<<
logger
::
endl
;
<<
" idx="
<<
active_first_idx
<<
logger
::
endl
;
#endif
#endif
if
(
cnt
==
0
)
if
(
cnt
==
0
)
return
;
return
;
// mark these descriptors as writing back
// mark these descriptors as writing back
for
(
uint32_t
i
=
0
;
i
<
cnt
;
i
++
)
{
for
(
uint32_t
i
=
0
;
i
<
cnt
;
i
++
)
{
desc_ctx
&
ctx
=
*
desc_ctxs
[(
active_first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
desc_ctx
&
ctx
=
*
desc_ctxs
[(
active_first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
ctx
.
state
=
desc_ctx
::
DESC_WRITING_BACK
;
ctx
.
state
=
desc_ctx
::
DESC_WRITING_BACK
;
}
}
do_writeback
(
active_first_idx
,
active_first_pos
,
cnt
);
do_writeback
(
active_first_idx
,
active_first_pos
,
cnt
);
}
}
void
queue_base
::
trigger
()
void
queue_base
::
trigger
()
{
{
trigger_fetch
();
trigger_fetch
();
trigger_process
();
trigger_process
();
trigger_writeback
();
trigger_writeback
();
}
}
void
queue_base
::
reset
()
void
queue_base
::
reset
()
{
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
"reset"
<<
logger
::
endl
;
log
<<
"reset"
<<
logger
::
endl
;
#endif
#endif
enabled
=
false
;
enabled
=
false
;
active_first_pos
=
0
;
active_first_pos
=
0
;
active_first_idx
=
0
;
active_first_idx
=
0
;
active_cnt
=
0
;
active_cnt
=
0
;
for
(
size_t
i
=
0
;
i
<
MAX_ACTIVE_DESCS
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
MAX_ACTIVE_DESCS
;
i
++
)
{
desc_ctxs
[
i
]
->
state
=
desc_ctx
::
DESC_EMPTY
;
desc_ctxs
[
i
]
->
state
=
desc_ctx
::
DESC_EMPTY
;
}
}
}
}
void
queue_base
::
reg_updated
()
void
queue_base
::
reg_updated
()
{
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
"reg_updated: tail="
<<
reg_tail
<<
" enabled="
<<
(
int
)
enabled
<<
log
<<
"reg_updated: tail="
<<
reg_tail
<<
" enabled="
<<
(
int
)
enabled
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
if
(
!
enabled
)
if
(
!
enabled
)
return
;
return
;
trigger
();
trigger
();
}
}
bool
queue_base
::
is_enabled
()
bool
queue_base
::
is_enabled
()
{
{
return
enabled
;
return
enabled
;
}
}
uint32_t
queue_base
::
max_fetch_capacity
()
uint32_t
queue_base
::
max_fetch_capacity
()
{
{
return
UINT32_MAX
;
return
UINT32_MAX
;
}
}
uint32_t
queue_base
::
max_active_capacity
()
uint32_t
queue_base
::
max_active_capacity
()
{
{
return
UINT32_MAX
;
return
UINT32_MAX
;
}
}
uint32_t
queue_base
::
max_writeback_capacity
()
uint32_t
queue_base
::
max_writeback_capacity
()
{
{
return
UINT32_MAX
;
return
UINT32_MAX
;
}
}
void
queue_base
::
interrupt
()
void
queue_base
::
interrupt
()
{
{
}
}
void
queue_base
::
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
void
queue_base
::
do_writeback
(
uint32_t
first_idx
,
uint32_t
first_pos
,
uint32_t
cnt
)
uint32_t
cnt
)
{
{
dma_wb
*
dma
=
new
dma_wb
(
*
this
,
desc_len
*
cnt
);
dma_wb
*
dma
=
new
dma_wb
(
*
this
,
desc_len
*
cnt
);
dma
->
write
=
true
;
dma
->
write
=
true
;
dma
->
dma_addr
=
base
+
first_idx
*
desc_len
;
dma
->
dma_addr
=
base
+
first_idx
*
desc_len
;
dma
->
pos
=
first_pos
;
dma
->
pos
=
first_pos
;
uint8_t
*
buf
=
reinterpret_cast
<
uint8_t
*>
(
dma
->
data
);
uint8_t
*
buf
=
reinterpret_cast
<
uint8_t
*>
(
dma
->
data
);
for
(
uint32_t
i
=
0
;
i
<
cnt
;
i
++
)
{
for
(
uint32_t
i
=
0
;
i
<
cnt
;
i
++
)
{
desc_ctx
&
ctx
=
*
desc_ctxs
[(
first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
desc_ctx
&
ctx
=
*
desc_ctxs
[(
first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
assert
(
ctx
.
state
==
desc_ctx
::
DESC_WRITING_BACK
);
assert
(
ctx
.
state
==
desc_ctx
::
DESC_WRITING_BACK
);
memcpy
(
buf
+
i
*
desc_len
,
ctx
.
desc
,
desc_len
);
memcpy
(
buf
+
i
*
desc_len
,
ctx
.
desc
,
desc_len
);
}
}
runner
->
issue_dma
(
*
dma
);
runner
->
issue_dma
(
*
dma
);
}
}
void
queue_base
::
writeback_done
(
uint32_t
first_pos
,
uint32_t
cnt
)
{
void
queue_base
::
writeback_done
(
uint32_t
first_pos
,
uint32_t
cnt
)
if
(
!
enabled
)
{
return
;
if
(
!
enabled
)
return
;
// first mark descriptors as written back
for
(
uint32_t
i
=
0
;
i
<
cnt
;
i
++
)
{
// first mark descriptors as written back
desc_ctx
&
ctx
=
*
desc_ctxs
[(
first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
for
(
uint32_t
i
=
0
;
i
<
cnt
;
i
++
)
{
assert
(
ctx
.
state
==
desc_ctx
::
DESC_WRITING_BACK
);
desc_ctx
&
ctx
=
*
desc_ctxs
[(
first_pos
+
i
)
%
MAX_ACTIVE_DESCS
];
ctx
.
state
=
desc_ctx
::
DESC_WRITTEN_BACK
;
assert
(
ctx
.
state
==
desc_ctx
::
DESC_WRITING_BACK
);
}
ctx
.
state
=
desc_ctx
::
DESC_WRITTEN_BACK
;
}
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
"written back afi="
<<
active_first_idx
<<
" afp="
<<
log
<<
"written back afi="
<<
active_first_idx
<<
" afp="
<<
active_first_pos
active_first_pos
<<
" acnt="
<<
active_cnt
<<
" pos="
<<
<<
" acnt="
<<
active_cnt
<<
" pos="
<<
first_pos
<<
" cnt="
<<
cnt
first_pos
<<
" cnt="
<<
cnt
<<
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
// then start at the beginning and check how many are written back and then
// then start at the beginning and check how many are written back and then
// free those
// free those
uint32_t
bump_cnt
=
0
;
uint32_t
bump_cnt
=
0
;
for
(
bump_cnt
=
0
;
bump_cnt
<
active_cnt
;
bump_cnt
++
)
{
for
(
bump_cnt
=
0
;
bump_cnt
<
active_cnt
;
bump_cnt
++
)
{
desc_ctx
&
ctx
=
*
desc_ctxs
[(
active_first_pos
+
bump_cnt
)
%
desc_ctx
&
ctx
=
MAX_ACTIVE_DESCS
];
*
desc_ctxs
[(
active_first_pos
+
bump_cnt
)
%
MAX_ACTIVE_DESCS
];
if
(
ctx
.
state
!=
desc_ctx
::
DESC_WRITTEN_BACK
)
if
(
ctx
.
state
!=
desc_ctx
::
DESC_WRITTEN_BACK
)
break
;
break
;
ctx
.
state
=
desc_ctx
::
DESC_EMPTY
;
ctx
.
state
=
desc_ctx
::
DESC_EMPTY
;
}
}
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
log
<<
" bump_cnt="
<<
bump_cnt
<<
logger
::
endl
;
log
<<
" bump_cnt="
<<
bump_cnt
<<
logger
::
endl
;
#endif
#endif
active_first_pos
=
(
active_first_pos
+
bump_cnt
)
%
MAX_ACTIVE_DESCS
;
active_first_pos
=
(
active_first_pos
+
bump_cnt
)
%
MAX_ACTIVE_DESCS
;
active_first_idx
=
(
active_first_idx
+
bump_cnt
)
%
len
;
active_first_idx
=
(
active_first_idx
+
bump_cnt
)
%
len
;
active_cnt
-=
bump_cnt
;
active_cnt
-=
bump_cnt
;
reg_head
=
active_first_idx
;
reg_head
=
active_first_idx
;
interrupt
();
interrupt
();
}
}
queue_base
::
desc_ctx
::
desc_ctx
(
queue_base
&
queue_
)
queue_base
::
desc_ctx
::
desc_ctx
(
queue_base
&
queue_
)
:
queue
(
queue_
),
state
(
DESC_EMPTY
),
index
(
0
),
data
(
nullptr
),
data_len
(
0
),
:
queue
(
queue_
),
data_capacity
(
0
)
state
(
DESC_EMPTY
),
{
index
(
0
),
desc
=
new
uint8_t
[
queue_
.
desc_len
];
data
(
nullptr
),
data_len
(
0
),
data_capacity
(
0
)
{
desc
=
new
uint8_t
[
queue_
.
desc_len
];
}
}
queue_base
::
desc_ctx
::~
desc_ctx
()
queue_base
::
desc_ctx
::~
desc_ctx
()
{
{
delete
[]((
uint8_t
*
)
desc
);
delete
[]
((
uint8_t
*
)
desc
);
if
(
data_capacity
>
0
)
if
(
data_capacity
>
0
)
delete
[]((
uint8_t
*
)
data
);
delete
[]
((
uint8_t
*
)
data
);
}
}
void
queue_base
::
desc_ctx
::
prepare
()
void
queue_base
::
desc_ctx
::
prepare
()
{
{
prepared
();
prepared
();
}
}
void
queue_base
::
desc_ctx
::
prepared
()
void
queue_base
::
desc_ctx
::
prepared
()
{
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"prepared desc "
<<
index
<<
logger
::
endl
;
queue
.
log
<<
"prepared desc "
<<
index
<<
logger
::
endl
;
#endif
#endif
assert
(
state
==
DESC_PREPARING
);
assert
(
state
==
DESC_PREPARING
);
state
=
DESC_PREPARED
;
state
=
DESC_PREPARED
;
}
}
void
queue_base
::
desc_ctx
::
processed
()
void
queue_base
::
desc_ctx
::
processed
()
{
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"processed desc "
<<
index
<<
logger
::
endl
;
queue
.
log
<<
"processed desc "
<<
index
<<
logger
::
endl
;
#endif
#endif
assert
(
state
==
DESC_PROCESSING
);
assert
(
state
==
DESC_PROCESSING
);
state
=
DESC_PROCESSED
;
state
=
DESC_PROCESSED
;
}
}
#define MAX_DMA_SIZE ((size_t)
9024)
#define MAX_DMA_SIZE ((size_t)9024)
void
queue_base
::
desc_ctx
::
data_fetch
(
uint64_t
addr
,
size_t
data_len
)
void
queue_base
::
desc_ctx
::
data_fetch
(
uint64_t
addr
,
size_t
data_len
)
{
{
if
(
data_capacity
<
data_len
)
{
if
(
data_capacity
<
data_len
)
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"data_fetch allocating"
<<
logger
::
endl
;
queue
.
log
<<
"data_fetch allocating"
<<
logger
::
endl
;
#endif
#endif
if
(
data_capacity
!=
0
)
if
(
data_capacity
!=
0
)
delete
[]
((
uint8_t
*
)
data
);
delete
[]((
uint8_t
*
)
data
);
data
=
new
uint8_t
[
data_len
];
data
=
new
uint8_t
[
data_len
];
data_capacity
=
data_len
;
data_capacity
=
data_len
;
}
}
dma_data_fetch
*
dma
=
new
dma_data_fetch
(
*
this
,
std
::
min
(
data_len
,
dma_data_fetch
*
dma
=
MAX_DMA_SIZE
),
data
);
new
dma_data_fetch
(
*
this
,
std
::
min
(
data_len
,
MAX_DMA_SIZE
),
data
);
dma
->
part_offset
=
0
;
dma
->
part_offset
=
0
;
dma
->
total_len
=
data_len
;
dma
->
total_len
=
data_len
;
dma
->
write
=
false
;
dma
->
write
=
false
;
dma
->
dma_addr
=
addr
;
dma
->
dma_addr
=
addr
;
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"fetching data idx="
<<
index
<<
" addr="
<<
addr
<<
" len="
<<
queue
.
log
<<
"fetching data idx="
<<
index
<<
" addr="
<<
addr
data_len
<<
logger
::
endl
;
<<
" len="
<<
data_len
<<
logger
::
endl
;
queue
.
log
<<
" dma = "
<<
dma
<<
" data="
<<
data
<<
logger
::
endl
;
queue
.
log
<<
" dma = "
<<
dma
<<
" data="
<<
data
<<
logger
::
endl
;
#endif
#endif
runner
->
issue_dma
(
*
dma
);
runner
->
issue_dma
(
*
dma
);
}
}
void
queue_base
::
desc_ctx
::
data_fetched
(
uint64_t
addr
,
size_t
len
)
void
queue_base
::
desc_ctx
::
data_fetched
(
uint64_t
addr
,
size_t
len
)
{
{
prepared
();
prepared
();
}
}
void
queue_base
::
desc_ctx
::
data_write
(
uint64_t
addr
,
size_t
data_len
,
void
queue_base
::
desc_ctx
::
data_write
(
uint64_t
addr
,
size_t
data_len
,
const
void
*
buf
)
const
void
*
buf
)
{
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"data_write(addr="
<<
addr
<<
" datalen="
<<
data_len
<<
")"
<<
queue
.
log
<<
"data_write(addr="
<<
addr
<<
" datalen="
<<
data_len
<<
")"
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
dma_data_wb
*
data_dma
=
new
dma_data_wb
(
*
this
,
data_len
);
dma_data_wb
*
data_dma
=
new
dma_data_wb
(
*
this
,
data_len
);
data_dma
->
write
=
true
;
data_dma
->
write
=
true
;
data_dma
->
dma_addr
=
addr
;
data_dma
->
dma_addr
=
addr
;
memcpy
(
data_dma
->
data
,
buf
,
data_len
);
memcpy
(
data_dma
->
data
,
buf
,
data_len
);
runner
->
issue_dma
(
*
data_dma
);
runner
->
issue_dma
(
*
data_dma
);
}
}
void
queue_base
::
desc_ctx
::
data_written
(
uint64_t
addr
,
size_t
len
)
void
queue_base
::
desc_ctx
::
data_written
(
uint64_t
addr
,
size_t
len
)
{
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"data_written(addr="
<<
addr
<<
" datalen="
<<
len
<<
")"
<<
queue
.
log
<<
"data_written(addr="
<<
addr
<<
" datalen="
<<
len
<<
")"
logger
::
endl
;
<<
logger
::
endl
;
#endif
#endif
processed
();
processed
();
}
}
queue_base
::
dma_fetch
::
dma_fetch
(
queue_base
&
queue_
,
size_t
len_
)
queue_base
::
dma_fetch
::
dma_fetch
(
queue_base
&
queue_
,
size_t
len_
)
:
queue
(
queue_
)
:
queue
(
queue_
)
{
{
data
=
new
char
[
len_
];
data
=
new
char
[
len_
];
len
=
len_
;
len
=
len_
;
}
}
queue_base
::
dma_fetch
::~
dma_fetch
()
queue_base
::
dma_fetch
::~
dma_fetch
()
{
{
delete
[]((
char
*
)
data
);
delete
[]
((
char
*
)
data
);
}
}
void
queue_base
::
dma_fetch
::
done
()
void
queue_base
::
dma_fetch
::
done
()
{
{
uint8_t
*
buf
=
reinterpret_cast
<
uint8_t
*>
(
data
);
uint8_t
*
buf
=
reinterpret_cast
<
uint8_t
*>
(
data
);
for
(
uint32_t
i
=
0
;
i
<
len
/
queue
.
desc_len
;
i
++
)
{
for
(
uint32_t
i
=
0
;
i
<
len
/
queue
.
desc_len
;
i
++
)
{
desc_ctx
&
ctx
=
*
queue
.
desc_ctxs
[(
pos
+
i
)
%
queue
.
MAX_ACTIVE_DESCS
];
desc_ctx
&
ctx
=
*
queue
.
desc_ctxs
[(
pos
+
i
)
%
queue
.
MAX_ACTIVE_DESCS
];
memcpy
(
ctx
.
desc
,
buf
+
queue
.
desc_len
*
i
,
queue
.
desc_len
);
memcpy
(
ctx
.
desc
,
buf
+
queue
.
desc_len
*
i
,
queue
.
desc_len
);
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
queue
.
log
<<
"preparing desc "
<<
ctx
.
index
<<
logger
::
endl
;
queue
.
log
<<
"preparing desc "
<<
ctx
.
index
<<
logger
::
endl
;
#endif
#endif
ctx
.
state
=
desc_ctx
::
DESC_PREPARING
;
ctx
.
state
=
desc_ctx
::
DESC_PREPARING
;
ctx
.
prepare
();
ctx
.
prepare
();
}
}
queue
.
trigger
();
queue
.
trigger
();
delete
this
;
delete
this
;
}
}
queue_base
::
dma_data_fetch
::
dma_data_fetch
(
desc_ctx
&
ctx_
,
size_t
len_
,
queue_base
::
dma_data_fetch
::
dma_data_fetch
(
desc_ctx
&
ctx_
,
size_t
len_
,
void
*
buffer
)
void
*
buffer
)
:
ctx
(
ctx_
)
:
ctx
(
ctx_
)
{
{
data
=
buffer
;
data
=
buffer
;
len
=
len_
;
len
=
len_
;
}
}
queue_base
::
dma_data_fetch
::~
dma_data_fetch
()
queue_base
::
dma_data_fetch
::~
dma_data_fetch
()
{
{
}
}
void
queue_base
::
dma_data_fetch
::
done
()
void
queue_base
::
dma_data_fetch
::
done
()
{
{
part_offset
+=
len
;
part_offset
+=
len
;
dma_addr
+=
len
;
dma_addr
+=
len
;
data
=
(
uint8_t
*
)
data
+
len
;
data
=
(
uint8_t
*
)
data
+
len
;
if
(
part_offset
<
total_len
)
{
if
(
part_offset
<
total_len
)
{
#ifdef DEBUG_QUEUES
#ifdef DEBUG_QUEUES
ctx
.
queue
.
log
<<
" dma_fetch: next part of multi part dma"
<<
ctx
.
queue
.
log
<<
" dma_fetch: next part of multi part dma"
<<
logger
::
endl
;
logger
::
endl
;
#endif
#endif
len
=
std
::
min
(
total_len
-
part_offset
,
MAX_DMA_SIZE
);
len
=
std
::
min
(
total_len
-
part_offset
,
MAX_DMA_SIZE
);
runner
->
issue_dma
(
*
this
);
runner
->
issue_dma
(
*
this
);
return
;
return
;
}
}
ctx
.
data_fetched
(
dma_addr
-
part_offset
,
total_len
);
ctx
.
data_fetched
(
dma_addr
-
part_offset
,
total_len
);
ctx
.
queue
.
trigger
();
ctx
.
queue
.
trigger
();
delete
this
;
delete
this
;
}
}
queue_base
::
dma_wb
::
dma_wb
(
queue_base
&
queue_
,
size_t
len_
)
queue_base
::
dma_wb
::
dma_wb
(
queue_base
&
queue_
,
size_t
len_
)
:
queue
(
queue_
)
{
:
queue
(
queue_
)
data
=
new
char
[
len_
];
{
len
=
len_
;
data
=
new
char
[
len_
];
len
=
len_
;
}
}
queue_base
::
dma_wb
::~
dma_wb
()
queue_base
::
dma_wb
::~
dma_wb
()
{
{
delete
[]((
char
*
)
data
);
delete
[]
((
char
*
)
data
);
}
}
void
queue_base
::
dma_wb
::
done
()
void
queue_base
::
dma_wb
::
done
()
{
{
queue
.
writeback_done
(
pos
,
len
/
queue
.
desc_len
);
queue
.
writeback_done
(
pos
,
len
/
queue
.
desc_len
);
queue
.
trigger
();
queue
.
trigger
();
delete
this
;
delete
this
;
}
}
queue_base
::
dma_data_wb
::
dma_data_wb
(
desc_ctx
&
ctx_
,
size_t
len_
)
:
ctx
(
ctx_
)
{
queue_base
::
dma_data_wb
::
dma_data_wb
(
desc_ctx
&
ctx_
,
size_t
len_
)
data
=
new
char
[
len_
];
:
ctx
(
ctx_
)
len
=
len_
;
{
data
=
new
char
[
len_
];
len
=
len_
;
}
}
queue_base
::
dma_data_wb
::~
dma_data_wb
()
queue_base
::
dma_data_wb
::~
dma_data_wb
()
{
{
delete
[]((
char
*
)
data
);
delete
[]
((
char
*
)
data
);
}
}
void
queue_base
::
dma_data_wb
::
done
()
void
queue_base
::
dma_data_wb
::
done
()
{
{
ctx
.
data_written
(
dma_addr
,
len
);
ctx
.
data_written
(
dma_addr
,
len
);
ctx
.
queue
.
trigger
();
ctx
.
queue
.
trigger
();
delete
this
;
delete
this
;
}
}
sims/nic/i40e_bm/logger.cc
View file @
d4666c97
...
@@ -30,69 +30,58 @@ using namespace i40e;
...
@@ -30,69 +30,58 @@ using namespace i40e;
extern
nicbm
::
Runner
*
runner
;
extern
nicbm
::
Runner
*
runner
;
logger
::
logger
(
const
std
::
string
&
label_
)
logger
::
logger
(
const
std
::
string
&
label_
)
:
label
(
label_
)
{
:
label
(
label_
)
ss
<<
std
::
hex
;
{
ss
<<
std
::
hex
;
}
}
logger
&
logger
::
operator
<<
(
char
c
)
logger
&
logger
::
operator
<<
(
char
c
)
{
{
if
(
c
==
endl
)
{
if
(
c
==
endl
)
{
std
::
cerr
<<
runner
->
time_ps
()
<<
" "
<<
label
<<
": "
<<
ss
.
str
()
std
::
cerr
<<
runner
->
time_ps
()
<<
" "
<<
label
<<
": "
<<
ss
.
str
()
<<
<<
std
::
endl
;
std
::
endl
;
ss
.
str
(
std
::
string
());
ss
.
str
(
std
::
string
());
ss
<<
std
::
hex
;
ss
<<
std
::
hex
;
}
else
{
}
else
{
ss
<<
c
;
ss
<<
c
;
}
}
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
int32_t
i
)
logger
&
logger
::
operator
<<
(
int32_t
i
)
{
{
ss
<<
i
;
ss
<<
i
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
uint8_t
i
)
logger
&
logger
::
operator
<<
(
uint8_t
i
)
{
{
ss
<<
(
unsigned
)
i
;
ss
<<
(
unsigned
)
i
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
uint16_t
i
)
logger
&
logger
::
operator
<<
(
uint16_t
i
)
{
{
ss
<<
i
;
ss
<<
i
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
uint32_t
i
)
logger
&
logger
::
operator
<<
(
uint32_t
i
)
{
{
ss
<<
i
;
ss
<<
i
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
uint64_t
i
)
logger
&
logger
::
operator
<<
(
uint64_t
i
)
{
{
ss
<<
i
;
ss
<<
i
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
bool
b
)
logger
&
logger
::
operator
<<
(
bool
b
)
{
{
ss
<<
b
;
ss
<<
b
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
const
char
*
str
)
logger
&
logger
::
operator
<<
(
const
char
*
str
)
{
{
ss
<<
str
;
ss
<<
str
;
return
*
this
;
return
*
this
;
}
}
logger
&
logger
::
operator
<<
(
void
*
ptr
)
logger
&
logger
::
operator
<<
(
void
*
ptr
)
{
{
ss
<<
ptr
;
ss
<<
ptr
;
return
*
this
;
return
*
this
;
}
}
sims/nic/i40e_bm/rss.cc
View file @
d4666c97
...
@@ -26,74 +26,66 @@
...
@@ -26,74 +26,66 @@
using
namespace
i40e
;
using
namespace
i40e
;
rss_key_cache
::
rss_key_cache
(
const
uint32_t
(
&
key_
)[
key_len
/
4
])
rss_key_cache
::
rss_key_cache
(
const
uint32_t
(
&
key_
)[
key_len
/
4
])
:
key
(
key_
)
{
:
key
(
key_
)
cache_dirty
=
true
;
{
cache_dirty
=
true
;
}
}
void
rss_key_cache
::
build
()
{
const
uint8_t
*
k
=
reinterpret_cast
<
const
uint8_t
*>
(
&
key
);
uint32_t
result
=
(((
uint32_t
)
k
[
0
])
<<
24
)
|
(((
uint32_t
)
k
[
1
])
<<
16
)
|
(((
uint32_t
)
k
[
2
])
<<
8
)
|
((
uint32_t
)
k
[
3
]);
void
rss_key_cache
::
build
()
uint32_t
idx
=
32
;
{
size_t
i
;
const
uint8_t
*
k
=
reinterpret_cast
<
const
uint8_t
*>
(
&
key
);
uint32_t
result
=
(((
uint32_t
)
k
[
0
])
<<
24
)
|
(((
uint32_t
)
k
[
1
])
<<
16
)
|
(((
uint32_t
)
k
[
2
])
<<
8
)
|
((
uint32_t
)
k
[
3
]);
uint32_t
idx
=
32
;
size_t
i
;
for
(
i
=
0
;
i
<
cache_len
;
i
++
,
idx
++
)
{
for
(
i
=
0
;
i
<
cache_len
;
i
++
,
idx
++
)
{
uint8_t
shift
=
(
idx
%
8
);
uint8_t
shift
=
(
idx
%
8
);
uint32_t
bit
;
uint32_t
bit
;
cache
[
i
]
=
result
;
cache
[
i
]
=
result
;
bit
=
((
k
[
idx
/
8
]
<<
shift
)
&
0x80
)
?
1
:
0
;
bit
=
((
k
[
idx
/
8
]
<<
shift
)
&
0x80
)
?
1
:
0
;
result
=
((
result
<<
1
)
|
bit
);
result
=
((
result
<<
1
)
|
bit
);
}
}
cache_dirty
=
false
;
cache_dirty
=
false
;
}
}
void
rss_key_cache
::
set_dirty
()
void
rss_key_cache
::
set_dirty
()
{
{
cache_dirty
=
true
;
cache_dirty
=
true
;
}
}
uint32_t
rss_key_cache
::
hash_ipv4
(
uint32_t
sip
,
uint32_t
dip
,
uint16_t
sp
,
uint32_t
rss_key_cache
::
hash_ipv4
(
uint32_t
sip
,
uint32_t
dip
,
uint16_t
sp
,
uint16_t
dp
)
uint16_t
dp
)
{
{
static
const
uint32_t
MSB32
=
0x80000000
;
static
const
uint32_t
MSB32
=
0x80000000
;
static
const
uint32_t
MSB16
=
0x8000
;
static
const
uint32_t
MSB16
=
0x8000
;
uint32_t
res
=
0
;
uint32_t
res
=
0
;
int
i
;
int
i
;
if
(
cache_dirty
)
if
(
cache_dirty
)
build
();
build
();
for
(
i
=
0
;
i
<
32
;
i
++
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
sip
&
MSB32
)
if
(
sip
&
MSB32
)
res
^=
cache
[
i
];
res
^=
cache
[
i
];
sip
<<=
1
;
sip
<<=
1
;
}
}
for
(
i
=
0
;
i
<
32
;
i
++
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
dip
&
MSB32
)
if
(
dip
&
MSB32
)
res
^=
cache
[
32
+
i
];
res
^=
cache
[
32
+
i
];
dip
<<=
1
;
dip
<<=
1
;
}
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
sp
&
MSB16
)
if
(
sp
&
MSB16
)
res
^=
cache
[
64
+
i
];
res
^=
cache
[
64
+
i
];
sp
<<=
1
;
sp
<<=
1
;
}
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
dp
&
MSB16
)
if
(
dp
&
MSB16
)
res
^=
cache
[
80
+
i
];
res
^=
cache
[
80
+
i
];
dp
<<=
1
;
dp
<<=
1
;
}
}
return
res
;
return
res
;
}
}
#if 0
#if 0
...
...
sims/nic/i40e_bm/xsums.cc
View file @
d4666c97
...
@@ -6,9 +6,10 @@
...
@@ -6,9 +6,10 @@
* All rights reserved.
* All rights reserved.
*/
*/
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <arpa/inet.h>
#include <cassert>
#include <cassert>
#include <iostream>
#include <iostream>
...
@@ -18,142 +19,130 @@ namespace i40e {
...
@@ -18,142 +19,130 @@ namespace i40e {
/* from dpdk/lib/librte_net/rte_tcp.h */
/* from dpdk/lib/librte_net/rte_tcp.h */
struct
rte_tcp_hdr
{
struct
rte_tcp_hdr
{
uint16_t
src_port
;
/**< TCP source port. */
uint16_t
src_port
;
/**< TCP source port. */
uint16_t
dst_port
;
/**< TCP destination port. */
uint16_t
dst_port
;
/**< TCP destination port. */
uint32_t
sent_seq
;
/**< TX data sequence number. */
uint32_t
sent_seq
;
/**< TX data sequence number. */
uint32_t
recv_ack
;
/**< RX data acknowledgment sequence number. */
uint32_t
recv_ack
;
/**< RX data acknowledgment sequence number. */
uint8_t
data_off
;
/**< Data offset. */
uint8_t
data_off
;
/**< Data offset. */
uint8_t
tcp_flags
;
/**< TCP flags */
uint8_t
tcp_flags
;
/**< TCP flags */
uint16_t
rx_win
;
/**< RX flow control window. */
uint16_t
rx_win
;
/**< RX flow control window. */
uint16_t
cksum
;
/**< TCP checksum. */
uint16_t
cksum
;
/**< TCP checksum. */
uint16_t
tcp_urp
;
/**< TCP urgent pointer, if any. */
uint16_t
tcp_urp
;
/**< TCP urgent pointer, if any. */
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/* from dpdk/lib/librte_net/rte_ip.h */
/* from dpdk/lib/librte_net/rte_ip.h */
struct
ipv4_hdr
{
struct
ipv4_hdr
{
uint8_t
version_ihl
;
/**< version and header length */
uint8_t
version_ihl
;
/**< version and header length */
uint8_t
type_of_service
;
/**< type of service */
uint8_t
type_of_service
;
/**< type of service */
uint16_t
total_length
;
/**< length of packet */
uint16_t
total_length
;
/**< length of packet */
uint16_t
packet_id
;
/**< packet ID */
uint16_t
packet_id
;
/**< packet ID */
uint16_t
fragment_offset
;
/**< fragmentation offset */
uint16_t
fragment_offset
;
/**< fragmentation offset */
uint8_t
time_to_live
;
/**< time to live */
uint8_t
time_to_live
;
/**< time to live */
uint8_t
next_proto_id
;
/**< protocol ID */
uint8_t
next_proto_id
;
/**< protocol ID */
uint16_t
hdr_checksum
;
/**< header checksum */
uint16_t
hdr_checksum
;
/**< header checksum */
uint32_t
src_addr
;
/**< source address */
uint32_t
src_addr
;
/**< source address */
uint32_t
dst_addr
;
/**< destination address */
uint32_t
dst_addr
;
/**< destination address */
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
static
inline
uint32_t
__rte_raw_cksum
(
const
void
*
buf
,
size_t
len
,
static
inline
uint32_t
__rte_raw_cksum
(
const
void
*
buf
,
size_t
len
,
uint32_t
sum
)
uint32_t
sum
)
{
{
/* workaround gcc strict-aliasing warning */
/* workaround gcc strict-aliasing warning */
uintptr_t
ptr
=
(
uintptr_t
)
buf
;
uintptr_t
ptr
=
(
uintptr_t
)
buf
;
typedef
uint16_t
__attribute__
((
__may_alias__
))
u16_p
;
typedef
uint16_t
__attribute__
((
__may_alias__
))
u16_p
;
const
u16_p
*
u16_buf
=
(
const
u16_p
*
)
ptr
;
const
u16_p
*
u16_buf
=
(
const
u16_p
*
)
ptr
;
while
(
len
>=
(
sizeof
(
*
u16_buf
)
*
4
))
{
while
(
len
>=
(
sizeof
(
*
u16_buf
)
*
4
))
{
sum
+=
u16_buf
[
0
];
sum
+=
u16_buf
[
0
];
sum
+=
u16_buf
[
1
];
sum
+=
u16_buf
[
1
];
sum
+=
u16_buf
[
2
];
sum
+=
u16_buf
[
2
];
sum
+=
u16_buf
[
3
];
sum
+=
u16_buf
[
3
];
len
-=
sizeof
(
*
u16_buf
)
*
4
;
len
-=
sizeof
(
*
u16_buf
)
*
4
;
u16_buf
+=
4
;
u16_buf
+=
4
;
}
}
while
(
len
>=
sizeof
(
*
u16_buf
))
{
while
(
len
>=
sizeof
(
*
u16_buf
))
{
sum
+=
*
u16_buf
;
sum
+=
*
u16_buf
;
len
-=
sizeof
(
*
u16_buf
);
len
-=
sizeof
(
*
u16_buf
);
u16_buf
+=
1
;
u16_buf
+=
1
;
}
}
/* if length is in odd bytes */
/* if length is in odd bytes */
if
(
len
==
1
)
{
if
(
len
==
1
)
{
uint16_t
left
=
0
;
uint16_t
left
=
0
;
*
(
uint8_t
*
)
&
left
=
*
(
const
uint8_t
*
)
u16_buf
;
*
(
uint8_t
*
)
&
left
=
*
(
const
uint8_t
*
)
u16_buf
;
sum
+=
left
;
sum
+=
left
;
}
}
return
sum
;
return
sum
;
}
}
static
inline
uint16_t
__rte_raw_cksum_reduce
(
uint32_t
sum
)
static
inline
uint16_t
__rte_raw_cksum_reduce
(
uint32_t
sum
)
{
{
sum
=
((
sum
&
0xffff0000
)
>>
16
)
+
(
sum
&
0xffff
);
sum
=
((
sum
&
0xffff0000
)
>>
16
)
+
(
sum
&
0xffff
);
sum
=
((
sum
&
0xffff0000
)
>>
16
)
+
(
sum
&
0xffff
);
sum
=
((
sum
&
0xffff0000
)
>>
16
)
+
(
sum
&
0xffff
);
return
(
uint16_t
)
sum
;
return
(
uint16_t
)
sum
;
}
}
static
inline
uint16_t
rte_raw_cksum
(
const
void
*
buf
,
size_t
len
)
static
inline
uint16_t
rte_raw_cksum
(
const
void
*
buf
,
size_t
len
)
{
{
uint32_t
sum
;
uint32_t
sum
;
sum
=
__rte_raw_cksum
(
buf
,
len
,
0
);
sum
=
__rte_raw_cksum
(
buf
,
len
,
0
);
return
__rte_raw_cksum_reduce
(
sum
);
return
__rte_raw_cksum_reduce
(
sum
);
}
}
static
inline
uint16_t
rte_ipv4_phdr_cksum
(
const
struct
ipv4_hdr
*
ipv4_hdr
)
static
inline
uint16_t
rte_ipv4_phdr_cksum
(
const
struct
ipv4_hdr
*
ipv4_hdr
)
{
{
struct
ipv4_psd_header
{
struct
ipv4_psd_header
{
uint32_t
src_addr
;
/* IP address of source host. */
uint32_t
src_addr
;
/* IP address of source host. */
uint32_t
dst_addr
;
/* IP address of destination host. */
uint32_t
dst_addr
;
/* IP address of destination host. */
uint8_t
zero
;
/* zero. */
uint8_t
zero
;
/* zero. */
uint8_t
proto
;
/* L4 protocol type. */
uint8_t
proto
;
/* L4 protocol type. */
uint16_t
len
;
/* L4 length. */
uint16_t
len
;
/* L4 length. */
}
psd_hdr
;
}
psd_hdr
;
psd_hdr
.
src_addr
=
ipv4_hdr
->
src_addr
;
psd_hdr
.
src_addr
=
ipv4_hdr
->
src_addr
;
psd_hdr
.
dst_addr
=
ipv4_hdr
->
dst_addr
;
psd_hdr
.
dst_addr
=
ipv4_hdr
->
dst_addr
;
psd_hdr
.
zero
=
0
;
psd_hdr
.
zero
=
0
;
psd_hdr
.
proto
=
ipv4_hdr
->
next_proto_id
;
psd_hdr
.
proto
=
ipv4_hdr
->
next_proto_id
;
psd_hdr
.
len
=
htons
(
psd_hdr
.
len
=
htons
(
(
uint16_t
)(
ntohs
(
ipv4_hdr
->
total_length
)
-
sizeof
(
struct
ipv4_hdr
)));
(
uint16_t
)(
ntohs
(
ipv4_hdr
->
total_length
)
return
rte_raw_cksum
(
&
psd_hdr
,
sizeof
(
psd_hdr
));
-
sizeof
(
struct
ipv4_hdr
)));
return
rte_raw_cksum
(
&
psd_hdr
,
sizeof
(
psd_hdr
));
}
}
void
xsum_tcp
(
void
*
tcphdr
,
size_t
l4_len
)
{
void
xsum_tcp
(
void
*
tcphdr
,
size_t
l4_len
)
struct
rte_tcp_hdr
*
tcph
=
reinterpret_cast
<
struct
rte_tcp_hdr
*>
(
tcphdr
);
{
uint32_t
cksum
=
rte_raw_cksum
(
tcphdr
,
l4_len
);
struct
rte_tcp_hdr
*
tcph
=
reinterpret_cast
<
struct
rte_tcp_hdr
*>
(
tcphdr
);
cksum
=
((
cksum
&
0xffff0000
)
>>
16
)
+
(
cksum
&
0xffff
);
uint32_t
cksum
=
rte_raw_cksum
(
tcphdr
,
l4_len
);
cksum
=
(
~
cksum
)
&
0xffff
;
cksum
=
((
cksum
&
0xffff0000
)
>>
16
)
+
(
cksum
&
0xffff
);
tcph
->
cksum
=
cksum
;
cksum
=
(
~
cksum
)
&
0xffff
;
tcph
->
cksum
=
cksum
;
}
}
void
xsum_tcpip_tso
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
void
xsum_tcpip_tso
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
uint16_t
paylen
)
uint16_t
paylen
)
{
{
struct
ipv4_hdr
*
ih
=
(
struct
ipv4_hdr
*
)
iphdr
;
struct
ipv4_hdr
*
ih
=
(
struct
ipv4_hdr
*
)
iphdr
;
struct
rte_tcp_hdr
*
tcph
=
(
struct
rte_tcp_hdr
*
)((
uint8_t
*
)
iphdr
+
iplen
);
struct
rte_tcp_hdr
*
tcph
=
(
struct
rte_tcp_hdr
*
)
uint32_t
cksum
;
((
uint8_t
*
)
iphdr
+
iplen
);
uint32_t
cksum
;
// calculate ip xsum
ih
->
total_length
=
htons
(
iplen
+
l4len
+
paylen
);
// calculate ip xsum
ih
->
hdr_checksum
=
0
;
ih
->
total_length
=
htons
(
iplen
+
l4len
+
paylen
);
cksum
=
rte_raw_cksum
(
iphdr
,
iplen
);
ih
->
hdr_checksum
=
0
;
cksum
=
((
cksum
&
0xffff0000
)
>>
16
)
+
(
cksum
&
0xffff
);
cksum
=
rte_raw_cksum
(
iphdr
,
iplen
);
cksum
=
(
~
cksum
)
&
0xffff
;
cksum
=
((
cksum
&
0xffff0000
)
>>
16
)
+
(
cksum
&
0xffff
);
ih
->
hdr_checksum
=
cksum
;
cksum
=
(
~
cksum
)
&
0xffff
;
ih
->
hdr_checksum
=
cksum
;
// calculate tcp xsum
tcph
->
cksum
=
0
;
// calculate tcp xsum
cksum
=
rte_raw_cksum
(
tcph
,
l4len
+
paylen
);
tcph
->
cksum
=
0
;
cksum
+=
rte_ipv4_phdr_cksum
(
ih
);
cksum
=
rte_raw_cksum
(
tcph
,
l4len
+
paylen
);
cksum
=
((
cksum
&
0xffff0000
)
>>
16
)
+
(
cksum
&
0xffff
);
cksum
+=
rte_ipv4_phdr_cksum
(
ih
);
cksum
=
(
~
cksum
)
&
0xffff
;
cksum
=
((
cksum
&
0xffff0000
)
>>
16
)
+
(
cksum
&
0xffff
);
tcph
->
cksum
=
cksum
;
cksum
=
(
~
cksum
)
&
0xffff
;
tcph
->
cksum
=
cksum
;
}
}
void
tso_postupdate_header
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
void
tso_postupdate_header
(
void
*
iphdr
,
uint8_t
iplen
,
uint8_t
l4len
,
uint16_t
paylen
)
uint16_t
paylen
)
{
{
struct
ipv4_hdr
*
ih
=
(
struct
ipv4_hdr
*
)
iphdr
;
struct
ipv4_hdr
*
ih
=
(
struct
ipv4_hdr
*
)
iphdr
;
struct
rte_tcp_hdr
*
tcph
=
(
struct
rte_tcp_hdr
*
)((
uint8_t
*
)
iphdr
+
iplen
);
struct
rte_tcp_hdr
*
tcph
=
(
struct
rte_tcp_hdr
*
)
tcph
->
sent_seq
=
htonl
(
ntohl
(
tcph
->
sent_seq
)
+
paylen
);
((
uint8_t
*
)
iphdr
+
iplen
);
ih
->
packet_id
=
htons
(
ntohs
(
ih
->
packet_id
)
+
1
);
tcph
->
sent_seq
=
htonl
(
ntohl
(
tcph
->
sent_seq
)
+
paylen
);
ih
->
packet_id
=
htons
(
ntohs
(
ih
->
packet_id
)
+
1
);
}
}
}
// namespace i40e
}
// namespace i40e
trace/events.h
View file @
d4666c97
...
@@ -27,290 +27,267 @@
...
@@ -27,290 +27,267 @@
#include <string>
#include <string>
class
event
{
class
event
{
public:
public:
uint64_t
ts
;
uint64_t
ts
;
event
(
uint64_t
ts_
)
event
(
uint64_t
ts_
)
:
ts
(
ts_
)
{
:
ts
(
ts_
)
}
{
}
virtual
~
event
()
{
}
virtual
~
event
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
=
0
;
virtual
void
dump
(
std
::
ostream
&
out
)
=
0
;
};
};
class
EHostCall
:
public
event
{
class
EHostCall
:
public
event
{
public:
public:
const
std
::
string
&
fun
;
const
std
::
string
&
fun
;
EHostCall
(
uint64_t
ts_
,
const
std
::
string
&
fun_
)
EHostCall
(
uint64_t
ts_
,
const
std
::
string
&
fun_
)
:
event
(
ts_
),
fun
(
fun_
)
{
:
event
(
ts_
),
fun
(
fun_
)
}
{
}
virtual
~
EHostCall
()
{
}
virtual
~
EHostCall
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.CALL "
<<
fun
<<
std
::
endl
;
out
<<
ts
<<
": H.CALL "
<<
fun
<<
std
::
endl
;
}
}
};
};
class
EHostMsiX
:
public
event
{
class
EHostMsiX
:
public
event
{
public:
public:
uint16_t
vec
;
uint16_t
vec
;
EHostMsiX
(
uint64_t
ts_
,
uint16_t
vec_
)
EHostMsiX
(
uint64_t
ts_
,
uint16_t
vec_
)
:
event
(
ts_
),
vec
(
vec_
)
{
:
event
(
ts_
),
vec
(
vec_
)
}
{
}
virtual
~
EHostMsiX
()
{
}
virtual
~
EHostMsiX
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.MSIX "
<<
vec
<<
std
::
endl
;
out
<<
ts
<<
": H.MSIX "
<<
vec
<<
std
::
endl
;
}
}
};
};
class
EHostDmaR
:
public
event
{
class
EHostDmaR
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
EHostDmaR
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
EHostDmaR
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
{
{
}
}
virtual
~
EHostDmaR
()
{
virtual
~
EHostDmaR
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.DMAR id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
size
out
<<
ts
<<
": H.DMAR id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
<<
std
::
endl
;
size
<<
std
::
endl
;
}
}
};
};
class
EHostDmaW
:
public
event
{
class
EHostDmaW
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
EHostDmaW
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
EHostDmaW
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
{
{
}
}
virtual
~
EHostDmaW
()
{
virtual
~
EHostDmaW
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.DMAW id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
size
out
<<
ts
<<
": H.DMAW id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
<<
std
::
endl
;
size
<<
std
::
endl
;
}
}
};
};
class
EHostDmaC
:
public
event
{
class
EHostDmaC
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
EHostDmaC
(
uint64_t
ts_
,
uint64_t
id_
)
EHostDmaC
(
uint64_t
ts_
,
uint64_t
id_
)
:
event
(
ts_
),
id
(
id_
)
{
:
event
(
ts_
),
id
(
id_
)
}
{
}
virtual
~
EHostDmaC
()
{
}
virtual
~
EHostDmaC
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.DMAC id="
<<
id
<<
std
::
endl
;
out
<<
ts
<<
": H.DMAC id="
<<
id
<<
std
::
endl
;
}
}
};
};
class
EHostMmioR
:
public
event
{
class
EHostMmioR
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
EHostMmioR
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
EHostMmioR
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
{
{
}
}
virtual
~
EHostMmioR
()
{
virtual
~
EHostMmioR
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.MMIOR id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
size
out
<<
ts
<<
": H.MMIOR id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
<<
std
::
endl
;
size
<<
std
::
endl
;
}
}
};
};
class
EHostMmioW
:
public
event
{
class
EHostMmioW
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
EHostMmioW
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
EHostMmioW
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
{
{
}
}
virtual
~
EHostMmioW
()
{
virtual
~
EHostMmioW
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.MMIOW id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
size
out
<<
ts
<<
": H.MMIOW id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
<<
std
::
endl
;
size
<<
std
::
endl
;
}
}
};
};
class
EHostMmioC
:
public
event
{
class
EHostMmioC
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
EHostMmioC
(
uint64_t
ts_
,
uint64_t
id_
)
EHostMmioC
(
uint64_t
ts_
,
uint64_t
id_
)
:
event
(
ts_
),
id
(
id_
)
{
:
event
(
ts_
),
id
(
id_
)
}
{
}
virtual
~
EHostMmioC
()
{
}
virtual
~
EHostMmioC
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": H.MMIOC id="
<<
id
<<
std
::
endl
;
out
<<
ts
<<
": H.MMIOC id="
<<
id
<<
std
::
endl
;
}
}
};
};
class
e_nic_msix
:
public
event
{
class
e_nic_msix
:
public
event
{
public:
public:
uint16_t
vec
;
uint16_t
vec
;
e_nic_msix
(
uint64_t
ts_
,
uint16_t
vec_
)
e_nic_msix
(
uint64_t
ts_
,
uint16_t
vec_
)
:
event
(
ts_
),
vec
(
vec_
)
{
:
event
(
ts_
),
vec
(
vec_
)
}
{
}
virtual
~
e_nic_msix
()
{
}
virtual
~
e_nic_msix
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.MSIX "
<<
vec
<<
std
::
endl
;
out
<<
ts
<<
": N.MSIX "
<<
vec
<<
std
::
endl
;
}
}
};
};
class
e_nic_dma_i
:
public
event
{
class
e_nic_dma_i
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
e_nic_dma_i
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
e_nic_dma_i
(
uint64_t
ts_
,
uint64_t
id_
,
uint64_t
addr_
,
uint64_t
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
:
event
(
ts_
),
id
(
id_
),
addr
(
addr_
),
size
(
size_
)
{
{
}
}
virtual
~
e_nic_dma_i
()
{
virtual
~
e_nic_dma_i
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.DMAI id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
size
out
<<
ts
<<
": N.DMAI id="
<<
id
<<
" addr="
<<
addr
<<
" size="
<<
<<
std
::
endl
;
size
<<
std
::
endl
;
}
}
};
};
class
e_nic_dma_c
:
public
event
{
class
e_nic_dma_c
:
public
event
{
public:
public:
uint64_t
id
;
uint64_t
id
;
e_nic_dma_c
(
uint64_t
ts_
,
uint64_t
id_
)
e_nic_dma_c
(
uint64_t
ts_
,
uint64_t
id_
)
:
event
(
ts_
),
id
(
id_
)
{
:
event
(
ts_
),
id
(
id_
)
{
}
}
virtual
~
e_nic_dma_c
()
{
}
virtual
~
e_nic_dma_c
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.DMAC id="
<<
id
<<
std
::
endl
;
out
<<
ts
<<
": N.DMAC id="
<<
id
<<
std
::
endl
;
}
}
};
};
class
e_nic_mmio_r
:
public
event
{
class
e_nic_mmio_r
:
public
event
{
public:
public:
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
uint64_t
val
;
uint64_t
val
;
e_nic_mmio_r
(
uint64_t
ts_
,
uint64_t
addr_
,
uint64_t
size_
,
uint64_t
val_
)
e_nic_mmio_r
(
uint64_t
ts_
,
uint64_t
addr_
,
uint64_t
size_
,
uint64_t
val_
)
:
event
(
ts_
),
addr
(
addr_
),
size
(
size_
),
val
(
val_
)
:
event
(
ts_
),
addr
(
addr_
),
size
(
size_
),
val
(
val_
)
{
{
}
}
virtual
~
e_nic_mmio_r
()
{
virtual
~
e_nic_mmio_r
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.MMIOR addr="
<<
addr
<<
" size="
<<
size
<<
" val="
<<
val
out
<<
ts
<<
": N.MMIOR addr="
<<
addr
<<
" size="
<<
size
<<
" val="
<<
<<
std
::
endl
;
val
<<
std
::
endl
;
}
}
};
};
class
e_nic_mmio_w
:
public
event
{
class
e_nic_mmio_w
:
public
event
{
public:
public:
uint64_t
addr
;
uint64_t
addr
;
uint64_t
size
;
uint64_t
size
;
uint64_t
val
;
uint64_t
val
;
e_nic_mmio_w
(
uint64_t
ts_
,
uint64_t
addr_
,
uint64_t
size_
,
uint64_t
val_
)
e_nic_mmio_w
(
uint64_t
ts_
,
uint64_t
addr_
,
uint64_t
size_
,
uint64_t
val_
)
:
event
(
ts_
),
addr
(
addr_
),
size
(
size_
),
val
(
val_
)
:
event
(
ts_
),
addr
(
addr_
),
size
(
size_
),
val
(
val_
)
{
{
}
}
virtual
~
e_nic_mmio_w
()
{
virtual
~
e_nic_mmio_w
()
{
}
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.MMIOW addr="
<<
addr
<<
" size="
<<
size
<<
" val="
<<
val
out
<<
ts
<<
": N.MMIOW addr="
<<
addr
<<
" size="
<<
size
<<
" val="
<<
<<
std
::
endl
;
val
<<
std
::
endl
;
}
}
};
};
class
e_nic_tx
:
public
event
{
class
e_nic_tx
:
public
event
{
public:
public:
uint16_t
len
;
uint16_t
len
;
e_nic_tx
(
uint64_t
ts_
,
uint16_t
len_
)
e_nic_tx
(
uint64_t
ts_
,
uint16_t
len_
)
:
event
(
ts_
),
len
(
len_
)
{
:
event
(
ts_
),
len
(
len_
)
}
{
}
virtual
~
e_nic_tx
()
{
}
virtual
~
e_nic_tx
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.TX "
<<
len
<<
std
::
endl
;
out
<<
ts
<<
": N.TX "
<<
len
<<
std
::
endl
;
}
}
};
};
class
e_nic_rx
:
public
event
{
class
e_nic_rx
:
public
event
{
public:
public:
uint16_t
len
;
uint16_t
len
;
e_nic_rx
(
uint64_t
ts_
,
uint16_t
len_
)
e_nic_rx
(
uint64_t
ts_
,
uint16_t
len_
)
:
event
(
ts_
),
len
(
len_
)
{
:
event
(
ts_
),
len
(
len_
)
}
{
}
virtual
~
e_nic_rx
()
{
}
virtual
~
e_nic_rx
()
{
}
virtual
void
dump
(
std
::
ostream
&
out
)
virtual
void
dump
(
std
::
ostream
&
out
)
{
{
out
<<
ts
<<
": N.RX "
<<
len
<<
std
::
endl
;
out
<<
ts
<<
": N.RX "
<<
len
<<
std
::
endl
;
}
}
};
};
trace/gem5.cc
View file @
d4666c97
...
@@ -30,160 +30,154 @@
...
@@ -30,160 +30,154 @@
namespace
bio
=
boost
::
iostreams
;
namespace
bio
=
boost
::
iostreams
;
gem5_parser
::
gem5_parser
(
sym_map
&
syms_
)
gem5_parser
::
gem5_parser
(
sym_map
&
syms_
)
:
syms
(
syms_
)
{
:
syms
(
syms_
)
{
}
}
gem5_parser
::~
gem5_parser
()
gem5_parser
::~
gem5_parser
()
{
{
}
}
void
gem5_parser
::
process_msg
(
uint64_t
ts
,
char
*
comp_name
,
void
gem5_parser
::
process_msg
(
uint64_t
ts
,
char
*
comp_name
,
size_t
comp_name_len
,
char
*
msg
,
size_t
msg_len
)
size_t
comp_name_len
,
char
*
msg
,
size_t
msg_len
)
{
{
parser
p
(
msg
,
msg_len
,
0
);
parser
p
(
msg
,
msg_len
,
0
);
/*if (ts < ts_first)
return;*/
if
(
comp_name_len
==
18
&&
!
memcmp
(
comp_name
,
"system.switch_cpus"
,
18
))
{
// cpu_lines++;
if
(
!
p
.
consume_str
(
"T0 : 0x"
))
return
;
uint64_t
addr
;
if
(
!
p
.
consume_hex
(
addr
)
||
p
.
consume_char
(
'.'
))
return
;
if
(
const
std
::
string
*
s
=
syms
.
lookup
(
addr
))
{
cur_event
=
new
EHostCall
(
ts
,
*
s
);
}
}
else
if
(
comp_name_len
==
18
&&
!
memcmp
(
comp_name
,
"system.pc.ethernet"
,
18
))
{
// eth_lines++;
/*std::cout.write(msg, msg_len);
std::cout << std::endl;*/
if
(
!
p
.
consume_str
(
"cosim: "
))
return
;
uint64_t
id
=
0
;
uint64_t
addr
=
0
;
uint64_t
size
=
0
;
if
(
p
.
consume_str
(
"received "
))
{
if
(
p
.
consume_str
(
"MSI-X intr vec "
)
&&
p
.
consume_dec
(
id
))
{
cur_event
=
new
EHostMsiX
(
ts
,
id
);
}
else
if
(
p
.
consume_str
(
"DMA read id "
)
&&
p
.
consume_dec
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
))
{
// cosim: received DMA read id 94113551511792 addr 23697ad60
// size 20
cur_event
=
new
EHostDmaR
(
ts
,
id
,
addr
,
size
);
}
else
if
(
p
.
consume_str
(
"DMA write id "
)
&&
p
.
consume_dec
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
))
{
// cosim: received DMA write id 94113551528032 addr 236972000
// size 4
cur_event
=
new
EHostDmaW
(
ts
,
id
,
addr
,
size
);
}
else
if
(
p
.
consume_str
(
"read completion id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: received read completion id 94583743418112
cur_event
=
new
EHostMmioC
(
ts
,
id
);
}
else
if
(
p
.
consume_str
(
"write completion id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: received write completion id 94583743418736
cur_event
=
new
EHostMmioC
(
ts
,
id
);
}
}
else
if
(
p
.
consume_str
(
"sending "
))
{
if
(
p
.
consume_str
(
"read addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
)
&&
p
.
consume_str
(
" id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: sending read addr c012a500 size 4 id 94583743418112
cur_event
=
new
EHostMmioR
(
ts
,
id
,
addr
,
size
);
}
else
if
(
p
.
consume_str
(
"write addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
)
&&
p
.
consume_str
(
" id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: sending write addr c0108000 size 4 id 94584005188256
cur_event
=
new
EHostMmioW
(
ts
,
id
,
addr
,
size
);
}
}
else
if
(
p
.
consume_str
(
"completed DMA id "
)
&&
p
.
consume_dec
(
id
))
{
cur_event
=
new
EHostDmaC
(
ts
,
id
);
}
}
/*if (!cur_event) {
std::cout.write(msg, msg_len);
std::cout << std::endl;
}*/
}
/*if (ts < ts_first)
return;*/
void
gem5_parser
::
process_line
(
char
*
line
,
size_t
line_len
)
if
(
comp_name_len
==
18
&&
!
memcmp
(
comp_name
,
"system.switch_cpus"
,
18
))
{
{
// cpu_lines++;
size_t
pos
=
0
;
if
(
!
p
.
consume_str
(
"T0 : 0x"
))
return
;
size_t
line_start
=
pos
;
uint64_t
addr
;
size_t
comp_name_start
=
0
;
if
(
!
p
.
consume_hex
(
addr
)
||
p
.
consume_char
(
'.'
))
size_t
comp_name_len
=
0
;
return
;
bool
valid
=
true
;
// eat spaces
if
(
const
std
::
string
*
s
=
syms
.
lookup
(
addr
))
{
for
(;
pos
<
line_len
&&
line
[
pos
]
==
' '
;
pos
++
)
{}
cur_event
=
new
EHostCall
(
ts
,
*
s
);
// parse ts
uint64_t
ts
=
0
;
size_t
ts_len
=
0
;
for
(;
pos
<
line_len
&&
line
[
pos
]
>=
'0'
&&
line
[
pos
]
<=
'9'
;
pos
++
)
{
ts
=
ts
*
10
+
line
[
pos
]
-
'0'
;
ts_len
++
;
}
}
if
(
ts_len
==
0
)
{
}
else
if
(
comp_name_len
==
18
&&
valid
=
false
;
!
memcmp
(
comp_name
,
"system.pc.ethernet"
,
18
))
{
goto
out
;
// eth_lines++;
/*std::cout.write(msg, msg_len);
std::cout << std::endl;*/
if
(
!
p
.
consume_str
(
"cosim: "
))
return
;
uint64_t
id
=
0
;
uint64_t
addr
=
0
;
uint64_t
size
=
0
;
if
(
p
.
consume_str
(
"received "
))
{
if
(
p
.
consume_str
(
"MSI-X intr vec "
)
&&
p
.
consume_dec
(
id
))
{
cur_event
=
new
EHostMsiX
(
ts
,
id
);
}
else
if
(
p
.
consume_str
(
"DMA read id "
)
&&
p
.
consume_dec
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
))
{
// cosim: received DMA read id 94113551511792 addr 23697ad60
// size 20
cur_event
=
new
EHostDmaR
(
ts
,
id
,
addr
,
size
);
}
else
if
(
p
.
consume_str
(
"DMA write id "
)
&&
p
.
consume_dec
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
))
{
// cosim: received DMA write id 94113551528032 addr 236972000
// size 4
cur_event
=
new
EHostDmaW
(
ts
,
id
,
addr
,
size
);
}
else
if
(
p
.
consume_str
(
"read completion id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: received read completion id 94583743418112
cur_event
=
new
EHostMmioC
(
ts
,
id
);
}
else
if
(
p
.
consume_str
(
"write completion id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: received write completion id 94583743418736
cur_event
=
new
EHostMmioC
(
ts
,
id
);
}
}
else
if
(
p
.
consume_str
(
"sending "
))
{
if
(
p
.
consume_str
(
"read addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
)
&&
p
.
consume_str
(
" id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: sending read addr c012a500 size 4 id 94583743418112
cur_event
=
new
EHostMmioR
(
ts
,
id
,
addr
,
size
);
}
else
if
(
p
.
consume_str
(
"write addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" size "
)
&&
p
.
consume_dec
(
size
)
&&
p
.
consume_str
(
" id "
)
&&
p
.
consume_dec
(
id
))
{
// cosim: sending write addr c0108000 size 4 id 94584005188256
cur_event
=
new
EHostMmioW
(
ts
,
id
,
addr
,
size
);
}
}
else
if
(
p
.
consume_str
(
"completed DMA id "
)
&&
p
.
consume_dec
(
id
))
{
cur_event
=
new
EHostDmaC
(
ts
,
id
);
}
}
}
// skip colon
/*if (!cur_event) {
if
(
line
[
pos
]
!=
':'
)
{
std::cout.write(msg, msg_len);
valid
=
false
;
std::cout << std::endl;
goto
out
;
}*/
}
}
pos
++
;
// skip space
void
gem5_parser
::
process_line
(
char
*
line
,
size_t
line_len
)
{
if
(
line
[
pos
]
!=
' '
)
{
size_t
pos
=
0
;
valid
=
false
;
goto
out
;
size_t
line_start
=
pos
;
}
size_t
comp_name_start
=
0
;
pos
++
;
size_t
comp_name_len
=
0
;
bool
valid
=
true
;
comp_name_start
=
pos
;
for
(;
pos
<
line_len
&&
line
[
pos
]
!=
' '
&&
line
[
pos
]
!=
'\n'
;
pos
++
,
// eat spaces
comp_name_len
++
)
{}
for
(;
pos
<
line_len
&&
line
[
pos
]
==
' '
;
pos
++
)
{
// skip space
}
if
(
line
[
pos
]
!=
' '
)
{
valid
=
false
;
// parse ts
goto
out
;
uint64_t
ts
=
0
;
}
size_t
ts_len
=
0
;
if
(
line
[
pos
-
1
]
!=
':'
)
{
for
(;
pos
<
line_len
&&
line
[
pos
]
>=
'0'
&&
line
[
pos
]
<=
'9'
;
pos
++
)
{
valid
=
false
;
ts
=
ts
*
10
+
line
[
pos
]
-
'0'
;
goto
out
;
ts_len
++
;
}
}
comp_name_len
--
;
if
(
ts_len
==
0
)
{
pos
++
;
valid
=
false
;
goto
out
;
}
// skip colon
if
(
line
[
pos
]
!=
':'
)
{
valid
=
false
;
goto
out
;
}
pos
++
;
// skip space
if
(
line
[
pos
]
!=
' '
)
{
valid
=
false
;
goto
out
;
}
pos
++
;
comp_name_start
=
pos
;
for
(;
pos
<
line_len
&&
line
[
pos
]
!=
' '
&&
line
[
pos
]
!=
'\n'
;
pos
++
,
comp_name_len
++
)
{
}
// skip space
if
(
line
[
pos
]
!=
' '
)
{
valid
=
false
;
goto
out
;
}
if
(
line
[
pos
-
1
]
!=
':'
)
{
valid
=
false
;
goto
out
;
}
comp_name_len
--
;
pos
++
;
out:
out:
size_t
msg_start
=
pos
;
size_t
msg_start
=
pos
;
size_t
msg_len
=
line_len
-
msg_start
;
size_t
msg_len
=
line_len
-
msg_start
;
line
[
line_len
-
1
]
=
0
;
line
[
line_len
-
1
]
=
0
;
if
(
valid
)
{
if
(
valid
)
{
process_msg
(
ts
,
line
+
comp_name_start
,
comp_name_len
,
line
+
msg_start
,
process_msg
(
ts
,
line
+
comp_name_start
,
comp_name_len
,
line
+
msg_start
,
msg_len
);
msg_len
);
}
else
{
}
else
{
std
::
cout
<<
line
+
line_start
<<
std
::
endl
;
std
::
cout
<<
line
+
line_start
<<
std
::
endl
;
std
::
cout
<<
pos
<<
std
::
endl
;
std
::
cout
<<
pos
<<
std
::
endl
;
}
}
return
;
return
;
}
}
trace/log_parser.cc
View file @
d4666c97
...
@@ -22,10 +22,10 @@
...
@@ -22,10 +22,10 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
*/
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <fstream>
#include <fstream>
#include <iostream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include "trace/events.h"
#include "trace/events.h"
#include "trace/parser.h"
#include "trace/parser.h"
...
@@ -33,100 +33,91 @@
...
@@ -33,100 +33,91 @@
namespace
bio
=
boost
::
iostreams
;
namespace
bio
=
boost
::
iostreams
;
log_parser
::
log_parser
()
log_parser
::
log_parser
()
:
inf
(
nullptr
),
gz_file
(
nullptr
),
gz_in
(
nullptr
)
{
:
inf
(
nullptr
),
gz_file
(
nullptr
),
gz_in
(
nullptr
)
buf
=
new
char
[
block_size
];
{
buf
=
new
char
[
block_size
];
}
}
log_parser
::~
log_parser
()
log_parser
::~
log_parser
()
{
{
if
(
inf
)
if
(
inf
)
delete
inf
;
delete
inf
;
if
(
gz_file
)
{
if
(
gz_file
)
{
delete
gz_in
;
delete
gz_in
;
delete
gz_file
;
delete
gz_file
;
}
}
delete
[]
buf
;
delete
[]
buf
;
}
}
bool
log_parser
::
next_block
()
bool
log_parser
::
next_block
()
{
{
if
(
buf_pos
==
buf_len
)
{
if
(
buf_pos
==
buf_len
)
{
buf_pos
=
0
;
buf_pos
=
0
;
}
else
{
}
else
{
memmove
(
buf
,
buf
+
buf_pos
,
buf_len
-
buf_pos
);
memmove
(
buf
,
buf
+
buf_pos
,
buf_len
-
buf_pos
);
buf_pos
=
buf_len
-
buf_pos
;
buf_pos
=
buf_len
-
buf_pos
;
}
}
inf
->
read
(
buf
+
buf_pos
,
block_size
-
buf_pos
);
inf
->
read
(
buf
+
buf_pos
,
block_size
-
buf_pos
);
size_t
newlen
=
inf
->
gcount
();
size_t
newlen
=
inf
->
gcount
();
buf_len
=
buf_pos
+
newlen
;
buf_len
=
buf_pos
+
newlen
;
buf_pos
=
0
;
buf_pos
=
0
;
return
newlen
!=
0
;
return
newlen
!=
0
;
}
}
void
log_parser
::
open
(
const
char
*
path
)
void
log_parser
::
open
(
const
char
*
path
)
{
{
inf
=
new
std
::
ifstream
(
path
,
std
::
ios_base
::
in
);
inf
=
new
std
::
ifstream
(
path
,
std
::
ios_base
::
in
);
}
}
void
log_parser
::
open_gz
(
const
char
*
path
)
void
log_parser
::
open_gz
(
const
char
*
path
)
{
{
gz_file
=
new
std
::
ifstream
(
path
,
std
::
ios_base
::
in
|
std
::
ios_base
::
binary
);
gz_file
=
new
std
::
ifstream
(
path
,
std
::
ios_base
::
in
|
gz_in
=
new
bio
::
filtering_streambuf
<
bio
::
input
>
();
std
::
ios_base
::
binary
);
gz_in
=
new
bio
::
filtering_streambuf
<
bio
::
input
>
();
gz_in
->
push
(
bio
::
gzip_decompressor
());
gz_in
->
push
(
bio
::
gzip_decompressor
());
gz_in
->
push
(
*
gz_file
);
gz_in
->
push
(
*
gz_file
);
inf
=
new
std
::
istream
(
gz_in
);
inf
=
new
std
::
istream
(
gz_in
);
}
}
size_t
log_parser
::
try_line
()
size_t
log_parser
::
try_line
()
{
{
size_t
pos
=
buf_pos
;
size_t
pos
=
buf_pos
;
size_t
line_len
=
0
;
size_t
line_len
=
0
;
for
(;
pos
<
buf_len
&&
buf
[
pos
]
!=
'\n'
;
pos
++
,
line_len
++
)
{}
for
(;
pos
<
buf_len
&&
buf
[
pos
]
!=
'\n'
;
pos
++
,
line_len
++
)
{
if
(
pos
>=
buf_len
)
{
}
// line is incomplete
if
(
pos
>=
buf_len
)
{
return
0
;
// line is incomplete
}
return
0
;
}
process_line
(
buf
+
buf_pos
,
line_len
);
process_line
(
buf
+
buf_pos
,
line_len
);
return
pos
+
1
;
return
pos
+
1
;
}
}
bool
log_parser
::
next_event
()
{
cur_event
=
nullptr
;
bool
log_parser
::
next_event
()
if
(
buf_len
==
0
&&
!
next_block
())
{
{
std
::
cerr
<<
"escape 0"
<<
std
::
endl
;
cur_event
=
nullptr
;
return
false
;
}
do
{
size_t
newpos
=
try_line
();
if
(
!
newpos
)
{
if
(
!
next_block
())
{
std
::
cerr
<<
"escape 1"
<<
std
::
endl
;
return
false
;
}
if
(
buf_len
==
0
&&
!
next_block
())
{
newpos
=
try_line
();
std
::
cerr
<<
"escape 0"
<<
std
::
endl
;
if
(
!
newpos
)
{
std
::
cerr
<<
"escape 2"
<<
std
::
endl
;
return
false
;
return
false
;
}
}
}
buf_pos
=
newpos
;
}
while
(
!
cur_event
);
do
{
return
true
;
size_t
newpos
=
try_line
();
if
(
!
newpos
)
{
if
(
!
next_block
())
{
std
::
cerr
<<
"escape 1"
<<
std
::
endl
;
return
false
;
}
newpos
=
try_line
();
if
(
!
newpos
)
{
std
::
cerr
<<
"escape 2"
<<
std
::
endl
;
return
false
;
}
}
buf_pos
=
newpos
;
}
while
(
!
cur_event
);
return
true
;
}
}
trace/nicbm.cc
View file @
d4666c97
...
@@ -30,77 +30,59 @@
...
@@ -30,77 +30,59 @@
namespace
bio
=
boost
::
iostreams
;
namespace
bio
=
boost
::
iostreams
;
nicbm_parser
::~
nicbm_parser
()
nicbm_parser
::~
nicbm_parser
()
{
{
}
}
void
nicbm_parser
::
process_line
(
char
*
line
,
size_t
line_len
)
void
nicbm_parser
::
process_line
(
char
*
line
,
size_t
line_len
)
{
{
parser
p
(
line
,
line_len
,
0
);
parser
p
(
line
,
line_len
,
0
);
uint64_t
ts
;
uint64_t
ts
;
if
(
!
p
.
consume_dec
(
ts
))
if
(
!
p
.
consume_dec
(
ts
))
return
;
return
;
if
(
!
p
.
consume_str
(
" nicbm: "
))
if
(
!
p
.
consume_str
(
" nicbm: "
))
return
;
return
;
uint64_t
id
,
addr
,
len
,
val
;
uint64_t
id
,
addr
,
len
,
val
;
if
(
p
.
consume_str
(
"read(off=0x"
))
{
if
(
p
.
consume_str
(
"read(off=0x"
))
{
if
(
p
.
consume_hex
(
addr
)
&&
if
(
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
", len="
)
&&
p
.
consume_dec
(
len
)
&&
p
.
consume_str
(
", len="
)
&&
p
.
consume_str
(
", val=0x"
)
&&
p
.
consume_hex
(
val
))
{
p
.
consume_dec
(
len
)
&&
cur_event
=
new
e_nic_mmio_r
(
ts
,
addr
,
len
,
val
);
p
.
consume_str
(
", val=0x"
)
&&
p
.
consume_hex
(
val
))
{
cur_event
=
new
e_nic_mmio_r
(
ts
,
addr
,
len
,
val
);
}
}
else
if
(
p
.
consume_str
(
"write(off=0x"
))
{
if
(
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
", len="
)
&&
p
.
consume_dec
(
len
)
&&
p
.
consume_str
(
", val=0x"
)
&&
p
.
consume_hex
(
val
))
{
cur_event
=
new
e_nic_mmio_w
(
ts
,
addr
,
len
,
val
);
}
}
else
if
(
p
.
consume_str
(
"issuing dma op 0x"
))
{
if
(
p
.
consume_hex
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" len "
)
&&
p
.
consume_hex
(
len
))
{
cur_event
=
new
e_nic_dma_i
(
ts
,
id
,
addr
,
len
);
}
}
else
if
(
p
.
consume_str
(
"completed dma read op 0x"
)
||
p
.
consume_str
(
"completed dma write op 0x"
))
{
if
(
p
.
consume_hex
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" len "
)
&&
p
.
consume_hex
(
len
))
{
cur_event
=
new
e_nic_dma_c
(
ts
,
id
);
}
}
else
if
(
p
.
consume_str
(
"issue MSI-X interrupt vec "
))
{
if
(
p
.
consume_dec
(
id
))
{
cur_event
=
new
e_nic_msix
(
ts
,
id
);
}
}
else
if
(
p
.
consume_str
(
"eth tx: len "
))
{
if
(
p
.
consume_dec
(
len
))
{
cur_event
=
new
e_nic_tx
(
ts
,
len
);
}
}
else
if
(
p
.
consume_str
(
"eth rx: port 0 len "
))
{
if
(
p
.
consume_dec
(
len
))
{
cur_event
=
new
e_nic_rx
(
ts
,
len
);
}
#if 1
}
}
#else
}
else
if
(
p
.
consume_str
(
"write(off=0x"
))
{
}
else
{
if
(
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
", len="
)
&&
p
.
consume_dec
(
len
)
&&
std
::
cerr
.
write
(
line
,
line_len
);
p
.
consume_str
(
", val=0x"
)
&&
p
.
consume_hex
(
val
))
{
std
::
cerr
<<
std
::
endl
;
cur_event
=
new
e_nic_mmio_w
(
ts
,
addr
,
len
,
val
);
}
}
else
if
(
p
.
consume_str
(
"issuing dma op 0x"
))
{
if
(
p
.
consume_hex
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" len "
)
&&
p
.
consume_hex
(
len
))
{
cur_event
=
new
e_nic_dma_i
(
ts
,
id
,
addr
,
len
);
}
}
else
if
(
p
.
consume_str
(
"completed dma read op 0x"
)
||
p
.
consume_str
(
"completed dma write op 0x"
))
{
if
(
p
.
consume_hex
(
id
)
&&
p
.
consume_str
(
" addr "
)
&&
p
.
consume_hex
(
addr
)
&&
p
.
consume_str
(
" len "
)
&&
p
.
consume_hex
(
len
))
{
cur_event
=
new
e_nic_dma_c
(
ts
,
id
);
}
}
else
if
(
p
.
consume_str
(
"issue MSI-X interrupt vec "
))
{
if
(
p
.
consume_dec
(
id
))
{
cur_event
=
new
e_nic_msix
(
ts
,
id
);
}
}
}
else
if
(
p
.
consume_str
(
"eth tx: len "
))
{
if
(
p
.
consume_dec
(
len
))
{
cur_event
=
new
e_nic_tx
(
ts
,
len
);
}
}
else
if
(
p
.
consume_str
(
"eth rx: port 0 len "
))
{
if
(
p
.
consume_dec
(
len
))
{
cur_event
=
new
e_nic_rx
(
ts
,
len
);
}
#if 1
}
#else
}
else
{
std
::
cerr
.
write
(
line
,
line_len
);
std
::
cerr
<<
std
::
endl
;
}
#endif
#endif
}
}
trace/parser.h
View file @
d4666c97
...
@@ -29,94 +29,89 @@
...
@@ -29,94 +29,89 @@
#include <string>
#include <string>
class
parser
{
class
parser
{
protected:
protected:
const
char
*
buf
;
const
char
*
buf
;
size_t
buf_len
;
size_t
buf_len
;
size_t
pos
;
size_t
pos
;
public:
public:
parser
(
const
char
*
buf_
,
size_t
buf_len_
,
size_t
start_pos
=
0
)
parser
(
const
char
*
buf_
,
size_t
buf_len_
,
size_t
start_pos
=
0
)
:
buf
(
buf_
),
buf_len
(
buf_len_
),
pos
(
start_pos
)
:
buf
(
buf_
),
buf_len
(
buf_len_
),
pos
(
start_pos
)
{
{
}
inline
size_t
trim_spaces
()
{
size_t
cnt
=
0
;
for
(;
pos
<
buf_len
&&
buf
[
pos
]
==
' '
;
pos
++
,
cnt
++
)
{
}
}
return
cnt
;
}
inline
size_t
trim_spaces
()
inline
bool
consume_char
(
char
c
)
{
{
if
(
pos
==
buf_len
||
buf
[
pos
]
!=
c
)
{
size_t
cnt
=
0
;
return
false
;
for
(;
pos
<
buf_len
&&
buf
[
pos
]
==
' '
;
pos
++
,
cnt
++
)
{}
return
cnt
;
}
}
inline
bool
consume_char
(
char
c
)
pos
++
;
{
return
true
;
if
(
pos
==
buf_len
||
buf
[
pos
]
!=
c
)
{
}
return
false
;
}
inline
bool
consume_hex
(
uint64_t
&
val
)
{
size_t
val_len
=
0
;
pos
++
;
val
=
0
;
return
true
;
for
(;
pos
<
buf_len
;
pos
++
)
{
}
char
d
=
buf
[
pos
];
bool
is_d
=
d
>=
'0'
&&
d
<=
'9'
;
inline
bool
consume_hex
(
uint64_t
&
val
)
bool
is_x
=
d
>=
'a'
&&
d
<=
'f'
;
{
size_t
val_len
=
0
;
if
(
!
is_d
&&
!
is_x
)
val
=
0
;
break
;
for
(;
pos
<
buf_len
;
pos
++
)
{
char
d
=
buf
[
pos
];
val
<<=
4
;
bool
is_d
=
d
>=
'0'
&&
d
<=
'9'
;
if
(
is_d
)
bool
is_x
=
d
>=
'a'
&&
d
<=
'f'
;
val
|=
d
-
'0'
;
else
if
(
!
is_d
&&
!
is_x
)
val
|=
d
-
'a'
+
10
;
break
;
val_len
++
;
val
<<=
4
;
if
(
is_d
)
val
|=
d
-
'0'
;
else
val
|=
d
-
'a'
+
10
;
val_len
++
;
}
return
val_len
>
0
;
}
}
inline
bool
consume_dec
(
uint64_t
&
val
)
return
val_len
>
0
;
{
}
size_t
val_len
=
0
;
val
=
0
;
for
(;
pos
<
buf_len
;
pos
++
)
{
char
d
=
buf
[
pos
];
if
(
d
<
'0'
||
d
>
'9'
)
break
;
val
=
val
*
10
+
(
d
-
'0'
);
inline
bool
consume_dec
(
uint64_t
&
val
)
{
val_len
++
;
size_t
val_len
=
0
;
}
val
=
0
;
for
(;
pos
<
buf_len
;
pos
++
)
{
char
d
=
buf
[
pos
];
if
(
d
<
'0'
||
d
>
'9'
)
break
;
return
val_len
>
0
;
val
=
val
*
10
+
(
d
-
'0'
);
val_len
++
;
}
}
inline
bool
consume_str
(
const
char
*
str
)
return
val_len
>
0
;
{
}
size_t
str_len
=
strlen
(
str
);
if
(
pos
+
str_len
>
buf_len
||
memcmp
(
buf
+
pos
,
str
,
str_len
))
{
return
false
;
}
pos
+=
str_len
;
inline
bool
consume_str
(
const
char
*
str
)
{
return
true
;
size_t
str_len
=
strlen
(
str
);
if
(
pos
+
str_len
>
buf_len
||
memcmp
(
buf
+
pos
,
str
,
str_len
))
{
return
false
;
}
}
inline
bool
extract_until
(
char
end_c
,
std
::
string
&
str
)
pos
+=
str_len
;
{
return
true
;
size_t
end
=
pos
;
}
for
(;
end
<
buf_len
&&
buf
[
end
]
!=
end_c
;
end
++
)
{}
if
(
end
>=
buf_len
)
inline
bool
extract_until
(
char
end_c
,
std
::
string
&
str
)
{
return
false
;
size_t
end
=
pos
;
for
(;
end
<
buf_len
&&
buf
[
end
]
!=
end_c
;
end
++
)
{
str
.
assign
(
buf
+
pos
,
end
-
pos
);
pos
=
end
+
1
;
return
true
;
}
}
if
(
end
>=
buf_len
)
return
false
;
str
.
assign
(
buf
+
pos
,
end
-
pos
);
pos
=
end
+
1
;
return
true
;
}
};
};
trace/process.cc
View file @
d4666c97
...
@@ -22,89 +22,88 @@
...
@@ -22,89 +22,88 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
*/
#include "trace/process.h"
#include <iostream>
#include <iostream>
#include "trace/events.h"
#include "trace/events.h"
#include "trace/parser.h"
#include "trace/parser.h"
#include "trace/process.h"
struct
log_parser_cmp
{
struct
log_parser_cmp
{
bool
operator
()
(
const
log_parser
*
l
,
const
log_parser
*
r
)
const
{
bool
operator
()(
const
log_parser
*
l
,
const
log_parser
*
r
)
const
{
return
l
->
cur_event
->
ts
<
r
->
cur_event
->
ts
;
return
l
->
cur_event
->
ts
<
r
->
cur_event
->
ts
;
}
}
};
};
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
sym_map
syms
;
sym_map
syms
;
syms
.
add_filter
(
"entry_SYSCALL_64"
);
syms
.
add_filter
(
"entry_SYSCALL_64"
);
syms
.
add_filter
(
"__do_sys_gettimeofday"
);
syms
.
add_filter
(
"__do_sys_gettimeofday"
);
syms
.
add_filter
(
"__sys_sendto"
);
syms
.
add_filter
(
"__sys_sendto"
);
syms
.
add_filter
(
"i40e_lan_xmit_frame"
);
syms
.
add_filter
(
"i40e_lan_xmit_frame"
);
syms
.
add_filter
(
"syscall_return_via_sysret"
);
syms
.
add_filter
(
"syscall_return_via_sysret"
);
syms
.
add_filter
(
"__sys_recvfrom"
);
syms
.
add_filter
(
"__sys_recvfrom"
);
syms
.
add_filter
(
"deactivate_task"
);
syms
.
add_filter
(
"deactivate_task"
);
syms
.
add_filter
(
"interrupt_entry"
);
syms
.
add_filter
(
"interrupt_entry"
);
syms
.
add_filter
(
"i40e_msix_clean_rings"
);
syms
.
add_filter
(
"i40e_msix_clean_rings"
);
syms
.
add_filter
(
"napi_schedule_prep"
);
syms
.
add_filter
(
"napi_schedule_prep"
);
syms
.
add_filter
(
"__do_softirq"
);
syms
.
add_filter
(
"__do_softirq"
);
syms
.
add_filter
(
"trace_napi_poll"
);
syms
.
add_filter
(
"trace_napi_poll"
);
syms
.
add_filter
(
"net_rx_action"
);
syms
.
add_filter
(
"net_rx_action"
);
syms
.
add_filter
(
"i40e_napi_poll"
);
syms
.
add_filter
(
"i40e_napi_poll"
);
syms
.
add_filter
(
"activate_task"
);
syms
.
add_filter
(
"activate_task"
);
syms
.
add_filter
(
"copyout"
);
syms
.
add_filter
(
"copyout"
);
syms
.
load_file
(
"linux.dump"
,
0
);
syms
.
load_file
(
"linux.dump"
,
0
);
syms
.
load_file
(
"i40e.dump"
,
0xffffffffa0000000ULL
);
syms
.
load_file
(
"i40e.dump"
,
0xffffffffa0000000ULL
);
std
::
cerr
<<
"map loaded"
<<
std
::
endl
;
std
::
cerr
<<
"map loaded"
<<
std
::
endl
;
std
::
set
<
log_parser
*>
all_parsers
;
std
::
set
<
log_parser
*>
all_parsers
;
gem5_parser
ch
(
syms
);
gem5_parser
ch
(
syms
);
gem5_parser
sh
(
syms
);
gem5_parser
sh
(
syms
);
nicbm_parser
cn
;
nicbm_parser
cn
;
nicbm_parser
sn
;
nicbm_parser
sn
;
ch
.
open
(
argv
[
1
]);
ch
.
open
(
argv
[
1
]);
cn
.
open
(
argv
[
2
]);
cn
.
open
(
argv
[
2
]);
sh
.
open
(
argv
[
3
]);
sh
.
open
(
argv
[
3
]);
sn
.
open
(
argv
[
4
]);
sn
.
open
(
argv
[
4
]);
ch
.
label
=
cn
.
label
=
"C"
;
ch
.
label
=
cn
.
label
=
"C"
;
sh
.
label
=
sn
.
label
=
"S"
;
sh
.
label
=
sn
.
label
=
"S"
;
all_parsers
.
insert
(
&
ch
);
all_parsers
.
insert
(
&
ch
);
all_parsers
.
insert
(
&
cn
);
all_parsers
.
insert
(
&
cn
);
all_parsers
.
insert
(
&
sh
);
all_parsers
.
insert
(
&
sh
);
all_parsers
.
insert
(
&
sn
);
all_parsers
.
insert
(
&
sn
);
std
::
set
<
log_parser
*
,
log_parser_cmp
>
active_parsers
;
std
::
set
<
log_parser
*
,
log_parser_cmp
>
active_parsers
;
for
(
auto
p
:
all_parsers
)
{
for
(
auto
p
:
all_parsers
)
{
if
(
p
->
next_event
()
&&
p
->
cur_event
)
if
(
p
->
next_event
()
&&
p
->
cur_event
)
active_parsers
.
insert
(
p
);
active_parsers
.
insert
(
p
);
}
}
uint64_t
ts_off
=
0
;
uint64_t
ts_off
=
0
;
while
(
!
active_parsers
.
empty
())
{
while
(
!
active_parsers
.
empty
())
{
auto
i
=
active_parsers
.
begin
();
auto
i
=
active_parsers
.
begin
();
log_parser
*
p
=
*
i
;
log_parser
*
p
=
*
i
;
active_parsers
.
erase
(
i
);
active_parsers
.
erase
(
i
);
EHostCall
*
hc
;
EHostCall
*
hc
;
event
*
ev
=
p
->
cur_event
;
event
*
ev
=
p
->
cur_event
;
if
(
p
==
&
ch
&&
(
hc
=
dynamic_cast
<
EHostCall
*>
(
ev
))
&&
if
(
p
==
&
ch
&&
(
hc
=
dynamic_cast
<
EHostCall
*>
(
ev
))
&&
hc
->
fun
==
"__sys_sendto"
)
hc
->
fun
==
"__sys_sendto"
)
{
{
std
::
cout
<<
"---------- REQ START:"
<<
ev
->
ts
<<
std
::
endl
;
std
::
cout
<<
"---------- REQ START:"
<<
ev
->
ts
<<
std
::
endl
;
ts_off
=
ev
->
ts
;
ts_off
=
ev
->
ts
;
}
}
std
::
cout
<<
p
->
label
<<
" "
;
std
::
cout
<<
p
->
label
<<
" "
;
ev
->
ts
-=
ts_off
;
ev
->
ts
-=
ts_off
;
ev
->
ts
/=
1000
;
ev
->
ts
/=
1000
;
ev
->
dump
(
std
::
cout
);
ev
->
dump
(
std
::
cout
);
delete
ev
;
delete
ev
;
if
(
p
->
next_event
()
&&
p
->
cur_event
)
if
(
p
->
next_event
()
&&
p
->
cur_event
)
active_parsers
.
insert
(
p
);
active_parsers
.
insert
(
p
);
}
}
}
}
trace/process.h
View file @
d4666c97
...
@@ -24,83 +24,82 @@
...
@@ -24,83 +24,82 @@
#pragma once
#pragma once
#include <boost/iostreams/filtering_streambuf.hpp>
#include <map>
#include <map>
#include <set>
#include <set>
#include <string>
#include <string>
#include <boost/iostreams/filtering_streambuf.hpp>
#include "trace/events.h"
#include "trace/events.h"
class
sym_map
{
class
sym_map
{
protected:
protected:
bool
filter_en
;
bool
filter_en
;
bool
insmap_en
;
bool
insmap_en
;
std
::
set
<
std
::
string
>
filter
;
std
::
set
<
std
::
string
>
filter
;
public:
public:
std
::
map
<
uint64_t
,
std
::
string
>
map
;
std
::
map
<
uint64_t
,
std
::
string
>
map
;
std
::
map
<
uint64_t
,
std
::
string
>
map_ins
;
std
::
map
<
uint64_t
,
std
::
string
>
map_ins
;
sym_map
();
sym_map
();
void
add_filter
(
const
std
::
string
&
sym
);
void
add_filter
(
const
std
::
string
&
sym
);
void
load_file
(
const
char
*
path
,
uint64_t
offset
=
0
);
void
load_file
(
const
char
*
path
,
uint64_t
offset
=
0
);
inline
const
std
::
string
*
lookup
(
uint64_t
addr
)
inline
const
std
::
string
*
lookup
(
uint64_t
addr
)
{
{
auto
it
=
map
.
find
(
addr
);
auto
it
=
map
.
find
(
addr
);
if
(
it
==
map
.
end
())
if
(
it
==
map
.
end
())
return
nullptr
;
return
nullptr
;
return
&
it
->
second
;
return
&
it
->
second
;
}
}
};
};
class
log_parser
{
class
log_parser
{
protected:
protected:
std
::
istream
*
inf
;
std
::
istream
*
inf
;
std
::
ifstream
*
gz_file
;
std
::
ifstream
*
gz_file
;
boost
::
iostreams
::
filtering_streambuf
<
boost
::
iostreams
::
input
>
*
gz_in
;
boost
::
iostreams
::
filtering_streambuf
<
boost
::
iostreams
::
input
>
*
gz_in
;
static
const
size_t
block_size
=
16
*
1024
*
1024
;
static
const
size_t
block_size
=
16
*
1024
*
1024
;
char
*
buf
;
char
*
buf
;
size_t
buf_len
;
size_t
buf_len
;
size_t
buf_pos
;
size_t
buf_pos
;
bool
next_block
();
bool
next_block
();
size_t
try_line
();
size_t
try_line
();
virtual
void
process_line
(
char
*
line
,
size_t
len
)
=
0
;
virtual
void
process_line
(
char
*
line
,
size_t
len
)
=
0
;
public:
public:
const
char
*
label
;
const
char
*
label
;
event
*
cur_event
;
event
*
cur_event
;
log_parser
();
log_parser
();
virtual
~
log_parser
();
virtual
~
log_parser
();
void
open
(
const
char
*
path
);
void
open
(
const
char
*
path
);
void
open_gz
(
const
char
*
path
);
void
open_gz
(
const
char
*
path
);
bool
next_event
();
bool
next_event
();
};
};
class
gem5_parser
:
public
log_parser
{
class
gem5_parser
:
public
log_parser
{
protected:
protected:
sym_map
&
syms
;
sym_map
&
syms
;
virtual
void
process_line
(
char
*
line
,
size_t
len
);
virtual
void
process_line
(
char
*
line
,
size_t
len
);
void
process_msg
(
uint64_t
ts
,
char
*
comp_name
,
size_t
comp_name_len
,
void
process_msg
(
uint64_t
ts
,
char
*
comp_name
,
size_t
comp_name_len
,
char
*
msg
,
size_t
msg_len
);
char
*
msg
,
size_t
msg_len
);
public:
public:
gem5_parser
(
sym_map
&
syms_
);
gem5_parser
(
sym_map
&
syms_
);
virtual
~
gem5_parser
();
virtual
~
gem5_parser
();
};
};
class
nicbm_parser
:
public
log_parser
{
class
nicbm_parser
:
public
log_parser
{
protected:
protected:
virtual
void
process_line
(
char
*
line
,
size_t
len
);
virtual
void
process_line
(
char
*
line
,
size_t
len
);
public:
public:
virtual
~
nicbm_parser
();
virtual
~
nicbm_parser
();
};
};
Prev
1
2
3
Next
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