Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
openairinterface-6g
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
openairinterface-6g
Commits
8ecda65d
Commit
8ecda65d
authored
Oct 23, 2025
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove Benetel radio drivers
These drivers are superseded by the O-RAN 7.2 FHI.
parent
70451408
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
2 additions
and
3373 deletions
+2
-3373
cmake_targets/build_oai
cmake_targets/build_oai
+2
-2
radio/ETHERNET/CMakeLists.txt
radio/ETHERNET/CMakeLists.txt
+0
-2
radio/ETHERNET/benetel/4g/CMakeLists.txt
radio/ETHERNET/benetel/4g/CMakeLists.txt
+0
-20
radio/ETHERNET/benetel/4g/benetel.c
radio/ETHERNET/benetel/4g/benetel.c
+0
-392
radio/ETHERNET/benetel/4g/dpdk_driver.c
radio/ETHERNET/benetel/4g/dpdk_driver.c
+0
-774
radio/ETHERNET/benetel/4g/low.c
radio/ETHERNET/benetel/4g/low.c
+0
-94
radio/ETHERNET/benetel/4g/low.h
radio/ETHERNET/benetel/4g/low.h
+0
-50
radio/ETHERNET/benetel/4g/low_dpdk.c
radio/ETHERNET/benetel/4g/low_dpdk.c
+0
-119
radio/ETHERNET/benetel/4g/shared_buffers.c
radio/ETHERNET/benetel/4g/shared_buffers.c
+0
-117
radio/ETHERNET/benetel/4g/shared_buffers.h
radio/ETHERNET/benetel/4g/shared_buffers.h
+0
-61
radio/ETHERNET/benetel/5g/CMakeLists.txt
radio/ETHERNET/benetel/5g/CMakeLists.txt
+0
-19
radio/ETHERNET/benetel/5g/benetel.c
radio/ETHERNET/benetel/5g/benetel.c
+0
-399
radio/ETHERNET/benetel/5g/dpdk_driver.c
radio/ETHERNET/benetel/5g/dpdk_driver.c
+0
-835
radio/ETHERNET/benetel/5g/low.c
radio/ETHERNET/benetel/5g/low.c
+0
-128
radio/ETHERNET/benetel/5g/low.h
radio/ETHERNET/benetel/5g/low.h
+0
-49
radio/ETHERNET/benetel/5g/low_dpdk.c
radio/ETHERNET/benetel/5g/low_dpdk.c
+0
-119
radio/ETHERNET/benetel/5g/shared_buffers.c
radio/ETHERNET/benetel/5g/shared_buffers.c
+0
-123
radio/ETHERNET/benetel/5g/shared_buffers.h
radio/ETHERNET/benetel/5g/shared_buffers.h
+0
-61
radio/ETHERNET/benetel/CMakeLists.txt
radio/ETHERNET/benetel/CMakeLists.txt
+0
-9
No files found.
cmake_targets/build_oai
View file @
8ecda65d
...
@@ -92,7 +92,7 @@ Options:
...
@@ -92,7 +92,7 @@ Options:
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
Adds this RF board support (in external packages installation and in compilation)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport
-t | --transport
Selects the transport protocol type, options: None, Ethernet,
benetel4g, benetel5g,
oran_fhlib_5g, oran_fhlib_5g_mplane, WLS
Selects the transport protocol type, options: None, Ethernet, oran_fhlib_5g, oran_fhlib_5g_mplane, WLS
-P | --phy_simulators
-P | --phy_simulators
Makes the unitary tests Layer 1 simulators
Makes the unitary tests Layer 1 simulators
-V | --vcd
-V | --vcd
...
@@ -278,7 +278,7 @@ function main() {
...
@@ -278,7 +278,7 @@ function main() {
TARGET_LIST
=
"
$TARGET_LIST
oai_eth_transpro"
TARGET_LIST
=
"
$TARGET_LIST
oai_eth_transpro"
CMAKE_CMD
=
"
$CMAKE_CMD
-DOAI_
${
2
^^
}
=ON"
# ^^ makes uppercase
CMAKE_CMD
=
"
$CMAKE_CMD
-DOAI_
${
2
^^
}
=ON"
# ^^ makes uppercase
;;
;;
"
benetel4g"
|
"benetel5g"
|
"
oran_fhlib_4g"
)
"oran_fhlib_4g"
)
TARGET_LIST
=
"
$TARGET_LIST
$2
"
TARGET_LIST
=
"
$TARGET_LIST
$2
"
CMAKE_CMD
=
"
$CMAKE_CMD
-DOAI_
${
2
^^
}
=ON"
# ^^ makes uppercase
CMAKE_CMD
=
"
$CMAKE_CMD
-DOAI_
${
2
^^
}
=ON"
# ^^ makes uppercase
;;
;;
...
...
radio/ETHERNET/CMakeLists.txt
View file @
8ecda65d
...
@@ -9,5 +9,3 @@ set_target_properties(oai_eth_transpro PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMA
...
@@ -9,5 +9,3 @@ set_target_properties(oai_eth_transpro PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMA
add_custom_command
(
TARGET oai_eth_transpro POST_BUILD
add_custom_command
(
TARGET oai_eth_transpro POST_BUILD
COMMAND
${
CMAKE_COMMAND
}
-E create_symlink liboai_eth_transpro.so liboai_transpro.so
COMMAND
${
CMAKE_COMMAND
}
-E create_symlink liboai_eth_transpro.so liboai_transpro.so
WORKING_DIRECTORY
${
CMAKE_BINARY_DIR
}
)
WORKING_DIRECTORY
${
CMAKE_BINARY_DIR
}
)
add_subdirectory
(
benetel
)
radio/ETHERNET/benetel/4g/CMakeLists.txt
deleted
100644 → 0
View file @
70451408
pkg_check_modules
(
libdpdk REQUIRED libdpdk=20.05.0
)
add_library
(
benetel_4g MODULE
benetel.c
shared_buffers.c
low.c
low_dpdk.c
dpdk_driver.c
)
target_compile_definitions
(
benetel_4g PROPERTIES COMPILE_FLAGS
"-fvisibility=hidden -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include"
)
SET
(
DPDK_LIBS
"-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive"
)
target_include_directories
(
benetel_4g PRIVATE
${
libdpdk_INCLUDE_DIRS
}
)
target_link_libraries
(
benetel_4g PRIVATE
${
libdpdk_LIBRARIES
}
)
target_link_libraries
(
benetel_4g PRIVATE pthread dl rt m numa
)
set_target_properties
(
benetel_4g PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${
CMAKE_BINARY_DIR
}
)
add_custom_command
(
TARGET benetel_4g POST_BUILD
COMMAND
${
CMAKE_COMMAND
}
-E create_symlink libbenetel_4g.so liboai_transpro.so
WORKING_DIRECTORY
${
CMAKE_BINARY_DIR
}
)
radio/ETHERNET/benetel/4g/benetel.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#include "shared_buffers.h"
#include "low.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
typedef
struct
{
eth_state_t
e
;
shared_buffers
buffers
;
rru_config_msg_type_t
last_msg
;
int
capabilities_sent
;
void
*
benetel_priv
;
char
*
dpdk_main_command_line
;
}
benetel_eth_state_t
;
int
trx_benetel_start
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
0
;
}
void
trx_benetel_end
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
}
int
trx_benetel_stop
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_get_stats
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_reset_stats
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
ethernet_tune
(
openair0_device
*
device
,
unsigned
int
option
,
int
value
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
0
;
}
int
trx_benetel_write_raw
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
nsamps
*
4
;
}
int
trx_benetel_read_raw
(
openair0_device
*
device
,
openair0_timestamp
*
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
nsamps
*
4
;
}
char
*
msg_type
(
int
t
)
{
static
char
*
s
[
12
]
=
{
"RAU_tick"
,
"RRU_capabilities"
,
"RRU_config"
,
"RRU_config_ok"
,
"RRU_start"
,
"RRU_stop"
,
"RRU_sync_ok"
,
"RRU_frame_resynch"
,
"RRU_MSG_max_num"
,
"RRU_check_sync"
,
"RRU_config_update"
,
"RRU_config_update_ok"
,
};
if
(
t
<
0
||
t
>
11
)
return
"UNKNOWN"
;
return
s
[
t
];
}
int
trx_benetel_ctlsend
(
openair0_device
*
device
,
void
*
msg
,
ssize_t
msg_len
)
{
RRU_CONFIG_msg_t
*
rru_config_msg
=
msg
;
benetel_eth_state_t
*
s
=
device
->
priv
;
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
printf
(
" rru_config_msg->type %d [%s]
\n
"
,
rru_config_msg
->
type
,
msg_type
(
rru_config_msg
->
type
));
s
->
last_msg
=
rru_config_msg
->
type
;
return
msg_len
;
}
int
trx_benetel_ctlrecv
(
openair0_device
*
device
,
void
*
msg
,
ssize_t
msg_len
)
{
RRU_CONFIG_msg_t
*
rru_config_msg
=
msg
;
benetel_eth_state_t
*
s
=
device
->
priv
;
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
if
(
s
->
last_msg
==
RAU_tick
&&
s
->
capabilities_sent
==
0
)
{
RRU_capabilities_t
*
cap
;
rru_config_msg
->
type
=
RRU_capabilities
;
rru_config_msg
->
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_capabilities_t
);
cap
=
(
RRU_capabilities_t
*
)
&
rru_config_msg
->
msg
[
0
];
cap
->
FH_fmt
=
OAI_IF4p5_only
;
cap
->
num_bands
=
1
;
cap
->
band_list
[
0
]
=
7
;
cap
->
nb_rx
[
0
]
=
device
->
openair0_cfg
->
rx_num_channels
;
cap
->
nb_tx
[
0
]
=
device
->
openair0_cfg
->
tx_num_channels
;
cap
->
max_pdschReferenceSignalPower
[
0
]
=
-
27
;
cap
->
max_rxgain
[
0
]
=
90
;
s
->
capabilities_sent
=
1
;
return
rru_config_msg
->
len
;
}
if
(
s
->
last_msg
==
RRU_config
)
{
rru_config_msg
->
type
=
RRU_config_ok
;
return
0
;
}
if
(
s
->
last_msg
==
RRU_start
)
{
s
->
benetel_priv
=
benetel_start
(
s
->
e
.
if_name
,
&
s
->
buffers
,
s
->
dpdk_main_command_line
);
}
/* correct? */
while
(
1
)
pause
();
return
0
;
}
void
benetel_fh_if4p5_south_in
(
RU_t
*
ru
,
int
*
frame
,
int
*
subframe
)
{
benetel_eth_state_t
*
s
=
ru
->
ifdevice
.
priv
;
PHY_VARS_eNB
**
eNB_list
=
ru
->
eNB_list
,
*
eNB
;
LTE_DL_FRAME_PARMS
*
fp
;
int
symbol
;
int32_t
*
rxdata
;
int
antenna
;
lock_ul_buffer
(
&
s
->
buffers
,
*
subframe
);
next:
while
(
!
((
s
->
buffers
.
ul_busy
[
0
][
*
subframe
]
==
0x3fff
&&
s
->
buffers
.
ul_busy
[
1
][
*
subframe
]
==
0x3fff
)
||
s
->
buffers
.
prach_busy
[
*
subframe
]
==
1
))
wait_ul_buffer
(
&
s
->
buffers
,
*
subframe
);
if
(
s
->
buffers
.
prach_busy
[
*
subframe
]
==
1
)
{
int
i
;
int
antenna
=
0
;
uint16_t
*
in
;
uint16_t
*
out
;
in
=
(
uint16_t
*
)
s
->
buffers
.
prach
[
*
subframe
];
out
=
(
uint16_t
*
)
ru
->
prach_rxsigF
[
0
][
antenna
];
for
(
i
=
0
;
i
<
840
*
2
;
i
++
)
out
[
i
]
=
ntohs
(
in
[
i
]);
s
->
buffers
.
prach_busy
[
*
subframe
]
=
0
;
ru
->
wakeup_prach_eNB
(
ru
->
eNB_list
[
0
],
ru
,
*
frame
,
*
subframe
);
goto
next
;
}
eNB
=
eNB_list
[
0
];
fp
=
&
eNB
->
frame_parms
;
for
(
antenna
=
0
;
antenna
<
ru
->
nb_rx
;
antenna
++
)
{
for
(
symbol
=
0
;
symbol
<
14
;
symbol
++
)
{
int
i
;
uint16_t
*
p
=
(
uint16_t
*
)(
&
s
->
buffers
.
ul
[
antenna
][
*
subframe
][
symbol
*
1200
*
4
]);
for
(
i
=
0
;
i
<
1200
*
2
;
i
++
)
{
p
[
i
]
=
htons
(
p
[
i
]);
}
rxdata
=
&
ru
->
common
.
rxdataF
[
antenna
][
symbol
*
fp
->
ofdm_symbol_size
];
#if 1
memcpy
(
rxdata
+
2048
-
600
,
&
s
->
buffers
.
ul
[
antenna
][
*
subframe
][
symbol
*
1200
*
4
],
600
*
4
);
memcpy
(
rxdata
,
&
s
->
buffers
.
ul
[
antenna
][
*
subframe
][
symbol
*
1200
*
4
]
+
600
*
4
,
600
*
4
);
#endif
}
}
s
->
buffers
.
ul_busy
[
0
][
*
subframe
]
=
0
;
s
->
buffers
.
ul_busy
[
1
][
*
subframe
]
=
0
;
signal_ul_buffer
(
&
s
->
buffers
,
*
subframe
);
unlock_ul_buffer
(
&
s
->
buffers
,
*
subframe
);
//printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *subframe);
RU_proc_t
*
proc
=
&
ru
->
proc
;
extern
int
sf_ahead
;
int
f
=
*
frame
;
int
sf
=
*
subframe
;
//calculate timestamp_rx, timestamp_tx based on frame and subframe
proc
->
tti_rx
=
sf
;
proc
->
frame_rx
=
f
;
proc
->
timestamp_rx
=
((
proc
->
frame_rx
*
10
)
+
proc
->
tti_rx
)
*
fp
->
samples_per_tti
;
if
(
get_nprocs
()
<=
4
)
{
proc
->
tti_tx
=
(
sf
+
sf_ahead
)
%
10
;
proc
->
frame_tx
=
(
sf
>
(
9
-
sf_ahead
))
?
(
f
+
1
)
&
1023
:
f
;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_IN_RU
+
ru
->
idx
,
f
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_IN_RU
+
ru
->
idx
,
sf
);
proc
->
symbol_mask
[
sf
]
=
0
;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS
,
proc
->
timestamp_rx
&
0xffffffff
);
}
void
benetel_fh_if4p5_south_out
(
RU_t
*
ru
,
int
frame
,
int
subframe
,
uint64_t
timestamp
)
{
benetel_eth_state_t
*
s
=
ru
->
ifdevice
.
priv
;
PHY_VARS_eNB
**
eNB_list
=
ru
->
eNB_list
,
*
eNB
;
LTE_DL_FRAME_PARMS
*
fp
;
int
symbol
;
int32_t
*
txdata
;
int
aa
;
//printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST
,
ru
->
proc
.
timestamp_tx
&
0xffffffff
);
lock_dl_buffer
(
&
s
->
buffers
,
subframe
);
if
(
s
->
buffers
.
dl_busy
[
0
][
subframe
]
||
s
->
buffers
.
dl_busy
[
1
][
subframe
])
{
printf
(
"%s: fatal: DL buffer busy for subframe %d
\n
"
,
__FUNCTION__
,
subframe
);
unlock_dl_buffer
(
&
s
->
buffers
,
subframe
);
return
;
}
eNB
=
eNB_list
[
0
];
fp
=
&
eNB
->
frame_parms
;
if
(
ru
->
num_eNB
!=
1
||
fp
->
ofdm_symbol_size
!=
2048
||
fp
->
Ncp
!=
NORMAL
||
fp
->
symbols_per_tti
!=
14
)
{
printf
(
"%s:%d:%s: unsupported configuration
\n
"
,
__FILE__
,
__LINE__
,
__FUNCTION__
);
exit
(
1
);
}
for
(
aa
=
0
;
aa
<
ru
->
nb_tx
;
aa
++
)
{
for
(
symbol
=
0
;
symbol
<
14
;
symbol
++
)
{
txdata
=
&
ru
->
common
.
txdataF_BF
[
aa
][
symbol
*
fp
->
ofdm_symbol_size
];
#if 1
memcpy
(
&
s
->
buffers
.
dl
[
aa
][
subframe
][
symbol
*
1200
*
4
],
txdata
+
2048
-
600
,
600
*
4
);
memcpy
(
&
s
->
buffers
.
dl
[
aa
][
subframe
][
symbol
*
1200
*
4
]
+
600
*
4
,
txdata
+
1
,
600
*
4
);
#endif
int
i
;
uint16_t
*
p
=
(
uint16_t
*
)(
&
s
->
buffers
.
dl
[
aa
][
subframe
][
symbol
*
1200
*
4
]);
for
(
i
=
0
;
i
<
1200
*
2
;
i
++
)
{
p
[
i
]
=
htons
(
p
[
i
]);
}
}
}
s
->
buffers
.
dl_busy
[
0
][
subframe
]
=
0x3fff
;
s
->
buffers
.
dl_busy
[
1
][
subframe
]
=
0x3fff
;
unlock_dl_buffer
(
&
s
->
buffers
,
subframe
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU
+
ru
->
idx
,
ru
->
proc
.
frame_tx
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU
+
ru
->
idx
,
ru
->
proc
.
tti_tx
);
}
void
*
get_internal_parameter
(
char
*
name
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
if
(
!
strcmp
(
name
,
"fh_if4p5_south_in"
))
return
benetel_fh_if4p5_south_in
;
if
(
!
strcmp
(
name
,
"fh_if4p5_south_out"
))
return
benetel_fh_if4p5_south_out
;
return
NULL
;
}
__attribute__
((
__visibility__
(
"default"
)))
int
transport_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
eth_params_t
*
eth_params
)
{
benetel_eth_state_t
*
eth
;
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
device
->
Mod_id
=
0
;
device
->
transp_type
=
ETHERNET_TP
;
device
->
trx_start_func
=
trx_benetel_start
;
device
->
trx_get_stats_func
=
trx_benetel_get_stats
;
device
->
trx_reset_stats_func
=
trx_benetel_reset_stats
;
device
->
trx_end_func
=
trx_benetel_end
;
device
->
trx_stop_func
=
trx_benetel_stop
;
device
->
trx_set_freq_func
=
trx_benetel_set_freq
;
device
->
trx_set_gains_func
=
trx_benetel_set_gains
;
device
->
trx_write_func
=
trx_benetel_write_raw
;
device
->
trx_read_func
=
trx_benetel_read_raw
;
device
->
trx_ctlsend_func
=
trx_benetel_ctlsend
;
device
->
trx_ctlrecv_func
=
trx_benetel_ctlrecv
;
device
->
get_internal_parameter
=
get_internal_parameter
;
eth
=
calloc
(
1
,
sizeof
(
benetel_eth_state_t
));
if
(
eth
==
NULL
)
{
AssertFatal
(
0
==
1
,
"out of memory
\n
"
);
}
eth
->
e
.
flags
=
ETH_RAW_IF4p5_MODE
;
eth
->
e
.
compression
=
NO_COMPRESS
;
eth
->
e
.
if_name
=
eth_params
->
local_if_name
;
device
->
priv
=
eth
;
device
->
openair0_cfg
=&
openair0_cfg
[
0
];
if
(
openair0_cfg
->
sdr_addrs
==
NULL
)
{
printf
(
"benetel: fatal: sdr_addrs not set in configuration file
\n
"
);
exit
(
1
);
}
eth
->
dpdk_main_command_line
=
strdup
(
openair0_cfg
->
sdr_addrs
);
if
(
eth
->
dpdk_main_command_line
==
NULL
)
{
AssertFatal
(
0
==
1
,
"out of memory
\n
"
);
}
eth
->
last_msg
=
-
1
;
init_buffers
(
&
eth
->
buffers
);
return
0
;
}
radio/ETHERNET/benetel/4g/dpdk_driver.c
deleted
100644 → 0
View file @
70451408
/* license: to be defined */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include "low.h"
// HEADER DEFINITION
#define ANT_NUM buf[23]
#define PAYLOAD_1 buf[20]
#define PAYLOAD_2 buf[21]
#define ETH_TYPE buf[17]
#define SYMBOL buf[29]
#define SUBFRAME buf[28]
#define FRAME buf[27]
static
volatile
bool
force_quit
;
unsigned
short
iq
[
33600
];
unsigned
char
iq_swap
[
67200
];
unsigned
short
*
iq_ptr
[
14
];
unsigned
int
dl_start
=
0
;
/* MAC updating enabled by default */
static
int
mac_updating
=
1
;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 5
/* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static
uint16_t
nb_rxd
=
RTE_TEST_RX_DESC_DEFAULT
;
static
uint16_t
nb_txd
=
RTE_TEST_TX_DESC_DEFAULT
;
/* ethernet addresses of ports */
static
struct
ether_addr
l2fwd_ports_eth_addr
[
RTE_MAX_ETHPORTS
];
/* mask of enabled ports */
static
uint32_t
l2fwd_enabled_port_mask
=
0
;
/* list of enabled ports */
static
uint32_t
l2fwd_dst_ports
[
RTE_MAX_ETHPORTS
];
static
unsigned
int
l2fwd_rx_queue_per_lcore
=
1
;
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct
lcore_queue_conf
{
unsigned
n_rx_port
;
unsigned
rx_port_list
[
MAX_RX_QUEUE_PER_LCORE
];
}
__rte_cache_aligned
;
struct
lcore_queue_conf
lcore_queue_conf
[
RTE_MAX_LCORE
];
static
struct
rte_eth_dev_tx_buffer
*
tx_buffer
[
RTE_MAX_ETHPORTS
];
static
struct
rte_eth_conf
port_conf
=
{
.
rxmode
=
{
.
split_hdr_size
=
0
,
.
offloads
=
DEV_RX_OFFLOAD_JUMBO_FRAME
,
.
split_hdr_size
=
0
,
.
max_rx_pkt_len
=
9500
,
},
.
txmode
=
{
.
mq_mode
=
ETH_MQ_TX_NONE
,
},
};
struct
rte_mempool
*
l2fwd_pktmbuf_pool
=
NULL
;
/* Per-port statistics struct */
struct
l2fwd_port_statistics
{
uint64_t
tx
;
uint64_t
rx
;
uint64_t
dropped
;
}
__rte_cache_aligned
;
struct
l2fwd_port_statistics
port_statistics
[
RTE_MAX_ETHPORTS
];
#define MAX_TIMER_PERIOD 86400
/* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
static
uint64_t
timer_period
=
10
;
/* default period is 10 seconds */
/* Print out statistics on packets dropped */
static
void
print_stats
(
void
)
{
uint64_t
total_packets_dropped
,
total_packets_tx
,
total_packets_rx
;
unsigned
portid
;
total_packets_dropped
=
0
;
total_packets_tx
=
0
;
total_packets_rx
=
0
;
const
char
clr
[]
=
{
27
,
'['
,
'2'
,
'J'
,
'\0'
};
const
char
topLeft
[]
=
{
27
,
'['
,
'1'
,
';'
,
'1'
,
'H'
,
'\0'
};
/* Clear screen and move to top left */
printf
(
"%s%s"
,
clr
,
topLeft
);
printf
(
"
\n
Port statistics ===================================="
);
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
{
/* skip disabled ports */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"
\n
Statistics for port %u ------------------------------"
"
\n
Packets sent: %24"
PRIu64
"
\n
Packets received: %20"
PRIu64
"
\n
Packets dropped: %21"
PRIu64
,
portid
,
port_statistics
[
portid
].
tx
,
port_statistics
[
portid
].
rx
,
port_statistics
[
portid
].
dropped
);
total_packets_dropped
+=
port_statistics
[
portid
].
dropped
;
total_packets_tx
+=
port_statistics
[
portid
].
tx
;
total_packets_rx
+=
port_statistics
[
portid
].
rx
;
}
printf
(
"
\n
Aggregate statistics ==============================="
"
\n
Total packets sent: %18"
PRIu64
"
\n
Total packets received: %14"
PRIu64
"
\n
Total packets dropped: %15"
PRIu64
,
total_packets_tx
,
total_packets_rx
,
total_packets_dropped
);
printf
(
"
\n
====================================================
\n
"
);
}
static
void
l2fwd_simple_forward
(
struct
rte_mbuf
*
m
,
unsigned
portid
,
benetel_t
*
bs
)
{
unsigned
char
*
buf
,
*
buf_tx
;
unsigned
int
len
;
struct
ether_hdr
*
eth
;
unsigned
dst_port
;
int
sent
,
prach_ctrl
=
0
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
unsigned
char
*
IQ_ptr
;
ul_packet_t
p
;
buf
=
rte_pktmbuf_mtod
(
m
,
unsigned
char
*
);
//rte_memdump(stdout, "Rx Packet",buf ,34);
eth
=
rte_pktmbuf_mtod
(
m
,
struct
ether_hdr
*
);
len
=
rte_pktmbuf_data_len
(
m
);
IQ_ptr
=
&
buf
[
34
];
//destination mac address (RRU MAC)
eth
->
d_addr
.
addr_bytes
[
0
]
=
0x02
;
eth
->
d_addr
.
addr_bytes
[
1
]
=
0x00
;
eth
->
d_addr
.
addr_bytes
[
2
]
=
0x5e
;
eth
->
d_addr
.
addr_bytes
[
3
]
=
0x01
;
eth
->
d_addr
.
addr_bytes
[
4
]
=
0x01
;
eth
->
d_addr
.
addr_bytes
[
5
]
=
0x01
;
//source mac address (DU MAC)
eth
->
s_addr
.
addr_bytes
[
0
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
1
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
2
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
3
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
4
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
5
]
=
0xdd
;
dst_port
=
l2fwd_dst_ports
[
portid
];
#if 1
if
(
buf
[
18
]
==
0xAA
)
//msg1 check
{
printf
(
"
\n
Handshake MSG 1 Received
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
buf
[
18
]
=
0xBB
;
//change to msg2 after receive msg1
printf
(
"Handshake MSG 2 Sent
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
}
#else
// Handshake Condition
if
(
buf
[
18
]
==
0x01
||
buf
[
18
]
==
0x03
)
// ORAN handshake msgs.
{
if
(
buf
[
18
]
==
0x01
)
//msg1 check
{
printf
(
"
\n
Handshake MSG 1 Received
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
buf
[
18
]
=
0x02
;
//change to msg2 after receive msg1
printf
(
"Handshake MSG 2 Sent
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
}
else
if
(
buf
[
18
]
==
0x03
)
//msg3 check
{
printf
(
"Handshake MSG 3 Sent
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
buf
[
18
]
=
0x04
;
printf
(
"Handshake MSG 4 Sent
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
}
}
#endif
// Trigger start send DL packets
if
(
PAYLOAD_1
==
0x12
&&
PAYLOAD_2
==
0xce
&&
SYMBOL
==
0x09
&&
ANT_NUM
==
0x00
&&
dl_start
==
0
){
printf
(
"
\n
U-Plane Started
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
dl_start
=
1
;
}
if
(
PAYLOAD_1
==
0x12
&&
PAYLOAD_2
==
0xce
)
{
p
.
frame
=
FRAME
;
p
.
subframe
=
SUBFRAME
>>
4
;
p
.
slot
=
0
;
/* unused */
p
.
symbol
=
SYMBOL
;
p
.
antenna
=
ANT_NUM
;
memcpy
(
p
.
iq
,
IQ_ptr
,
4800
);
store_ul
(
bs
,
&
p
);
}
// U-PLANE UL PROCESSING
if
(
PAYLOAD_1
==
0x12
&&
PAYLOAD_2
==
0xce
&&
dl_start
==
1
)
{
int
a
=
ANT_NUM
;
int
tx_frame
=
FRAME
;
int
tx_subframe
=
SUBFRAME
>>
4
;
int
tx_symbol
=
SYMBOL
+
5
;
if
(
tx_symbol
>
13
)
{
tx_symbol
-=
14
;
tx_subframe
++
;
if
(
tx_subframe
==
10
)
{
tx_subframe
=
0
;
tx_frame
=
(
tx_frame
+
1
)
&
255
;
}
}
// ANT_NUM = 0x00;
// SYMBOL = (SYMBOL + 5) % 14;
PAYLOAD_2
=
0xc8
;
FRAME
=
tx_frame
;
SUBFRAME
=
tx_subframe
<<
4
;
SYMBOL
=
tx_symbol
;
/* send actual DL data (if available) */
lock_dl_buffer
(
bs
->
buffers
,
tx_subframe
);
if
(
!
(
bs
->
buffers
->
dl_busy
[
a
][
tx_subframe
]
&
(
1
<<
tx_symbol
)))
{
printf
(
"%s: warning, DL underflow (antenna %d sf.symbol %d.%d)
\n
"
,
__FUNCTION__
,
a
,
tx_subframe
,
tx_symbol
);
memset
(
IQ_ptr
,
0
,
1200
*
4
);
}
else
{
memcpy
(
IQ_ptr
,
bs
->
buffers
->
dl
[
a
][
tx_subframe
]
+
tx_symbol
*
1200
*
4
,
1200
*
4
);
}
bs
->
buffers
->
dl_busy
[
a
][
tx_subframe
]
&=
~
(
1
<<
tx_symbol
);
unlock_dl_buffer
(
bs
->
buffers
,
tx_subframe
);
}
// U-PLANE PRACH PROCESSING
else
if
(
PAYLOAD_1
==
0x0d
&&
PAYLOAD_2
==
0x28
){
if
(
ANT_NUM
==
0
)
{
store_prach
(
bs
,
FRAME
,
SUBFRAME
>>
4
,
IQ_ptr
);
}
rte_pktmbuf_free
(
m
);
return
;
}
// Send Packets
buffer
=
tx_buffer
[
dst_port
];
sent
=
rte_eth_tx_buffer
(
dst_port
,
0
,
buffer
,
m
);
if
(
sent
)
port_statistics
[
dst_port
].
tx
+=
sent
;
}
/* main processing loop */
static
void
l2fwd_main_loop
(
benetel_t
*
bs
)
{
struct
rte_mbuf
*
pkts_burst
[
MAX_PKT_BURST
];
struct
rte_mbuf
*
m
;
int
sent
;
unsigned
lcore_id
;
uint64_t
prev_tsc
,
diff_tsc
,
cur_tsc
,
timer_tsc
;
unsigned
i
,
j
,
portid
,
nb_rx
;
struct
lcore_queue_conf
*
qconf
;
const
uint64_t
drain_tsc
=
(
rte_get_tsc_hz
()
+
US_PER_S
-
1
)
/
US_PER_S
*
BURST_TX_DRAIN_US
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
prev_tsc
=
0
;
timer_tsc
=
0
;
lcore_id
=
rte_lcore_id
();
qconf
=
&
lcore_queue_conf
[
lcore_id
];
if
(
qconf
->
n_rx_port
==
0
)
{
RTE_LOG
(
INFO
,
L2FWD
,
"lcore %u has nothing to do
\n
"
,
lcore_id
);
return
;
}
RTE_LOG
(
INFO
,
L2FWD
,
"entering main loop on lcore %u
\n
"
,
lcore_id
);
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
RTE_LOG
(
INFO
,
L2FWD
,
" -- lcoreid=%u portid=%u
\n
"
,
lcore_id
,
portid
);
}
while
(
!
force_quit
)
{
cur_tsc
=
rte_rdtsc
();
/*
* TX burst queue drain
*/
diff_tsc
=
cur_tsc
-
prev_tsc
;
if
(
unlikely
(
diff_tsc
>
drain_tsc
))
{
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
l2fwd_dst_ports
[
qconf
->
rx_port_list
[
i
]];
buffer
=
tx_buffer
[
portid
];
sent
=
rte_eth_tx_buffer_flush
(
portid
,
0
,
buffer
);
if
(
sent
)
port_statistics
[
portid
].
tx
+=
sent
;
}
/* if timer is enabled */
if
(
timer_period
>
0
)
{
/* advance the timer */
timer_tsc
+=
diff_tsc
;
/* if timer has reached its timeout */
if
(
unlikely
(
timer_tsc
>=
timer_period
))
{
/* do this only on master core */
if
(
lcore_id
==
rte_get_master_lcore
())
{
//print_stats();
/* reset the timer */
timer_tsc
=
0
;
}
}
}
prev_tsc
=
cur_tsc
;
}
/*
* Read packet from RX queues
*/
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
nb_rx
=
rte_eth_rx_burst
(
portid
,
0
,
pkts_burst
,
MAX_PKT_BURST
);
port_statistics
[
portid
].
rx
+=
nb_rx
;
for
(
j
=
0
;
j
<
nb_rx
;
j
++
)
{
m
=
pkts_burst
[
j
];
rte_prefetch0
(
rte_pktmbuf_mtod
(
m
,
void
*
));
l2fwd_simple_forward
(
m
,
portid
,
bs
);
}
}
}
}
static
int
l2fwd_launch_one_lcore
(
void
*
bs
)
{
l2fwd_main_loop
(
bs
);
return
0
;
}
/* display usage */
static
void
l2fwd_usage
(
const
char
*
prgname
)
{
printf
(
"%s [EAL options] -- -p PORTMASK [-q NQ]
\n
"
" -p PORTMASK: hexadecimal bitmask of ports to configure
\n
"
" -q NQ: number of queue (=ports) per lcore (default is 1)
\n
"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)
\n
"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)
\n
"
" When enabled:
\n
"
" - The source MAC address is replaced by the TX port MAC address
\n
"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
\n
"
,
prgname
);
}
static
int
l2fwd_parse_portmask
(
const
char
*
portmask
)
{
char
*
end
=
NULL
;
unsigned
long
pm
;
/* parse hexadecimal string */
pm
=
strtoul
(
portmask
,
&
end
,
16
);
if
((
portmask
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
pm
==
0
)
return
-
1
;
return
pm
;
}
static
unsigned
int
l2fwd_parse_nqueue
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
unsigned
long
n
;
/* parse hexadecimal string */
n
=
strtoul
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
if
(
n
==
0
)
return
0
;
if
(
n
>=
MAX_RX_QUEUE_PER_LCORE
)
return
0
;
return
n
;
}
static
int
l2fwd_parse_timer_period
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
int
n
;
/* parse number string */
n
=
strtol
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
n
>=
MAX_TIMER_PERIOD
)
return
-
1
;
return
n
;
}
static
const
char
short_options
[]
=
"p:"
/* portmask */
"q:"
/* number of queues */
"T:"
/* timer period */
;
#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
enum
{
/* long options mapped to a short option */
/* first long only option value must be >= 256, so that we won't
* conflict with short options */
CMD_LINE_OPT_MIN_NUM
=
256
,
};
static
const
struct
option
lgopts
[]
=
{
{
CMD_LINE_OPT_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
1
},
{
CMD_LINE_OPT_NO_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
0
},
{
NULL
,
0
,
0
,
0
}
};
/* Parse the argument given in the command line of the application */
static
int
l2fwd_parse_args
(
int
argc
,
char
**
argv
)
{
int
opt
,
ret
,
timer_secs
;
char
**
argvopt
;
int
option_index
;
char
*
prgname
=
argv
[
0
];
argvopt
=
argv
;
while
((
opt
=
getopt_long
(
argc
,
argvopt
,
short_options
,
lgopts
,
&
option_index
))
!=
EOF
)
{
switch
(
opt
)
{
/* portmask */
case
'p'
:
l2fwd_enabled_port_mask
=
l2fwd_parse_portmask
(
optarg
);
if
(
l2fwd_enabled_port_mask
==
0
)
{
printf
(
"invalid portmask
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* nqueue */
case
'q'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
case
'T'
:
timer_secs
=
l2fwd_parse_timer_period
(
optarg
);
if
(
timer_secs
<
0
)
{
printf
(
"invalid timer period
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
timer_period
=
timer_secs
;
break
;
/* long options */
case
0
:
break
;
default:
l2fwd_usage
(
prgname
);
return
-
1
;
}
}
if
(
optind
>=
0
)
argv
[
optind
-
1
]
=
prgname
;
ret
=
optind
-
1
;
optind
=
1
;
/* reset getopt lib */
return
ret
;
}
/* Check the link status of all ports in up to 9s, and print them finally */
static
void
check_all_ports_link_status
(
uint32_t
port_mask
)
{
#define CHECK_INTERVAL 100
/* 100ms */
#define MAX_CHECK_TIME 90
/* 9s (90 * 100ms) in total */
uint16_t
portid
;
uint8_t
count
,
all_ports_up
,
print_flag
=
0
;
struct
rte_eth_link
link
;
printf
(
"
\n
Checking link status"
);
fflush
(
stdout
);
for
(
count
=
0
;
count
<=
MAX_CHECK_TIME
;
count
++
)
{
if
(
force_quit
)
return
;
all_ports_up
=
1
;
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
(
force_quit
)
return
;
if
((
port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
memset
(
&
link
,
0
,
sizeof
(
link
));
rte_eth_link_get_nowait
(
portid
,
&
link
);
/* print link status if flag set */
if
(
print_flag
==
1
)
{
if
(
link
.
link_status
)
printf
(
"Port%d Link Up. Speed %u Mbps - %s
\n
"
,
portid
,
link
.
link_speed
,
(
link
.
link_duplex
==
ETH_LINK_FULL_DUPLEX
)
?
(
"full-duplex"
)
:
(
"half-duplex
\n
"
));
else
printf
(
"Port %d Link Down
\n
"
,
portid
);
continue
;
}
/* clear all_ports_up flag if any link down */
if
(
link
.
link_status
==
ETH_LINK_DOWN
)
{
all_ports_up
=
0
;
break
;
}
}
/* after finally printing all link status, get out */
if
(
print_flag
==
1
)
break
;
if
(
all_ports_up
==
0
)
{
printf
(
"."
);
fflush
(
stdout
);
rte_delay_ms
(
CHECK_INTERVAL
);
}
/* set the print_flag if all ports up or timeout */
if
(
all_ports_up
==
1
||
count
==
(
MAX_CHECK_TIME
-
1
))
{
print_flag
=
1
;
printf
(
"done
\n
"
);
}
}
}
static
void
signal_handler
(
int
signum
)
{
if
(
signum
==
SIGINT
||
signum
==
SIGTERM
)
{
printf
(
"
\n\n
Signal %d received, preparing to exit...
\n
"
,
signum
);
force_quit
=
true
;
}
}
int
dpdk_main
(
int
argc
,
char
**
argv
,
benetel_t
*
bs
)
{
struct
lcore_queue_conf
*
qconf
;
int
ret
;
uint16_t
nb_ports
;
uint16_t
nb_ports_available
=
0
;
uint16_t
portid
,
last_port
;
unsigned
lcore_id
,
rx_lcore_id
;
unsigned
nb_ports_in_mask
=
0
;
unsigned
int
nb_lcores
=
0
;
unsigned
int
nb_mbufs
;
/* init EAL */
ret
=
rte_eal_init
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid EAL arguments
\n
"
);
argc
-=
ret
;
argv
+=
ret
;
force_quit
=
false
;
signal
(
SIGINT
,
signal_handler
);
signal
(
SIGTERM
,
signal_handler
);
/* parse application arguments (after the EAL ones) */
ret
=
l2fwd_parse_args
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid L2FWD arguments
\n
"
);
printf
(
"MAC updating %s
\n
"
,
mac_updating
?
"enabled"
:
"disabled"
);
/* convert to number of cycles */
timer_period
*=
rte_get_timer_hz
();
nb_ports
=
rte_eth_dev_count_avail
();
if
(
nb_ports
==
0
)
rte_exit
(
EXIT_FAILURE
,
"No Ethernet ports - bye
\n
"
);
/* check port mask to possible port mask */
if
(
l2fwd_enabled_port_mask
&
~
((
1
<<
nb_ports
)
-
1
))
rte_exit
(
EXIT_FAILURE
,
"Invalid portmask; possible (0x%x)
\n
"
,
(
1
<<
nb_ports
)
-
1
);
/* reset l2fwd_dst_ports */
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
l2fwd_dst_ports
[
portid
]
=
0
;
last_port
=
0
;
/*
* Each logical core is assigned a dedicated TX queue on each port.
*/
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
if
(
nb_ports_in_mask
%
2
)
{
l2fwd_dst_ports
[
portid
]
=
last_port
;
l2fwd_dst_ports
[
last_port
]
=
portid
;
}
else
last_port
=
portid
;
nb_ports_in_mask
++
;
}
if
(
nb_ports_in_mask
%
2
)
{
printf
(
"Notice: odd number of ports in portmask.
\n
"
);
l2fwd_dst_ports
[
last_port
]
=
last_port
;
}
rx_lcore_id
=
0
;
qconf
=
NULL
;
/* Initialize the port/queue configuration of each logical core */
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
/* get the lcore_id for this port */
while
(
rte_lcore_is_enabled
(
rx_lcore_id
)
==
0
||
lcore_queue_conf
[
rx_lcore_id
].
n_rx_port
==
l2fwd_rx_queue_per_lcore
)
{
rx_lcore_id
++
;
if
(
rx_lcore_id
>=
RTE_MAX_LCORE
)
rte_exit
(
EXIT_FAILURE
,
"Not enough cores
\n
"
);
}
if
(
qconf
!=
&
lcore_queue_conf
[
rx_lcore_id
])
{
/* Assigned a new logical core in the loop above. */
qconf
=
&
lcore_queue_conf
[
rx_lcore_id
];
nb_lcores
++
;
}
qconf
->
rx_port_list
[
qconf
->
n_rx_port
]
=
portid
;
qconf
->
n_rx_port
++
;
printf
(
"Lcore %u: RX port %u
\n
"
,
rx_lcore_id
,
portid
);
}
nb_mbufs
=
RTE_MAX
(
nb_ports
*
(
nb_rxd
+
nb_txd
+
MAX_PKT_BURST
+
nb_lcores
*
MEMPOOL_CACHE_SIZE
),
8192U
);
/* create the mbuf pool */
l2fwd_pktmbuf_pool
=
rte_pktmbuf_pool_create
(
"mbuf_pool"
,
nb_mbufs
,
MEMPOOL_CACHE_SIZE
,
0
,
9680
,
rte_socket_id
());
if
(
l2fwd_pktmbuf_pool
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot init mbuf pool
\n
"
);
/* Initialise each port */
RTE_ETH_FOREACH_DEV
(
portid
)
{
struct
rte_eth_rxconf
rxq_conf
;
struct
rte_eth_txconf
txq_conf
;
struct
rte_eth_conf
local_port_conf
=
port_conf
;
struct
rte_eth_dev_info
dev_info
;
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"Skipping disabled port %u
\n
"
,
portid
);
continue
;
}
nb_ports_available
++
;
/* init port */
printf
(
"Initializing port %u... "
,
portid
);
fflush
(
stdout
);
rte_eth_dev_info_get
(
portid
,
&
dev_info
);
if
(
dev_info
.
tx_offload_capa
&
DEV_TX_OFFLOAD_MBUF_FAST_FREE
)
local_port_conf
.
txmode
.
offloads
|=
DEV_TX_OFFLOAD_MBUF_FAST_FREE
;
ret
=
rte_eth_dev_configure
(
portid
,
1
,
1
,
&
local_port_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot configure device: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_dev_adjust_nb_rx_tx_desc
(
portid
,
&
nb_rxd
,
&
nb_txd
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot adjust number of descriptors: err=%d, port=%u
\n
"
,
ret
,
portid
);
rte_eth_macaddr_get
(
portid
,
&
l2fwd_ports_eth_addr
[
portid
]);
/* init one RX queue */
fflush
(
stdout
);
rxq_conf
=
dev_info
.
default_rxconf
;
rxq_conf
.
offloads
=
local_port_conf
.
rxmode
.
offloads
;
ret
=
rte_eth_rx_queue_setup
(
portid
,
0
,
nb_rxd
,
rte_eth_dev_socket_id
(
portid
),
&
rxq_conf
,
l2fwd_pktmbuf_pool
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_rx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one TX queue on each port */
fflush
(
stdout
);
txq_conf
=
dev_info
.
default_txconf
;
txq_conf
.
offloads
=
local_port_conf
.
txmode
.
offloads
;
ret
=
rte_eth_tx_queue_setup
(
portid
,
0
,
nb_txd
,
rte_eth_dev_socket_id
(
portid
),
&
txq_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_tx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* Initialize TX buffers */
tx_buffer
[
portid
]
=
rte_zmalloc_socket
(
"tx_buffer"
,
RTE_ETH_TX_BUFFER_SIZE
(
MAX_PKT_BURST
),
0
,
rte_eth_dev_socket_id
(
portid
));
if
(
tx_buffer
[
portid
]
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot allocate buffer for tx on port %u
\n
"
,
portid
);
rte_eth_tx_buffer_init
(
tx_buffer
[
portid
],
MAX_PKT_BURST
);
ret
=
rte_eth_tx_buffer_set_err_callback
(
tx_buffer
[
portid
],
rte_eth_tx_buffer_count_callback
,
&
port_statistics
[
portid
].
dropped
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot set error callback for tx buffer on port %u
\n
"
,
portid
);
/* Start device */
ret
=
rte_eth_dev_start
(
portid
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_dev_start:err=%d, port=%u
\n
"
,
ret
,
portid
);
printf
(
"done:
\n
"
);
rte_eth_promiscuous_enable
(
portid
);
printf
(
"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X
\n\n
"
,
portid
,
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
0
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
1
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
2
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
3
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
4
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
5
]);
/* initialize port stats */
memset
(
&
port_statistics
,
0
,
sizeof
(
port_statistics
));
}
if
(
!
nb_ports_available
)
{
rte_exit
(
EXIT_FAILURE
,
"All available ports are disabled. Please set portmask.
\n
"
);
}
check_all_ports_link_status
(
l2fwd_enabled_port_mask
);
ret
=
0
;
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch
(
l2fwd_launch_one_lcore
,
bs
,
CALL_MASTER
);
RTE_LCORE_FOREACH_SLAVE
(
lcore_id
)
{
if
(
rte_eal_wait_lcore
(
lcore_id
)
<
0
)
{
ret
=
-
1
;
break
;
}
}
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"Closing port %d..."
,
portid
);
rte_eth_dev_stop
(
portid
);
rte_eth_dev_close
(
portid
);
printf
(
" Done
\n
"
);
}
printf
(
"Bye...
\n
"
);
return
ret
;
}
radio/ETHERNET/benetel/4g/low.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "low.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
store_ul
(
benetel_t
*
bs
,
ul_packet_t
*
ul
)
{
int
a
=
ul
->
antenna
;
if
(
ul
->
subframe
!=
bs
->
next_subframe
[
a
]
||
ul
->
symbol
!=
bs
->
next_symbol
[
a
])
{
printf
(
"%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d
\n
"
,
__FUNCTION__
,
a
,
bs
->
expected_benetel_frame
[
a
],
bs
->
next_subframe
[
a
],
bs
->
next_symbol
[
a
],
ul
->
frame
,
ul
->
subframe
,
ul
->
symbol
);
exit
(
1
);
}
lock_ul_buffer
(
bs
->
buffers
,
bs
->
next_subframe
[
a
]);
if
(
bs
->
buffers
->
ul_busy
[
a
][
bs
->
next_subframe
[
a
]]
&
(
1
<<
bs
->
next_symbol
[
a
]))
{
printf
(
"%s: warning, UL overflow (sf.symbol %d.%d)
\n
"
,
__FUNCTION__
,
bs
->
next_subframe
[
a
],
bs
->
next_symbol
[
a
]);
}
memcpy
(
bs
->
buffers
->
ul
[
a
][
bs
->
next_subframe
[
a
]]
+
bs
->
next_symbol
[
a
]
*
1200
*
4
,
ul
->
iq
,
1200
*
4
);
bs
->
buffers
->
ul_busy
[
a
][
bs
->
next_subframe
[
a
]]
|=
(
1
<<
bs
->
next_symbol
[
a
]);
signal_ul_buffer
(
bs
->
buffers
,
bs
->
next_subframe
[
a
]);
unlock_ul_buffer
(
bs
->
buffers
,
bs
->
next_subframe
[
a
]);
bs
->
next_symbol
[
a
]
++
;
if
(
bs
->
next_symbol
[
a
]
==
14
)
{
bs
->
next_symbol
[
a
]
=
0
;
bs
->
next_subframe
[
a
]
=
(
bs
->
next_subframe
[
a
]
+
1
)
%
10
;
if
(
bs
->
next_subframe
[
a
]
==
0
)
{
bs
->
expected_benetel_frame
[
a
]
++
;
bs
->
expected_benetel_frame
[
a
]
&=
255
;
}
}
}
void
store_prach
(
benetel_t
*
bs
,
int
frame
,
int
subframe
,
void
*
data
)
{
static
int
last_frame
=
-
1
;
static
int
last_subframe
=
-
1
;
/* hack: antenna number is always 0, discard second packet with same f/sf */
if
(
frame
==
last_frame
&&
subframe
==
last_subframe
)
return
;
last_frame
=
frame
;
last_subframe
=
subframe
;
lock_ul_buffer
(
bs
->
buffers
,
subframe
);
if
(
bs
->
buffers
->
prach_busy
[
subframe
])
{
printf
(
"store_prach: fatal: previous prach buffer not processed
\n
"
);
unlock_ul_buffer
(
bs
->
buffers
,
subframe
);
return
;
}
bs
->
buffers
->
prach_busy
[
subframe
]
=
1
;
memcpy
(
bs
->
buffers
->
prach
[
subframe
],
data
,
849
*
4
);
signal_ul_buffer
(
bs
->
buffers
,
subframe
);
unlock_ul_buffer
(
bs
->
buffers
,
subframe
);
}
void
*
benetel_start_dpdk
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
);
void
*
benetel_start
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
)
{
if
(
!
strcmp
(
ifname
,
"dpdk"
))
return
benetel_start_dpdk
(
ifname
,
buffers
,
dpdk_main_command_line
);
printf
(
"benetel: fatal: interface %s not supported, only dpdpk is supported
\n
"
,
ifname
);
exit
(
1
);
}
radio/ETHERNET/benetel/4g/low.h
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _BENETEL_4G_LOW_H_
#define _BENETEL_4G_LOW_H_
#include "shared_buffers.h"
typedef
struct
{
shared_buffers
*
buffers
;
/* [2] is for two antennas */
int
next_subframe
[
2
];
int
next_symbol
[
2
];
int
expected_benetel_frame
[
2
];
char
*
dpdk_main_command_line
;
}
benetel_t
;
typedef
struct
{
int
frame
;
int
subframe
;
int
slot
;
int
symbol
;
int
antenna
;
unsigned
char
iq
[
4800
];
}
ul_packet_t
;
void
*
benetel_start
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
);
void
store_ul
(
benetel_t
*
bs
,
ul_packet_t
*
ul
);
void
store_prach
(
benetel_t
*
bs
,
int
frame
,
int
subframe
,
void
*
data
);
#endif
/* _BENETEL_4G_LOW_H_ */
radio/ETHERNET/benetel/4g/low_dpdk.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* those 2 lines for CPU_SET */
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "low.h"
int
dpdk_main
(
int
argc
,
char
**
argv
,
benetel_t
*
);
void
*
dpdk_thread
(
void
*
_bs
)
{
benetel_t
*
bs
=
_bs
;
int
n
=
0
;
char
**
v
=
NULL
;
// { "softmodem", "-n", "2", "-l", "8", "--", "-p", "0x2" };
char
*
s
=
bs
->
dpdk_main_command_line
;
char
*
tok
;
while
((
tok
=
strtok
(
s
,
" "
))
!=
NULL
)
{
n
++
;
v
=
realloc
(
v
,
n
*
sizeof
(
char
*
));
if
(
v
==
NULL
)
{
printf
(
"%s: out of memory
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
v
[
n
-
1
]
=
tok
;
s
=
NULL
;
}
dpdk_main
(
n
,
v
,
bs
);
exit
(
1
);
return
0
;
}
void
*
benetel_start_dpdk
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
)
{
benetel_t
*
bs
;
bs
=
calloc
(
1
,
sizeof
(
benetel_t
));
if
(
bs
==
NULL
)
{
printf
(
"%s: out of memory
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
bs
->
buffers
=
buffers
;
bs
->
expected_benetel_frame
[
0
]
=
255
;
bs
->
expected_benetel_frame
[
1
]
=
255
;
bs
->
dpdk_main_command_line
=
dpdk_main_command_line
;
pthread_attr_t
attr
;
if
(
pthread_attr_init
(
&
attr
)
!=
0
)
{
printf
(
"pthread_attr_init failed
\n
"
);
exit
(
1
);
}
cpu_set_t
cpuset
;
CPU_ZERO
(
&
cpuset
);
CPU_SET
(
12
,
&
cpuset
);
if
(
pthread_attr_setaffinity_np
(
&
attr
,
sizeof
(
cpu_set_t
),
&
cpuset
)
!=
0
)
{
printf
(
"pthread_attr_setaffinity_np failed
\n
"
);
exit
(
1
);
}
if
(
pthread_attr_setschedpolicy
(
&
attr
,
SCHED_FIFO
)
!=
0
)
{
printf
(
"pthread_attr_setschedpolicy failed
\n
"
);
exit
(
1
);
}
struct
sched_param
params
;
params
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
if
(
sched_get_priority_max
(
SCHED_FIFO
)
==
-
1
)
{
printf
(
"sched_get_priority_max failed
\n
"
);
exit
(
1
);
}
if
(
pthread_attr_setschedparam
(
&
attr
,
&
params
)
!=
0
)
{
printf
(
"pthread_setschedparam failed
\n
"
);
exit
(
1
);
}
pthread_t
t
;
if
(
pthread_create
(
&
t
,
&
attr
,
dpdk_thread
,
bs
)
!=
0
)
{
printf
(
"%s: thread creation failed
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
if
(
pthread_attr_destroy
(
&
attr
)
!=
0
)
{
printf
(
"pthread_attr_init failed
\n
"
);
exit
(
1
);
}
return
bs
;
}
radio/ETHERNET/benetel/4g/shared_buffers.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "shared_buffers.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
init_buffers
(
shared_buffers
*
s
)
{
int
subframe
;
memset
(
s
,
0
,
sizeof
(
*
s
));
for
(
subframe
=
0
;
subframe
<
10
;
subframe
++
)
{
if
(
pthread_mutex_init
(
&
s
->
m_dl
[
subframe
],
NULL
)
!=
0
||
pthread_cond_init
(
&
s
->
c_dl
[
subframe
],
NULL
)
!=
0
||
pthread_mutex_init
(
&
s
->
m_ul
[
subframe
],
NULL
)
!=
0
||
pthread_cond_init
(
&
s
->
c_ul
[
subframe
],
NULL
)
!=
0
)
{
printf
(
"%s: error initializing mutex/cond
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
/* in FDD the eNB's first transmitted DL subframe is 4 but the device
* needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready.
*/
s
->
dl_busy
[
0
][
1
]
=
0x3fff
;
s
->
dl_busy
[
0
][
2
]
=
0x3fff
;
s
->
dl_busy
[
0
][
3
]
=
0x3fff
;
s
->
dl_busy
[
1
][
1
]
=
0x3fff
;
s
->
dl_busy
[
1
][
2
]
=
0x3fff
;
s
->
dl_busy
[
1
][
3
]
=
0x3fff
;
}
void
lock_dl_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_mutex_lock
(
&
s
->
m_dl
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: lock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
unlock_dl_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_mutex_unlock
(
&
s
->
m_dl
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: unlock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
wait_dl_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_cond_wait
(
&
s
->
c_dl
[
subframe
],
&
s
->
m_dl
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: cond_wait fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
signal_dl_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_cond_broadcast
(
&
s
->
c_dl
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: cond_broadcast fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
lock_ul_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_mutex_lock
(
&
s
->
m_ul
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: lock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
unlock_ul_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_mutex_unlock
(
&
s
->
m_ul
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: unlock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
wait_ul_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_cond_wait
(
&
s
->
c_ul
[
subframe
],
&
s
->
m_ul
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: cond_wait fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
signal_ul_buffer
(
shared_buffers
*
s
,
int
subframe
)
{
if
(
pthread_cond_broadcast
(
&
s
->
c_ul
[
subframe
])
!=
0
)
{
printf
(
"%s: fatal: cond_broadcast fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
radio/ETHERNET/benetel/4g/shared_buffers.h
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _BENETEL_4G_SHARED_BUFFERS_H_
#define _BENETEL_4G_SHARED_BUFFERS_H_
#include <pthread.h>
#include <stdint.h>
typedef
struct
{
/* [2] is for two antennas */
unsigned
char
dl
[
2
][
10
][
14
*
1200
*
4
];
unsigned
char
ul
[
2
][
10
][
14
*
1200
*
4
];
uint16_t
dl_busy
[
2
][
10
];
uint16_t
ul_busy
[
2
][
10
];
pthread_mutex_t
m_ul
[
10
];
pthread_cond_t
c_ul
[
10
];
pthread_mutex_t
m_dl
[
10
];
pthread_cond_t
c_dl
[
10
];
unsigned
char
prach
[
10
][
849
*
4
];
unsigned
char
prach_busy
[
10
];
/* statistics/error counting */
int
ul_overflow
;
int
dl_underflow
;
}
shared_buffers
;
void
init_buffers
(
shared_buffers
*
s
);
void
lock_dl_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
unlock_dl_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
wait_dl_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
signal_dl_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
lock_ul_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
unlock_ul_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
wait_ul_buffer
(
shared_buffers
*
s
,
int
subframe
);
void
signal_ul_buffer
(
shared_buffers
*
s
,
int
subframe
);
#endif
/* _BENETEL_4G_SHARED_BUFFERS_H_ */
radio/ETHERNET/benetel/5g/CMakeLists.txt
deleted
100644 → 0
View file @
70451408
pkg_check_modules
(
libdpdk REQUIRED libdpdk=20.05.0
)
add_library
(
benetel_5g MODULE
benetel.c
shared_buffers.c
low.c
low_dpdk.c
dpdk_driver.c
)
SET
(
DPDK_LIBS
"-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive"
)
target_include_directories
(
benetel_5g PRIVATE
${
libdpdk_INCLUDE_DIRS
}
)
target_link_libraries
(
benetel_5g PRIVATE
${
libdpdk_LIBRARIES
}
)
target_link_libraries
(
benetel_5g PRIVATE pthread dl rt m numa
)
set_target_properties
(
benetel_5g PROPERTIES COMPILE_FLAGS
"-fvisibility=hidden -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include"
)
set_target_properties
(
benetel_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${
CMAKE_BINARY_DIR
}
)
add_custom_command
(
TARGET benetel_5g POST_BUILD
COMMAND
${
CMAKE_COMMAND
}
-E create_symlink libbenetel_5g.so liboai_transpro.so
WORKING_DIRECTORY
${
CMAKE_BINARY_DIR
}
)
radio/ETHERNET/benetel/5g/benetel.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#include "shared_buffers.h"
#include "low.h"
#include "openair1/PHY/defs_gNB.h"
typedef
struct
{
eth_state_t
e
;
shared_buffers
buffers
;
rru_config_msg_type_t
last_msg
;
int
capabilities_sent
;
void
*
benetel_priv
;
char
*
dpdk_main_command_line
;
}
benetel_eth_state_t
;
int
trx_benetel_start
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
0
;
}
void
trx_benetel_end
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
}
int
trx_benetel_stop
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_get_stats
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
trx_benetel_reset_stats
(
openair0_device
*
device
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
(
0
);
}
int
ethernet_tune
(
openair0_device
*
device
,
unsigned
int
option
,
int
value
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
0
;
}
int
trx_benetel_write_raw
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
nsamps
*
4
;
}
int
trx_benetel_read_raw
(
openair0_device
*
device
,
openair0_timestamp
*
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
return
nsamps
*
4
;
}
char
*
msg_type
(
int
t
)
{
static
char
*
s
[
12
]
=
{
"RAU_tick"
,
"RRU_capabilities"
,
"RRU_config"
,
"RRU_config_ok"
,
"RRU_start"
,
"RRU_stop"
,
"RRU_sync_ok"
,
"RRU_frame_resynch"
,
"RRU_MSG_max_num"
,
"RRU_check_sync"
,
"RRU_config_update"
,
"RRU_config_update_ok"
,
};
if
(
t
<
0
||
t
>
11
)
return
"UNKNOWN"
;
return
s
[
t
];
}
int
trx_benetel_ctlsend
(
openair0_device
*
device
,
void
*
msg
,
ssize_t
msg_len
)
{
RRU_CONFIG_msg_t
*
rru_config_msg
=
msg
;
benetel_eth_state_t
*
s
=
device
->
priv
;
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
printf
(
" rru_config_msg->type %d [%s]
\n
"
,
rru_config_msg
->
type
,
msg_type
(
rru_config_msg
->
type
));
s
->
last_msg
=
rru_config_msg
->
type
;
return
msg_len
;
}
int
trx_benetel_ctlrecv
(
openair0_device
*
device
,
void
*
msg
,
ssize_t
msg_len
)
{
RRU_CONFIG_msg_t
*
rru_config_msg
=
msg
;
benetel_eth_state_t
*
s
=
device
->
priv
;
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
if
(
s
->
last_msg
==
RAU_tick
&&
s
->
capabilities_sent
==
0
)
{
RRU_capabilities_t
*
cap
;
rru_config_msg
->
type
=
RRU_capabilities
;
rru_config_msg
->
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_capabilities_t
);
cap
=
(
RRU_capabilities_t
*
)
&
rru_config_msg
->
msg
[
0
];
cap
->
FH_fmt
=
OAI_IF4p5_only
;
cap
->
num_bands
=
1
;
cap
->
band_list
[
0
]
=
78
;
/* TODO: hardcoded to 1 for the moment, get the real value somehow... */
cap
->
nb_rx
[
0
]
=
1
;
//device->openair0_cfg->rx_num_channels;
cap
->
nb_tx
[
0
]
=
1
;
//device->openair0_cfg->tx_num_channels;
cap
->
max_pdschReferenceSignalPower
[
0
]
=
-
27
;
cap
->
max_rxgain
[
0
]
=
90
;
s
->
capabilities_sent
=
1
;
return
rru_config_msg
->
len
;
}
#if 0
if (s->last_msg == RRU_config) {
rru_config_msg->type = RRU_config_ok;
return 0;
}
if (s->last_msg == RRU_start) {
printf("***************** benetel start\n");
s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line);
}
#endif
if
(
s
->
last_msg
==
RRU_config
)
{
rru_config_msg
->
type
=
RRU_config_ok
;
s
->
benetel_priv
=
benetel_start
(
s
->
e
.
if_name
,
&
s
->
buffers
,
s
->
dpdk_main_command_line
);
}
/* correct? */
//printf("***************** benetel pause\n");
// while (1) pause();
return
0
;
}
void
benetel_fh_if4p5_south_in
(
RU_t
*
ru
,
int
*
frame
,
int
*
slot
)
{
//printf("XXX benetel_fh_if4p5_south_in %d %d\n", *frame, *slot);
benetel_eth_state_t
*
s
=
ru
->
ifdevice
.
priv
;
NR_DL_FRAME_PARMS
*
fp
;
int
symbol
;
int32_t
*
rxdata
;
int
antenna
;
lock_ul_buffer
(
&
s
->
buffers
,
*
slot
);
#if 1
next:
while
(
!
((
s
->
buffers
.
ul_busy
[
0
][
*
slot
]
==
0x3fff
&&
s
->
buffers
.
ul_busy
[
1
][
*
slot
]
==
0x3fff
)
||
s
->
buffers
.
prach_busy
[
*
slot
]
==
1
))
wait_ul_buffer
(
&
s
->
buffers
,
*
slot
);
if
(
s
->
buffers
.
prach_busy
[
*
slot
]
==
1
)
{
int
i
;
int
antenna
=
0
;
uint16_t
*
in
;
uint16_t
*
out
;
in
=
(
uint16_t
*
)
s
->
buffers
.
prach
[
*
slot
];
out
=
(
uint16_t
*
)
ru
->
prach_rxsigF
[
0
][
antenna
];
for
(
i
=
0
;
i
<
839
*
2
;
i
++
)
out
[
i
]
=
ntohs
(
in
[
i
]);
s
->
buffers
.
prach_busy
[
*
slot
]
=
0
;
//printf("prach for f.sl %d.%d\n", *frame, *slot);
//ru->wakeup_prach_gNB(ru->gNB_list[0], ru, *frame, *slot);
goto
next
;
}
#endif
fp
=
ru
->
nr_frame_parms
;
for
(
antenna
=
0
;
antenna
<
ru
->
nb_rx
;
antenna
++
)
{
for
(
symbol
=
0
;
symbol
<
14
;
symbol
++
)
{
int
i
;
int16_t
*
p
=
(
int16_t
*
)(
&
s
->
buffers
.
ul
[
antenna
][
*
slot
][
symbol
*
1272
*
4
]);
for
(
i
=
0
;
i
<
1272
*
2
;
i
++
)
{
p
[
i
]
=
(
int16_t
)(
ntohs
(
p
[
i
]))
/
16
;
}
rxdata
=
&
ru
->
common
.
rxdataF
[
antenna
][
symbol
*
fp
->
ofdm_symbol_size
];
#if 0
if (*slot == 0 && symbol == 0)
printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]);
#endif
#if 1
memcpy
(
rxdata
+
2048
-
1272
/
2
,
&
s
->
buffers
.
ul
[
antenna
][
*
slot
][
symbol
*
1272
*
4
],
(
1272
/
2
)
*
4
);
memcpy
(
rxdata
,
&
s
->
buffers
.
ul
[
antenna
][
*
slot
][
symbol
*
1272
*
4
]
+
(
1272
/
2
)
*
4
,
(
1272
/
2
)
*
4
);
#endif
}
}
s
->
buffers
.
ul_busy
[
0
][
*
slot
]
=
0
;
s
->
buffers
.
ul_busy
[
1
][
*
slot
]
=
0
;
signal_ul_buffer
(
&
s
->
buffers
,
*
slot
);
unlock_ul_buffer
(
&
s
->
buffers
,
*
slot
);
//printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *slot);
RU_proc_t
*
proc
=
&
ru
->
proc
;
int
f
=
*
frame
;
int
sl
=
*
slot
;
//calculate timestamp_rx, timestamp_tx based on frame and slot
proc
->
tti_rx
=
sl
;
proc
->
frame_rx
=
f
;
/* TODO: be sure of samples_per_slot0
FK: should use get_samples_per_slot(slot)
but for mu=1 its ok
*/
proc
->
timestamp_rx
=
((
proc
->
frame_rx
*
20
)
+
proc
->
tti_rx
)
*
fp
->
samples_per_slot0
;
if
(
get_nprocs
()
<=
4
)
{
// why? what if there are more?
proc
->
tti_tx
=
(
sl
+
ru
->
sl_ahead
)
%
20
;
proc
->
frame_tx
=
(
sl
>
(
19
-
ru
->
sl_ahead
))
?
(
f
+
1
)
&
1023
:
f
;
}
}
void
benetel_fh_if4p5_south_out
(
RU_t
*
ru
,
int
frame
,
int
slot
,
uint64_t
timestamp
)
{
//printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp);
benetel_eth_state_t
*
s
=
ru
->
ifdevice
.
priv
;
NR_DL_FRAME_PARMS
*
fp
;
int
symbol
;
int32_t
*
txdata
;
int
aa
;
//printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp);
lock_dl_buffer
(
&
s
->
buffers
,
slot
);
if
(
s
->
buffers
.
dl_busy
[
0
][
slot
]
||
s
->
buffers
.
dl_busy
[
1
][
slot
])
{
printf
(
"%s: fatal: DL buffer busy for subframe %d
\n
"
,
__FUNCTION__
,
slot
);
unlock_dl_buffer
(
&
s
->
buffers
,
slot
);
return
;
}
fp
=
ru
->
nr_frame_parms
;
if
(
ru
->
num_gNB
!=
1
||
fp
->
ofdm_symbol_size
!=
2048
||
fp
->
Ncp
!=
NORMAL
||
fp
->
symbols_per_slot
!=
14
)
{
printf
(
"%s:%d:%s: unsupported configuration
\n
"
,
__FILE__
,
__LINE__
,
__FUNCTION__
);
exit
(
1
);
}
for
(
aa
=
0
;
aa
<
ru
->
nb_tx
;
aa
++
)
{
for
(
symbol
=
0
;
symbol
<
14
;
symbol
++
)
{
txdata
=
&
ru
->
common
.
txdataF_BF
[
aa
][
symbol
*
fp
->
ofdm_symbol_size
];
#if 1
memcpy
(
&
s
->
buffers
.
dl
[
aa
][
slot
][
symbol
*
1272
*
4
],
txdata
+
2048
-
(
1272
/
2
),
(
1272
/
2
)
*
4
);
memcpy
(
&
s
->
buffers
.
dl
[
aa
][
slot
][
symbol
*
1272
*
4
]
+
(
1272
/
2
)
*
4
,
txdata
,
(
1272
/
2
)
*
4
);
#endif
int
i
;
uint16_t
*
p
=
(
uint16_t
*
)(
&
s
->
buffers
.
dl
[
aa
][
slot
][
symbol
*
1272
*
4
]);
for
(
i
=
0
;
i
<
1272
*
2
;
i
++
)
{
p
[
i
]
=
htons
(
p
[
i
]);
}
}
}
s
->
buffers
.
dl_busy
[
0
][
slot
]
=
0x3fff
;
s
->
buffers
.
dl_busy
[
1
][
slot
]
=
0x3fff
;
unlock_dl_buffer
(
&
s
->
buffers
,
slot
);
}
void
*
get_internal_parameter
(
char
*
name
)
{
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
if
(
!
strcmp
(
name
,
"fh_if4p5_south_in"
))
return
benetel_fh_if4p5_south_in
;
if
(
!
strcmp
(
name
,
"fh_if4p5_south_out"
))
return
benetel_fh_if4p5_south_out
;
return
NULL
;
}
__attribute__
((
__visibility__
(
"default"
)))
int
transport_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
eth_params_t
*
eth_params
)
{
benetel_eth_state_t
*
eth
;
printf
(
"BENETEL: %s
\n
"
,
__FUNCTION__
);
device
->
Mod_id
=
0
;
device
->
transp_type
=
ETHERNET_TP
;
device
->
trx_start_func
=
trx_benetel_start
;
device
->
trx_get_stats_func
=
trx_benetel_get_stats
;
device
->
trx_reset_stats_func
=
trx_benetel_reset_stats
;
device
->
trx_end_func
=
trx_benetel_end
;
device
->
trx_stop_func
=
trx_benetel_stop
;
device
->
trx_set_freq_func
=
trx_benetel_set_freq
;
device
->
trx_set_gains_func
=
trx_benetel_set_gains
;
device
->
trx_write_func
=
trx_benetel_write_raw
;
device
->
trx_read_func
=
trx_benetel_read_raw
;
device
->
trx_ctlsend_func
=
trx_benetel_ctlsend
;
device
->
trx_ctlrecv_func
=
trx_benetel_ctlrecv
;
device
->
get_internal_parameter
=
get_internal_parameter
;
eth
=
calloc
(
1
,
sizeof
(
benetel_eth_state_t
));
if
(
eth
==
NULL
)
{
AssertFatal
(
0
==
1
,
"out of memory
\n
"
);
}
eth
->
e
.
flags
=
ETH_RAW_IF4p5_MODE
;
eth
->
e
.
compression
=
NO_COMPRESS
;
eth
->
e
.
if_name
=
eth_params
->
local_if_name
;
device
->
priv
=
eth
;
device
->
openair0_cfg
=&
openair0_cfg
[
0
];
if
(
openair0_cfg
->
sdr_addrs
==
NULL
)
{
printf
(
"benetel: fatal: sdr_addrs not set in configuration file
\n
"
);
exit
(
1
);
}
eth
->
dpdk_main_command_line
=
strdup
(
openair0_cfg
->
sdr_addrs
);
if
(
eth
->
dpdk_main_command_line
==
NULL
)
{
AssertFatal
(
0
==
1
,
"out of memory
\n
"
);
}
eth
->
last_msg
=
-
1
;
init_buffers
(
&
eth
->
buffers
);
return
0
;
}
radio/ETHERNET/benetel/5g/dpdk_driver.c
deleted
100644 → 0
View file @
70451408
/* license: to be defined */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include "low.h"
// HEADER DEFINITION
#define ANT_NUM buf[23]
#define PAYLOAD_1 buf[20]
#define PAYLOAD_2 buf[21]
#define ETH_TYPE buf[17]
#define SYMBOL buf[29]
#define SUBFRAME buf[28]
#define FRAME buf[27]
static
volatile
bool
force_quit
;
unsigned
short
iq
[
712320
];
unsigned
char
iq_swap
[
1424640
];
unsigned
short
*
iq_ptr
[
14
];
unsigned
int
dl_start
=
0
,
slot_id_ctrl
=
0
,
count_symbol
=
0
,
sf
=
0x10
;
/* MAC updating enabled by default */
static
int
mac_updating
=
1
;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 5
/* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static
uint16_t
nb_rxd
=
RTE_TEST_RX_DESC_DEFAULT
;
static
uint16_t
nb_txd
=
RTE_TEST_TX_DESC_DEFAULT
;
/* ethernet addresses of ports */
static
struct
ether_addr
l2fwd_ports_eth_addr
[
RTE_MAX_ETHPORTS
];
/* mask of enabled ports */
static
uint32_t
l2fwd_enabled_port_mask
=
0
;
/* list of enabled ports */
static
uint32_t
l2fwd_dst_ports
[
RTE_MAX_ETHPORTS
];
static
unsigned
int
l2fwd_rx_queue_per_lcore
=
1
;
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct
lcore_queue_conf
{
unsigned
n_rx_port
;
unsigned
rx_port_list
[
MAX_RX_QUEUE_PER_LCORE
];
}
__rte_cache_aligned
;
struct
lcore_queue_conf
lcore_queue_conf
[
RTE_MAX_LCORE
];
static
struct
rte_eth_dev_tx_buffer
*
tx_buffer
[
RTE_MAX_ETHPORTS
];
static
struct
rte_eth_conf
port_conf
=
{
.
rxmode
=
{
.
split_hdr_size
=
0
,
.
offloads
=
DEV_RX_OFFLOAD_JUMBO_FRAME
,
.
split_hdr_size
=
0
,
.
max_rx_pkt_len
=
9500
,
},
.
txmode
=
{
.
mq_mode
=
ETH_MQ_TX_NONE
,
},
};
struct
rte_mempool
*
l2fwd_pktmbuf_pool
=
NULL
;
/* Per-port statistics struct */
struct
l2fwd_port_statistics
{
uint64_t
tx
;
uint64_t
rx
;
uint64_t
dropped
;
}
__rte_cache_aligned
;
struct
l2fwd_port_statistics
port_statistics
[
RTE_MAX_ETHPORTS
];
#define MAX_TIMER_PERIOD 86400
/* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
static
uint64_t
timer_period
=
10
;
/* default period is 10 seconds */
/* Print out statistics on packets dropped */
static
void
print_stats
(
void
)
{
uint64_t
total_packets_dropped
,
total_packets_tx
,
total_packets_rx
;
unsigned
portid
;
total_packets_dropped
=
0
;
total_packets_tx
=
0
;
total_packets_rx
=
0
;
const
char
clr
[]
=
{
27
,
'['
,
'2'
,
'J'
,
'\0'
};
const
char
topLeft
[]
=
{
27
,
'['
,
'1'
,
';'
,
'1'
,
'H'
,
'\0'
};
/* Clear screen and move to top left */
printf
(
"%s%s"
,
clr
,
topLeft
);
printf
(
"
\n
Port statistics ===================================="
);
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
{
/* skip disabled ports */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"
\n
Statistics for port %u ------------------------------"
"
\n
Packets sent: %24"
PRIu64
"
\n
Packets received: %20"
PRIu64
"
\n
Packets dropped: %21"
PRIu64
,
portid
,
port_statistics
[
portid
].
tx
,
port_statistics
[
portid
].
rx
,
port_statistics
[
portid
].
dropped
);
total_packets_dropped
+=
port_statistics
[
portid
].
dropped
;
total_packets_tx
+=
port_statistics
[
portid
].
tx
;
total_packets_rx
+=
port_statistics
[
portid
].
rx
;
}
printf
(
"
\n
Aggregate statistics ==============================="
"
\n
Total packets sent: %18"
PRIu64
"
\n
Total packets received: %14"
PRIu64
"
\n
Total packets dropped: %15"
PRIu64
,
total_packets_tx
,
total_packets_rx
,
total_packets_dropped
);
printf
(
"
\n
====================================================
\n
"
);
}
static
void
l2fwd_simple_forward
(
struct
rte_mbuf
*
m
,
unsigned
portid
,
benetel_t
*
bs
)
{
unsigned
char
*
buf
,
*
buf_tx
;
unsigned
int
len
;
struct
ether_hdr
*
eth
;
unsigned
dst_port
;
int
sent
,
prach_ctrl
=
0
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
unsigned
char
*
IQ_ptr
;
ul_packet_t
p
;
buf
=
rte_pktmbuf_mtod
(
m
,
unsigned
char
*
);
//DD Debug
//rte_memdump(stdout, "Rx Packet",buf ,34);
eth
=
rte_pktmbuf_mtod
(
m
,
struct
ether_hdr
*
);
len
=
rte_pktmbuf_data_len
(
m
);
IQ_ptr
=
&
buf
[
34
];
if
(
portid
==
0
)
{
//destination mac address (RRU MAC)
/*eth->d_addr.addr_bytes[0] = 0x02;
eth->d_addr.addr_bytes[1] = 0x00;
eth->d_addr.addr_bytes[2] = 0x5e;
eth->d_addr.addr_bytes[3] = 0x01;
eth->d_addr.addr_bytes[4] = 0x01;
eth->d_addr.addr_bytes[5] = 0x01;*/
eth
->
d_addr
.
addr_bytes
[
0
]
=
buf
[
6
];
eth
->
d_addr
.
addr_bytes
[
1
]
=
buf
[
7
];
eth
->
d_addr
.
addr_bytes
[
2
]
=
buf
[
8
];
eth
->
d_addr
.
addr_bytes
[
3
]
=
buf
[
9
];
eth
->
d_addr
.
addr_bytes
[
4
]
=
buf
[
10
];
eth
->
d_addr
.
addr_bytes
[
5
]
=
buf
[
11
];
//source mac address (DU MAC)
eth
->
s_addr
.
addr_bytes
[
0
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
1
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
2
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
3
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
4
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
5
]
=
0xdd
;
}
else
{
//destination mac address (RRU MAC)
/*eth->d_addr.addr_bytes[0] = 0x02;
eth->d_addr.addr_bytes[1] = 0x00;
eth->d_addr.addr_bytes[2] = 0x5e;
eth->d_addr.addr_bytes[3] = 0x01;
eth->d_addr.addr_bytes[4] = 0x01;
eth->d_addr.addr_bytes[5] = 0x01;*/
eth
->
d_addr
.
addr_bytes
[
0
]
=
buf
[
6
];
eth
->
d_addr
.
addr_bytes
[
1
]
=
buf
[
7
];
eth
->
d_addr
.
addr_bytes
[
2
]
=
buf
[
8
];
eth
->
d_addr
.
addr_bytes
[
3
]
=
buf
[
9
];
eth
->
d_addr
.
addr_bytes
[
4
]
=
buf
[
10
];
eth
->
d_addr
.
addr_bytes
[
5
]
=
buf
[
11
];
//source mac address (DU MAC)
eth
->
s_addr
.
addr_bytes
[
0
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
1
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
2
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
3
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
4
]
=
0xdd
;
eth
->
s_addr
.
addr_bytes
[
5
]
=
0xde
;
}
dst_port
=
l2fwd_dst_ports
[
portid
];
//DD Debug
//printf("dstPort =%d\n", dst_port);
// Handshake Condition
if
(
buf
[
18
]
==
0xAA
)
// ORAN handshake msgs.
{
printf
(
"
\n
Start UP Request Received
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
buf
[
18
]
=
0xBB
;
//change to msg2 after receive msg1
printf
(
" Start Up Response Sent
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
}
// Trigger start send DL packets
if
(
PAYLOAD_1
==
0x13
&&
PAYLOAD_2
==
0xe4
&&
SYMBOL
==
0x44
&&
ANT_NUM
==
0x00
&&
SUBFRAME
==
0x00
&&
dl_start
==
0
){
printf
(
"
\n
U-Plane Started
\n
"
);
printf
(
"
\n
====================================================
\n
"
);
dl_start
=
1
;
count_symbol
=
28
;
}
if
(
PAYLOAD_1
==
0x13
&&
PAYLOAD_2
==
0xe4
)
{
int
subframe
=
SUBFRAME
>>
4
;
int
slot
=
((
SUBFRAME
&
0x0f
)
<<
2
)
|
((
SYMBOL
>>
6
)
&
0x03
);
p
.
frame
=
FRAME
;
p
.
slot
=
subframe
*
2
+
slot
;
p
.
symbol
=
SYMBOL
&
0x3f
;
p
.
antenna
=
ANT_NUM
;
memcpy
(
p
.
iq
,
IQ_ptr
,
5088
);
store_ul
(
bs
,
&
p
);
// if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol);
}
// U-PLANE UL PROCESSING
if
(
PAYLOAD_1
==
0x13
&&
PAYLOAD_2
==
0xe4
&&
dl_start
==
1
)
{
int
a
=
ANT_NUM
&
0x01
;
int
frame
=
FRAME
;
int
subframe
=
SUBFRAME
>>
4
;
int
slot
=
((
SUBFRAME
&
0x0f
)
<<
2
)
|
((
SYMBOL
>>
6
)
&
0x03
);
int
symbol
=
SYMBOL
&
0x3f
;
int
oai_slot
;
int
tx_frame
=
frame
;
int
tx_subframe
=
subframe
;
int
tx_slot
=
slot
;
int
tx_symbol
=
symbol
+
10
;
if
(
tx_symbol
>
13
)
{
tx_symbol
-=
14
;
tx_slot
++
;
if
(
tx_slot
==
2
)
{
tx_slot
=
0
;
tx_subframe
++
;
if
(
tx_subframe
==
10
)
{
tx_subframe
=
0
;
tx_frame
=
(
tx_frame
+
1
)
&
255
;
}
}
}
// Mask the symbol bits from UL packet received and apply the shift.
SYMBOL
=
((
SYMBOL
&
0
b00111111
)
+
10
)
%
14
;
ANT_NUM
=
a
;
SUBFRAME
=
sf
;
if
(
a
==
1
)
slot_id_ctrl
++
;
// Slot id control for DL
if
(
slot_id_ctrl
>
13
)
{
SYMBOL
=
SYMBOL
|
0
b01000000
;
if
(
a
==
1
)
{
if
(
slot_id_ctrl
>
27
)
{
slot_id_ctrl
=
0
;
sf
=
sf
+
0x10
;
if
(
sf
>
0x90
){
sf
=
0
;
}
}
}
}
/* send actual DL data (if available) */
oai_slot
=
tx_subframe
*
2
+
tx_slot
;
lock_dl_buffer
(
bs
->
buffers
,
oai_slot
);
if
(
!
(
bs
->
buffers
->
dl_busy
[
a
][
oai_slot
]
&
(
1
<<
tx_symbol
)))
{
//printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__,a, oai_slot, tx_symbol);
memset
(
IQ_ptr
,
0
,
1272
*
4
);
}
else
{
memcpy
(
IQ_ptr
,
bs
->
buffers
->
dl
[
a
][
oai_slot
]
+
tx_symbol
*
1272
*
4
,
1272
*
4
);
}
//printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf);
bs
->
buffers
->
dl_busy
[
a
][
oai_slot
]
&=
~
(
1
<<
tx_symbol
);
unlock_dl_buffer
(
bs
->
buffers
,
oai_slot
);
}
// U-PLANE PRACH PROCESSING
else
if
(
PAYLOAD_1
==
0x0d
&&
PAYLOAD_2
==
0x28
){
if
(
ANT_NUM
==
0
)
{
int
subframe
=
SUBFRAME
>>
4
;
//int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03);
if
(
subframe
==
9
)
{
//printf("store prach f.sf.sl %d.%d.%d %d\n", FRAME, subframe, slot, subframe * 2 + slot);
store_prach
(
bs
,
FRAME
,
subframe
*
2
+
1
,
IQ_ptr
);
}
}
rte_pktmbuf_free
(
m
);
return
;
}
// Send Packets
buffer
=
tx_buffer
[
dst_port
];
sent
=
rte_eth_tx_buffer
(
dst_port
,
0
,
buffer
,
m
);
if
(
sent
)
port_statistics
[
dst_port
].
tx
+=
sent
;
}
/* main processing loop */
static
void
l2fwd_main_loop
(
benetel_t
*
bs
)
{
struct
rte_mbuf
*
pkts_burst
[
MAX_PKT_BURST
];
struct
rte_mbuf
*
m
;
int
sent
;
unsigned
lcore_id
;
uint64_t
prev_tsc
,
diff_tsc
,
cur_tsc
,
timer_tsc
;
unsigned
i
,
j
,
portid
,
nb_rx
;
struct
lcore_queue_conf
*
qconf
;
const
uint64_t
drain_tsc
=
(
rte_get_tsc_hz
()
+
US_PER_S
-
1
)
/
US_PER_S
*
BURST_TX_DRAIN_US
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
prev_tsc
=
0
;
timer_tsc
=
0
;
lcore_id
=
rte_lcore_id
();
qconf
=
&
lcore_queue_conf
[
lcore_id
];
if
(
qconf
->
n_rx_port
==
0
)
{
RTE_LOG
(
INFO
,
L2FWD
,
"lcore %u has nothing to do
\n
"
,
lcore_id
);
return
;
}
RTE_LOG
(
INFO
,
L2FWD
,
"entering main loop on lcore %u
\n
"
,
lcore_id
);
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
RTE_LOG
(
INFO
,
L2FWD
,
" -- lcoreid=%u portid=%u
\n
"
,
lcore_id
,
portid
);
}
while
(
!
force_quit
)
{
cur_tsc
=
rte_rdtsc
();
/*
* TX burst queue drain
*/
diff_tsc
=
cur_tsc
-
prev_tsc
;
if
(
unlikely
(
diff_tsc
>
drain_tsc
))
{
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
l2fwd_dst_ports
[
qconf
->
rx_port_list
[
i
]];
buffer
=
tx_buffer
[
portid
];
sent
=
rte_eth_tx_buffer_flush
(
portid
,
0
,
buffer
);
if
(
sent
)
port_statistics
[
portid
].
tx
+=
sent
;
}
/* if timer is enabled */
if
(
timer_period
>
0
)
{
/* advance the timer */
timer_tsc
+=
diff_tsc
;
/* if timer has reached its timeout */
if
(
unlikely
(
timer_tsc
>=
timer_period
))
{
/* do this only on master core */
if
(
lcore_id
==
rte_get_master_lcore
())
{
print_stats
();
/* reset the timer */
timer_tsc
=
0
;
}
}
}
prev_tsc
=
cur_tsc
;
}
/*
* Read packet from RX queues
*/
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
nb_rx
=
rte_eth_rx_burst
(
portid
,
0
,
pkts_burst
,
MAX_PKT_BURST
);
port_statistics
[
portid
].
rx
+=
nb_rx
;
for
(
j
=
0
;
j
<
nb_rx
;
j
++
)
{
m
=
pkts_burst
[
j
];
rte_prefetch0
(
rte_pktmbuf_mtod
(
m
,
void
*
));
l2fwd_simple_forward
(
m
,
portid
,
bs
);
}
}
}
}
static
int
l2fwd_launch_one_lcore
(
void
*
bs
)
{
l2fwd_main_loop
(
bs
);
return
0
;
}
/* display usage */
static
void
l2fwd_usage
(
const
char
*
prgname
)
{
printf
(
"%s [EAL options] -- -p PORTMASK [-q NQ]
\n
"
" -p PORTMASK: hexadecimal bitmask of ports to configure
\n
"
" -q NQ: number of queue (=ports) per lcore (default is 1)
\n
"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)
\n
"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)
\n
"
" When enabled:
\n
"
" - The source MAC address is replaced by the TX port MAC address
\n
"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
\n
"
,
prgname
);
}
static
int
l2fwd_parse_portmask
(
const
char
*
portmask
)
{
char
*
end
=
NULL
;
unsigned
long
pm
;
/* parse hexadecimal string */
pm
=
strtoul
(
portmask
,
&
end
,
16
);
if
((
portmask
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
pm
==
0
)
return
-
1
;
return
pm
;
}
static
unsigned
int
l2fwd_parse_nqueue
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
unsigned
long
n
;
/* parse hexadecimal string */
n
=
strtoul
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
if
(
n
==
0
)
return
0
;
if
(
n
>=
MAX_RX_QUEUE_PER_LCORE
)
return
0
;
return
n
;
}
static
int
l2fwd_parse_timer_period
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
int
n
;
/* parse number string */
n
=
strtol
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
n
>=
MAX_TIMER_PERIOD
)
return
-
1
;
return
n
;
}
static
const
char
short_options
[]
=
"p:"
/* portmask */
"q:"
/* number of queues */
"T:"
/* timer period */
;
#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
enum
{
/* long options mapped to a short option */
/* first long only option value must be >= 256, so that we won't
* conflict with short options */
CMD_LINE_OPT_MIN_NUM
=
256
,
};
static
const
struct
option
lgopts
[]
=
{
{
CMD_LINE_OPT_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
1
},
{
CMD_LINE_OPT_NO_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
0
},
{
NULL
,
0
,
0
,
0
}
};
/* Parse the argument given in the command line of the application */
static
int
l2fwd_parse_args
(
int
argc
,
char
**
argv
)
{
int
opt
,
ret
,
timer_secs
;
char
**
argvopt
;
int
option_index
;
char
*
prgname
=
argv
[
0
];
argvopt
=
argv
;
while
((
opt
=
getopt_long
(
argc
,
argvopt
,
short_options
,
lgopts
,
&
option_index
))
!=
EOF
)
{
switch
(
opt
)
{
/* portmask */
case
'p'
:
l2fwd_enabled_port_mask
=
l2fwd_parse_portmask
(
optarg
);
if
(
l2fwd_enabled_port_mask
==
0
)
{
printf
(
"invalid portmask
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* nqueue */
case
'q'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
case
'T'
:
timer_secs
=
l2fwd_parse_timer_period
(
optarg
);
if
(
timer_secs
<
0
)
{
printf
(
"invalid timer period
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
timer_period
=
timer_secs
;
break
;
/* long options */
case
0
:
break
;
case
'
proc
-
type
'
:
break
;
case
'
socket
-
mem
'
:
break
;
case
'
file
-
prefix
'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
/* timer period */
/* timer period */
default:
l2fwd_usage
(
prgname
);
return
-
1
;
}
}
if
(
optind
>=
0
)
argv
[
optind
-
1
]
=
prgname
;
ret
=
optind
-
1
;
optind
=
1
;
/* reset getopt lib */
return
ret
;
}
/* Check the link status of all ports in up to 9s, and print them finally */
static
void
check_all_ports_link_status
(
uint32_t
port_mask
)
{
#define CHECK_INTERVAL 100
/* 100ms */
#define MAX_CHECK_TIME 90
/* 9s (90 * 100ms) in total */
uint16_t
portid
;
uint8_t
count
,
all_ports_up
,
print_flag
=
0
;
struct
rte_eth_link
link
;
printf
(
"
\n
Checking link status"
);
fflush
(
stdout
);
for
(
count
=
0
;
count
<=
MAX_CHECK_TIME
;
count
++
)
{
if
(
force_quit
)
return
;
all_ports_up
=
1
;
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
(
force_quit
)
return
;
if
((
port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
memset
(
&
link
,
0
,
sizeof
(
link
));
rte_eth_link_get_nowait
(
portid
,
&
link
);
/* print link status if flag set */
if
(
print_flag
==
1
)
{
if
(
link
.
link_status
)
printf
(
"Port%d Link Up. Speed %u Mbps - %s
\n
"
,
portid
,
link
.
link_speed
,
(
link
.
link_duplex
==
ETH_LINK_FULL_DUPLEX
)
?
(
"full-duplex"
)
:
(
"half-duplex
\n
"
));
else
printf
(
"Port %d Link Down
\n
"
,
portid
);
continue
;
}
/* clear all_ports_up flag if any link down */
if
(
link
.
link_status
==
ETH_LINK_DOWN
)
{
all_ports_up
=
0
;
break
;
}
}
/* after finally printing all link status, get out */
if
(
print_flag
==
1
)
break
;
if
(
all_ports_up
==
0
)
{
printf
(
"."
);
fflush
(
stdout
);
rte_delay_ms
(
CHECK_INTERVAL
);
}
/* set the print_flag if all ports up or timeout */
if
(
all_ports_up
==
1
||
count
==
(
MAX_CHECK_TIME
-
1
))
{
print_flag
=
1
;
printf
(
"done
\n
"
);
}
}
}
static
void
signal_handler
(
int
signum
)
{
if
(
signum
==
SIGINT
||
signum
==
SIGTERM
)
{
printf
(
"
\n\n
Signal %d received, preparing to exit...
\n
"
,
signum
);
force_quit
=
true
;
}
}
int
dpdk_main
(
int
argc
,
char
**
argv
,
benetel_t
*
bs
)
{
struct
lcore_queue_conf
*
qconf
;
int
ret
;
uint16_t
nb_ports
;
uint16_t
nb_ports_available
=
0
;
uint16_t
portid
,
last_port
;
unsigned
lcore_id
,
rx_lcore_id
;
unsigned
nb_ports_in_mask
=
0
;
unsigned
int
nb_lcores
=
0
;
unsigned
int
nb_mbufs
;
/* init EAL */
ret
=
rte_eal_init
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid EAL arguments
\n
"
);
argc
-=
ret
;
argv
+=
ret
;
force_quit
=
false
;
signal
(
SIGINT
,
signal_handler
);
signal
(
SIGTERM
,
signal_handler
);
/* parse application arguments (after the EAL ones) */
ret
=
l2fwd_parse_args
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid L2FWD arguments
\n
"
);
printf
(
"MAC updating %s
\n
"
,
mac_updating
?
"enabled"
:
"disabled"
);
/* convert to number of cycles */
timer_period
*=
rte_get_timer_hz
();
nb_ports
=
rte_eth_dev_count_avail
();
if
(
nb_ports
==
0
)
rte_exit
(
EXIT_FAILURE
,
"No Ethernet ports - bye
\n
"
);
/* check port mask to possible port mask */
if
(
l2fwd_enabled_port_mask
&
~
((
1
<<
nb_ports
)
-
1
))
rte_exit
(
EXIT_FAILURE
,
"Invalid portmask; possible (0x%x)
\n
"
,
(
1
<<
nb_ports
)
-
1
);
/* reset l2fwd_dst_ports */
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
l2fwd_dst_ports
[
portid
]
=
0
;
last_port
=
0
;
/*
* Each logical core is assigned a dedicated TX queue on each port.
*/
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
if
(
nb_ports_in_mask
%
2
)
{
l2fwd_dst_ports
[
portid
]
=
last_port
;
l2fwd_dst_ports
[
last_port
]
=
portid
;
}
else
last_port
=
portid
;
nb_ports_in_mask
++
;
}
if
(
nb_ports_in_mask
%
2
)
{
printf
(
"Notice: odd number of ports in portmask.
\n
"
);
l2fwd_dst_ports
[
last_port
]
=
last_port
;
}
rx_lcore_id
=
0
;
qconf
=
NULL
;
/* Initialize the port/queue configuration of each logical core */
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
/* get the lcore_id for this port */
while
(
rte_lcore_is_enabled
(
rx_lcore_id
)
==
0
||
lcore_queue_conf
[
rx_lcore_id
].
n_rx_port
==
l2fwd_rx_queue_per_lcore
)
{
rx_lcore_id
++
;
if
(
rx_lcore_id
>=
RTE_MAX_LCORE
)
rte_exit
(
EXIT_FAILURE
,
"Not enough cores
\n
"
);
}
if
(
qconf
!=
&
lcore_queue_conf
[
rx_lcore_id
])
{
/* Assigned a new logical core in the loop above. */
qconf
=
&
lcore_queue_conf
[
rx_lcore_id
];
nb_lcores
++
;
}
qconf
->
rx_port_list
[
qconf
->
n_rx_port
]
=
portid
;
qconf
->
n_rx_port
++
;
printf
(
"Lcore %u: RX port %u
\n
"
,
rx_lcore_id
,
portid
);
}
nb_mbufs
=
RTE_MAX
(
nb_ports
*
(
nb_rxd
+
nb_txd
+
MAX_PKT_BURST
+
nb_lcores
*
MEMPOOL_CACHE_SIZE
),
8192U
);
/* create the mbuf pool */
//DD Debug
//printf ("Proc Type %d \n", rte_eal_process_type());
l2fwd_pktmbuf_pool
=
rte_pktmbuf_pool_create
(
"mbuf_pool"
,
nb_mbufs
,
MEMPOOL_CACHE_SIZE
,
0
,
9680
,
rte_socket_id
());
if
(
l2fwd_pktmbuf_pool
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot init mbuf pool
\n
"
);
/* Initialise each port */
RTE_ETH_FOREACH_DEV
(
portid
)
{
struct
rte_eth_rxconf
rxq_conf
;
struct
rte_eth_txconf
txq_conf
;
struct
rte_eth_conf
local_port_conf
=
port_conf
;
struct
rte_eth_dev_info
dev_info
;
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"Skipping disabled port %u
\n
"
,
portid
);
continue
;
}
nb_ports_available
++
;
/* init port */
printf
(
"Initializing port %u... "
,
portid
);
fflush
(
stdout
);
rte_eth_dev_info_get
(
portid
,
&
dev_info
);
if
(
dev_info
.
tx_offload_capa
&
DEV_TX_OFFLOAD_MBUF_FAST_FREE
)
local_port_conf
.
txmode
.
offloads
|=
DEV_TX_OFFLOAD_MBUF_FAST_FREE
;
ret
=
rte_eth_dev_configure
(
portid
,
1
,
1
,
&
local_port_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot configure device: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_dev_adjust_nb_rx_tx_desc
(
portid
,
&
nb_rxd
,
&
nb_txd
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot adjust number of descriptors: err=%d, port=%u
\n
"
,
ret
,
portid
);
rte_eth_macaddr_get
(
portid
,
&
l2fwd_ports_eth_addr
[
portid
]);
/* init one RX queue */
fflush
(
stdout
);
rxq_conf
=
dev_info
.
default_rxconf
;
rxq_conf
.
offloads
=
local_port_conf
.
rxmode
.
offloads
;
ret
=
rte_eth_rx_queue_setup
(
portid
,
0
,
nb_rxd
,
rte_eth_dev_socket_id
(
portid
),
&
rxq_conf
,
l2fwd_pktmbuf_pool
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_rx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one TX queue on each port */
fflush
(
stdout
);
txq_conf
=
dev_info
.
default_txconf
;
txq_conf
.
offloads
=
local_port_conf
.
txmode
.
offloads
;
ret
=
rte_eth_tx_queue_setup
(
portid
,
0
,
nb_txd
,
rte_eth_dev_socket_id
(
portid
),
&
txq_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_tx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* Initialize TX buffers */
tx_buffer
[
portid
]
=
rte_zmalloc_socket
(
"tx_buffer"
,
RTE_ETH_TX_BUFFER_SIZE
(
MAX_PKT_BURST
),
0
,
rte_eth_dev_socket_id
(
portid
));
if
(
tx_buffer
[
portid
]
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot allocate buffer for tx on port %u
\n
"
,
portid
);
rte_eth_tx_buffer_init
(
tx_buffer
[
portid
],
MAX_PKT_BURST
);
ret
=
rte_eth_tx_buffer_set_err_callback
(
tx_buffer
[
portid
],
rte_eth_tx_buffer_count_callback
,
&
port_statistics
[
portid
].
dropped
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot set error callback for tx buffer on port %u
\n
"
,
portid
);
/* Start device */
ret
=
rte_eth_dev_start
(
portid
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_dev_start:err=%d, port=%u
\n
"
,
ret
,
portid
);
printf
(
"done:
\n
"
);
rte_eth_promiscuous_enable
(
portid
);
printf
(
"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X
\n\n
"
,
portid
,
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
0
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
1
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
2
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
3
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
4
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
5
]);
/* initialize port stats */
memset
(
&
port_statistics
,
0
,
sizeof
(
port_statistics
));
}
if
(
!
nb_ports_available
)
{
rte_exit
(
EXIT_FAILURE
,
"All available ports are disabled. Please set portmask.
\n
"
);
}
check_all_ports_link_status
(
l2fwd_enabled_port_mask
);
ret
=
0
;
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch
(
l2fwd_launch_one_lcore
,
bs
,
CALL_MASTER
);
RTE_LCORE_FOREACH_SLAVE
(
lcore_id
)
{
if
(
rte_eal_wait_lcore
(
lcore_id
)
<
0
)
{
ret
=
-
1
;
break
;
}
}
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"Closing port %d..."
,
portid
);
rte_eth_dev_stop
(
portid
);
rte_eth_dev_close
(
portid
);
printf
(
" Done
\n
"
);
}
printf
(
"Bye...
\n
"
);
return
ret
;
}
radio/ETHERNET/benetel/5g/low.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "low.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
store_ul
(
benetel_t
*
bs
,
ul_packet_t
*
ul
)
{
#if 0
struct timespec t;
static struct timespec old;
clock_gettime(CLOCK_REALTIME, &t);
printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - old.tv_nsec);
old = t;
#endif
int
a
=
ul
->
antenna
;
if
(
ul
->
slot
!=
bs
->
next_slot
[
a
]
||
ul
->
symbol
!=
bs
->
next_symbol
[
a
])
{
printf
(
"%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d
\n
"
,
__FUNCTION__
,
a
,
bs
->
expected_benetel_frame
[
a
],
bs
->
next_slot
[
a
],
bs
->
next_symbol
[
a
],
ul
->
frame
,
ul
->
slot
,
ul
->
symbol
);
}
/* fill missing data with 0s */
while
(
ul
->
slot
!=
bs
->
next_slot
[
a
]
||
ul
->
symbol
!=
bs
->
next_symbol
[
a
])
{
lock_ul_buffer
(
bs
->
buffers
,
bs
->
next_slot
[
a
]);
if
(
bs
->
buffers
->
ul_busy
[
a
][
bs
->
next_slot
[
a
]]
&
(
1
<<
bs
->
next_symbol
[
a
]))
{
printf
(
"%s: warning, antenna %d UL overflow (sl.symbol %d.%d)
\n
"
,
__FUNCTION__
,
a
,
bs
->
next_slot
[
a
],
bs
->
next_symbol
[
a
]);
}
memset
(
bs
->
buffers
->
ul
[
a
][
bs
->
next_slot
[
a
]]
+
bs
->
next_symbol
[
a
]
*
1272
*
4
,
0
,
1272
*
4
);
bs
->
buffers
->
ul_busy
[
a
][
bs
->
next_slot
[
a
]]
|=
(
1
<<
bs
->
next_symbol
[
a
]);
signal_ul_buffer
(
bs
->
buffers
,
bs
->
next_slot
[
a
]);
unlock_ul_buffer
(
bs
->
buffers
,
bs
->
next_slot
[
a
]);
bs
->
next_symbol
[
a
]
++
;
if
(
bs
->
next_symbol
[
a
]
==
14
)
{
bs
->
next_symbol
[
a
]
=
0
;
bs
->
next_slot
[
a
]
=
(
bs
->
next_slot
[
a
]
+
1
)
%
20
;
if
(
bs
->
next_slot
[
a
]
==
0
)
{
bs
->
expected_benetel_frame
[
a
]
++
;
bs
->
expected_benetel_frame
[
a
]
&=
255
;
}
}
}
lock_ul_buffer
(
bs
->
buffers
,
bs
->
next_slot
[
a
]);
if
(
bs
->
buffers
->
ul_busy
[
a
][
bs
->
next_slot
[
a
]]
&
(
1
<<
bs
->
next_symbol
[
a
]))
{
printf
(
"%s: warning, antenna %d UL overflow (sl.symbol %d.%d)
\n
"
,
__FUNCTION__
,
a
,
bs
->
next_slot
[
a
],
bs
->
next_symbol
[
a
]);
}
memcpy
(
bs
->
buffers
->
ul
[
a
][
bs
->
next_slot
[
a
]]
+
bs
->
next_symbol
[
a
]
*
1272
*
4
,
ul
->
iq
,
1272
*
4
);
bs
->
buffers
->
ul_busy
[
a
][
bs
->
next_slot
[
a
]]
|=
(
1
<<
bs
->
next_symbol
[
a
]);
signal_ul_buffer
(
bs
->
buffers
,
bs
->
next_slot
[
a
]);
unlock_ul_buffer
(
bs
->
buffers
,
bs
->
next_slot
[
a
]);
bs
->
next_symbol
[
a
]
++
;
if
(
bs
->
next_symbol
[
a
]
==
14
)
{
bs
->
next_symbol
[
a
]
=
0
;
bs
->
next_slot
[
a
]
=
(
bs
->
next_slot
[
a
]
+
1
)
%
20
;
if
(
bs
->
next_slot
[
a
]
==
0
)
{
bs
->
expected_benetel_frame
[
a
]
++
;
bs
->
expected_benetel_frame
[
a
]
&=
255
;
}
}
}
void
store_prach
(
benetel_t
*
bs
,
int
frame
,
int
slot
,
void
*
data
)
{
static
int
last_frame
=
-
1
;
static
int
last_slot
=
-
1
;
/* hack: antenna number is always 0, discard second packet with same f/sf */
//if (frame == last_frame && slot == last_slot) return;
if
(
frame
==
last_frame
&&
slot
==
last_slot
)
{
printf
(
"got f.sl %d.%d twice
\n
"
,
frame
,
slot
);
return
;
}
last_frame
=
frame
;
last_slot
=
slot
;
lock_ul_buffer
(
bs
->
buffers
,
slot
);
if
(
bs
->
buffers
->
prach_busy
[
slot
])
{
printf
(
"store_prach: fatal: previous prach buffer not processed
\n
"
);
unlock_ul_buffer
(
bs
->
buffers
,
slot
);
return
;
}
bs
->
buffers
->
prach_busy
[
slot
]
=
1
;
memcpy
(
bs
->
buffers
->
prach
[
slot
],
data
,
839
*
4
);
signal_ul_buffer
(
bs
->
buffers
,
slot
);
unlock_ul_buffer
(
bs
->
buffers
,
slot
);
}
void
*
benetel_start_dpdk
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
);
void
*
benetel_start
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
)
{
if
(
!
strcmp
(
ifname
,
"dpdk"
))
return
benetel_start_dpdk
(
ifname
,
buffers
,
dpdk_main_command_line
);
printf
(
"benetel: fatal: interface %s not supported, only dpdpk is supported
\n
"
,
ifname
);
exit
(
1
);
}
radio/ETHERNET/benetel/5g/low.h
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _BENETEL_5G_LOW_H_
#define _BENETEL_5G_LOW_H_
#include "shared_buffers.h"
typedef
struct
{
shared_buffers
*
buffers
;
/* [2] is for two antennas */
int
next_slot
[
2
];
int
next_symbol
[
2
];
int
expected_benetel_frame
[
2
];
char
*
dpdk_main_command_line
;
}
benetel_t
;
typedef
struct
{
int
frame
;
int
slot
;
int
symbol
;
int
antenna
;
unsigned
char
iq
[
5088
];
}
ul_packet_t
;
void
*
benetel_start
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
);
void
store_ul
(
benetel_t
*
bs
,
ul_packet_t
*
ul
);
void
store_prach
(
benetel_t
*
bs
,
int
frame
,
int
slot
,
void
*
data
);
#endif
/* _BENETEL_5G_LOW_H_ */
radio/ETHERNET/benetel/5g/low_dpdk.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* those 2 lines for CPU_SET */
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "low.h"
int
dpdk_main
(
int
argc
,
char
**
argv
,
benetel_t
*
);
void
*
dpdk_thread
(
void
*
_bs
)
{
benetel_t
*
bs
=
_bs
;
int
n
=
0
;
char
**
v
=
NULL
;
// = { "softmodem", "-n", "2", "--file-prefix", "pg2", "-l", "6", "--", "-p", "0x1" };
char
*
s
=
bs
->
dpdk_main_command_line
;
char
*
tok
;
while
((
tok
=
strtok
(
s
,
" "
))
!=
NULL
)
{
n
++
;
v
=
realloc
(
v
,
n
*
sizeof
(
char
*
));
if
(
v
==
NULL
)
{
printf
(
"%s: out of memory
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
v
[
n
-
1
]
=
tok
;
s
=
NULL
;
}
dpdk_main
(
n
,
v
,
bs
);
exit
(
1
);
return
0
;
}
void
*
benetel_start_dpdk
(
char
*
ifname
,
shared_buffers
*
buffers
,
char
*
dpdk_main_command_line
)
{
benetel_t
*
bs
;
bs
=
calloc
(
1
,
sizeof
(
benetel_t
));
if
(
bs
==
NULL
)
{
printf
(
"%s: out of memory
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
bs
->
buffers
=
buffers
;
bs
->
expected_benetel_frame
[
0
]
=
255
;
bs
->
expected_benetel_frame
[
1
]
=
255
;
bs
->
dpdk_main_command_line
=
dpdk_main_command_line
;
pthread_attr_t
attr
;
if
(
pthread_attr_init
(
&
attr
)
!=
0
)
{
printf
(
"pthread_attr_init failed
\n
"
);
exit
(
1
);
}
cpu_set_t
cpuset
;
CPU_ZERO
(
&
cpuset
);
CPU_SET
(
10
,
&
cpuset
);
if
(
pthread_attr_setaffinity_np
(
&
attr
,
sizeof
(
cpu_set_t
),
&
cpuset
)
!=
0
)
{
printf
(
"pthread_attr_setaffinity_np failed
\n
"
);
exit
(
1
);
}
if
(
pthread_attr_setschedpolicy
(
&
attr
,
SCHED_FIFO
)
!=
0
)
{
printf
(
"pthread_attr_setschedpolicy failed
\n
"
);
exit
(
1
);
}
struct
sched_param
params
;
params
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
if
(
sched_get_priority_max
(
SCHED_FIFO
)
==
-
1
)
{
printf
(
"sched_get_priority_max failed
\n
"
);
exit
(
1
);
}
if
(
pthread_attr_setschedparam
(
&
attr
,
&
params
)
!=
0
)
{
printf
(
"pthread_setschedparam failed
\n
"
);
exit
(
1
);
}
pthread_t
t
;
if
(
pthread_create
(
&
t
,
&
attr
,
dpdk_thread
,
bs
)
!=
0
)
{
printf
(
"%s: thread creation failed
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
if
(
pthread_attr_destroy
(
&
attr
)
!=
0
)
{
printf
(
"pthread_attr_init failed
\n
"
);
exit
(
1
);
}
return
bs
;
}
radio/ETHERNET/benetel/5g/shared_buffers.c
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "shared_buffers.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
init_buffers
(
shared_buffers
*
s
)
{
int
slot
;
memset
(
s
,
0
,
sizeof
(
*
s
));
for
(
slot
=
0
;
slot
<
20
;
slot
++
)
{
if
(
pthread_mutex_init
(
&
s
->
m_dl
[
slot
],
NULL
)
!=
0
||
pthread_cond_init
(
&
s
->
c_dl
[
slot
],
NULL
)
!=
0
||
pthread_mutex_init
(
&
s
->
m_ul
[
slot
],
NULL
)
!=
0
||
pthread_cond_init
(
&
s
->
c_ul
[
slot
],
NULL
)
!=
0
)
{
printf
(
"%s: error initializing mutex/cond
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
/* the gNB's first transmitted DL slot is 6 but the device
* needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend
* they are ready.
*/
s
->
dl_busy
[
0
][
1
]
=
0x3fff
;
s
->
dl_busy
[
0
][
2
]
=
0x3fff
;
s
->
dl_busy
[
0
][
3
]
=
0x3fff
;
s
->
dl_busy
[
0
][
4
]
=
0x3fff
;
s
->
dl_busy
[
0
][
5
]
=
0x3fff
;
s
->
dl_busy
[
1
][
1
]
=
0x3fff
;
s
->
dl_busy
[
1
][
2
]
=
0x3fff
;
s
->
dl_busy
[
1
][
3
]
=
0x3fff
;
s
->
dl_busy
[
1
][
4
]
=
0x3fff
;
s
->
dl_busy
[
1
][
5
]
=
0x3fff
;
}
void
lock_dl_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_mutex_lock
(
&
s
->
m_dl
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: lock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
unlock_dl_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_mutex_unlock
(
&
s
->
m_dl
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: unlock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
wait_dl_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_cond_wait
(
&
s
->
c_dl
[
slot
],
&
s
->
m_dl
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: cond_wait fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
signal_dl_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_cond_broadcast
(
&
s
->
c_dl
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: cond_broadcast fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
lock_ul_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_mutex_lock
(
&
s
->
m_ul
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: lock fails
\n
"
,
__FUNCTION__
);
printf
(
"%s: fatal: lock fails slot %d
\n
"
,
__FUNCTION__
,
slot
);
exit
(
1
);
}
}
void
unlock_ul_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_mutex_unlock
(
&
s
->
m_ul
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: unlock fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
wait_ul_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_cond_wait
(
&
s
->
c_ul
[
slot
],
&
s
->
m_ul
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: cond_wait fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
void
signal_ul_buffer
(
shared_buffers
*
s
,
int
slot
)
{
if
(
pthread_cond_broadcast
(
&
s
->
c_ul
[
slot
])
!=
0
)
{
printf
(
"%s: fatal: cond_broadcast fails
\n
"
,
__FUNCTION__
);
exit
(
1
);
}
}
radio/ETHERNET/benetel/5g/shared_buffers.h
deleted
100644 → 0
View file @
70451408
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _BENETEL_5G_SHARED_BUFFERS_H_
#define _BENETEL_5G_SHARED_BUFFERS_H_
#include <pthread.h>
#include <stdint.h>
typedef
struct
{
/* [2] is for two antennas */
unsigned
char
dl
[
2
][
20
][
14
*
1272
*
4
];
unsigned
char
ul
[
2
][
20
][
14
*
1272
*
4
];
uint16_t
dl_busy
[
2
][
20
];
uint16_t
ul_busy
[
2
][
20
];
pthread_mutex_t
m_ul
[
20
];
pthread_cond_t
c_ul
[
20
];
pthread_mutex_t
m_dl
[
20
];
pthread_cond_t
c_dl
[
20
];
unsigned
char
prach
[
20
][
849
*
4
];
unsigned
char
prach_busy
[
20
];
/* statistics/error counting */
int
ul_overflow
;
int
dl_underflow
;
}
shared_buffers
;
void
init_buffers
(
shared_buffers
*
s
);
void
lock_dl_buffer
(
shared_buffers
*
s
,
int
slot
);
void
unlock_dl_buffer
(
shared_buffers
*
s
,
int
slot
);
void
wait_dl_buffer
(
shared_buffers
*
s
,
int
slot
);
void
signal_dl_buffer
(
shared_buffers
*
s
,
int
slot
);
void
lock_ul_buffer
(
shared_buffers
*
s
,
int
slot
);
void
unlock_ul_buffer
(
shared_buffers
*
s
,
int
slot
);
void
wait_ul_buffer
(
shared_buffers
*
s
,
int
slot
);
void
signal_ul_buffer
(
shared_buffers
*
s
,
int
slot
);
#endif
/* _BENETEL_5G_SHARED_BUFFERS_H_ */
radio/ETHERNET/benetel/CMakeLists.txt
deleted
100644 → 0
View file @
70451408
add_boolean_option
(
OAI_BENETEL4G OFF
"Activate OAI's Benetel 4G radio driver"
OFF
)
if
(
OAI_BENETEL4G
)
add_subdirectory
(
4g
)
endif
()
add_boolean_option
(
OAI_BENETEL5G OFF
"Activate OAI's Benetel 5G radio driver"
OFF
)
if
(
OAI_BENETEL5G
)
add_subdirectory
(
5g
)
endif
()
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