Merge branch 'integration_2026_w12' into 'develop'
Integration `2026.w12` * !3985 Fix XNAP to avoid recompilation and unnecessary includes * !3724 Better c style pss sss * !3972 Resolve "Demote AssertFatal `PUCCH list is full` message to a warning" * !3956 [FHI72] [xran F] Revert and simplify the code for Liteon FR2 interoperability * !3970 Fix for NTN phy-test mode * !3987 T: minor: remove target record_db from automatic building * !3993 UE: Derive Serving Network Name from SIB1 PLMN * !3997 vrtsim doc: clarify container requirements * !3935 [FHI72] Fix long PRACH format * !3998 Set rxgain to 0 in vrtsim * !3964 CI: Add FHI7.2 phytest pipeline * !4001 Remove unused ci-scripts/mysql4testresults/ dir and content * !3999 bugfix: use proper pointer * !3986 handle start symbol on non-zeroth downlink symbol for SIB1 for multiplexing pattern 3 configuration. * !3957 replace static allocation of max antennas in a dynamic structure for gnb rach * !3859 Delay compensation in SRS * !3909 Adjust ssPBCH_BlockPower in FHI7.2 configs Closes #1058 See merge request oai/openairinterface5g!3989
This commit is contained in:
@@ -183,10 +183,6 @@ amarisoft_ue_2x2:
|
||||
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue_20MHz_2x2/aw2s-multi-00102-2x2-v2.cfg &
|
||||
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
|
||||
NetworkScript: ip netns exec ue1 ip a show dev pdn0
|
||||
amarisoft_ue_fhi72:
|
||||
Host: amariue
|
||||
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_fhi72_asue_2x2_benetel550/fhi72-multi-20897-2x2.cfg &
|
||||
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
|
||||
amarisoft_ue_1:
|
||||
Host: amariue
|
||||
AttachScript: /root/lteue-linux-2025-03-15/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":1}'
|
||||
|
||||
@@ -789,7 +789,7 @@ class Containerize():
|
||||
logging.error('\u001B[1m Undeploying objects Failed\u001B[0m')
|
||||
return success
|
||||
|
||||
def AnalyzeRTStatsObject(self, HTML, node, ctx, thresholds):
|
||||
def AnalyzeRTStatsObject(self, HTML, node, ctx, thresholds, service=None):
|
||||
logging.info(f'Analyzing realtime stats from server: {node}')
|
||||
yaml = self.yamlPath.strip('/')
|
||||
wd = f'{self.eNBSourceCodePath}/{yaml}'
|
||||
@@ -797,7 +797,13 @@ class Containerize():
|
||||
|
||||
with cls_cmd.getConnection(node) as cmd:
|
||||
services = GetDeployedServices(cmd, wd_yaml)
|
||||
s, _ = services[0] # we simply assume something is deployed, if not Exception will report
|
||||
if not services:
|
||||
raise RuntimeError("No deployed docker compose services found")
|
||||
deployed_services = [s for s, _ in services]
|
||||
s = service or deployed_services[0] # choose first service if not provided
|
||||
if s not in deployed_services:
|
||||
raise RuntimeError(f"Requested service {s} not found among services: {deployed_services}")
|
||||
logging.info(f"Analyzing deployed service '{s}'")
|
||||
# similar to BuildRunTests(), use docker cp to avoid problems with permissions
|
||||
cmd.run(f'docker compose -f {wd_yaml} cp {s}:/opt/oai-gnb/nrL1_stats.log {wd}/')
|
||||
l1_file = archiveArtifact(cmd, ctx, f"{wd}/nrL1_stats.log")
|
||||
|
||||
@@ -245,12 +245,12 @@ log_config :
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:c3:11.0", "0000:c3:11.1");
|
||||
dpdk_devices = ("0000:c3:11.0");
|
||||
dpdk_iova_mode = "VA";
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
ru_addr = ("98:ae:71:04:83:e3", "98:ae:71:04:83:e3");
|
||||
ru_addr = ("98:ae:71:04:83:e3");
|
||||
mtu = 9216;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (285, 470);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#this is a configuration file
|
||||
#used to build real time processing statistics
|
||||
#for 5G NR phy test (gNB terminate)
|
||||
Title : Processing Time (us) from datalog_rt_stats.4x4.fhi72.yaml
|
||||
ColNames :
|
||||
- Metric
|
||||
- Average; Max; Count
|
||||
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
|
||||
Ref :
|
||||
tx_fhaul : 73.0
|
||||
feptx_prec (per port, half_slot) : 46.0
|
||||
L1 Tx processing : 371.7
|
||||
DLSCH encoding : 196.9
|
||||
L1 Rx processing : 578.0
|
||||
UL segments decoding : 81.2
|
||||
UL Indication : 0.4
|
||||
Slot Indication : 14.3
|
||||
PUSCH inner-receiver : 739.4
|
||||
DeviationThreshold :
|
||||
tx_fhaul : 0.25
|
||||
feptx_prec (per port, half_slot) : 0.25
|
||||
L1 Tx processing : 0.25
|
||||
DLSCH encoding : 0.25
|
||||
L1 Rx processing : 0.25
|
||||
UL segments decoding : 0.25
|
||||
UL Indication : 1.00
|
||||
Slot Indication : 0.50
|
||||
PUSCH inner-receiver : 0.25
|
||||
+2
-1
@@ -259,7 +259,8 @@ def ExecuteActionWithParam(action, ctx, node):
|
||||
|
||||
elif action == 'AnalyzeRTStats_Object':
|
||||
yaml = test.findtext('stats_cfg')
|
||||
success = CONTAINERS.AnalyzeRTStatsObject(HTML, node, ctx, yaml)
|
||||
service = test.findtext('service')
|
||||
success = CONTAINERS.AnalyzeRTStatsObject(HTML, node, ctx, yaml, service)
|
||||
|
||||
else:
|
||||
logging.warning(f"unknown action {action}, skip step")
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
version: '2'
|
||||
services:
|
||||
mysql:
|
||||
container_name: oaicicd_mysql
|
||||
restart: always
|
||||
image: mysql:latest
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 'ucZBc2XRYdvEm59F'
|
||||
ports:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- /home/oaicicd/mysql/data:/var/lib/mysql
|
||||
@@ -1,33 +0,0 @@
|
||||
import pymysql
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
#This is the script used to write the test results to the mysql DB
|
||||
#Called by Jenkins pipeline (jenkinsfile)
|
||||
#Must be located in /home/oaicicid/mysql on the database host
|
||||
#Usage from Jenkinsfile :
|
||||
#python3 /home/oaicicd/mysql/sql_connect.py ${JOB_NAME} ${params.eNB_MR} ${params.eNB_Branch} ${env.BUILD_ID} ${env.BUILD_URL} ${StatusForDb} ''
|
||||
|
||||
class SQLConnect:
|
||||
def __init__(self):
|
||||
self.connection = pymysql.connect(
|
||||
host='172.22.0.2',
|
||||
user='root',
|
||||
password = 'ucZBc2XRYdvEm59F',
|
||||
db='oaicicd_tests',
|
||||
port=3306
|
||||
)
|
||||
|
||||
def put(self,TEST,MR,BRANCH,BUILD,BUILD_LINK,STATUS):
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
cur=self.connection.cursor()
|
||||
cur.execute ('INSERT INTO test_results (TEST,MR,BRANCH,BUILD,BUILD_LINK,STATUS,DATE) VALUES (%s,%s,%s,%s,%s,%s,%s);' , (TEST, MR, BRANCH, BUILD, BUILD_LINK, STATUS, now))
|
||||
self.connection.commit()
|
||||
self.connection.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
mydb=SQLConnect()
|
||||
mydb.put(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4],sys.argv[5],sys.argv[6])
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>test-5g-fhi72-metanoia-2x2</htmlTabRef>
|
||||
<htmlTabName>100 MHz TDD SA METANOIA</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
|
||||
<testCase>
|
||||
<class>Custom_Script</class>
|
||||
<desc>Setup sriov and network interfaces Metanoia</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/setup_sriov_metanoia.sh</script>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<node>cacofonix</node>
|
||||
<images>oai-gnb-fhi72</images>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>cacofonix</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy gNB (TDD/Band78/100MHz/Metanoia) in a container</desc>
|
||||
<node>cacofonix</node>
|
||||
<yaml_path>ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb</yaml_path>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>up2-fhi72</id>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 100 pings in 10 sec</desc>
|
||||
<id>up2-fhi72</id>
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
<ping_args>-c 100 -i 0.1</ping_args>
|
||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||
<ping_rttavg_threshold>15</ping_rttavg_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/570Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 570M -t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
<iperf_profile>balanced</iperf_profile>
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/100Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 100M -t 30</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
<iperf_profile>balanced</iperf_profile>
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_tcp_rate_target>80</iperf_tcp_rate_target>
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_tcp_rate_target>80</iperf_tcp_rate_target>
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Detach_UE</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Detach UE</desc>
|
||||
<id>up2-fhi72</id>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy gNB</desc>
|
||||
<node>cacofonix</node>
|
||||
<yaml_path>ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb</yaml_path>
|
||||
<analysis>
|
||||
<services>oai-gnb=EndsWithBye</services>
|
||||
</analysis>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<node>cacofonix</node>
|
||||
<images>oai-gnb-fhi72</images>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Custom_Script</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Set CPU to idle state, set kernel parameters to default values</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/setup_cleanup.sh</script>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
<testCase>
|
||||
<class>Custom_Script</class>
|
||||
<desc>Setup sriov and network interfaces VVDN</desc>
|
||||
<desc>Configure system for low-latency RT performance</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_vvdn_gnb/setup_sriov_vvdn.sh</script>
|
||||
<script>yaml_files/sa_fhi_7.2_vvdn_gnb/setup_config.sh</script>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
|
||||
@@ -25,13 +25,6 @@
|
||||
<htmlTabName>Timing phytest 100 MHz 4x4 FHI7.2</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
|
||||
<testCase>
|
||||
<class>Custom_Script</class>
|
||||
<desc>Setup sriov and network interfaces for dummy (no RU)</desc>
|
||||
<node>bulbul</node>
|
||||
<script>yaml_files/phytest_fhi72/setup_sriov_dummy.sh</script>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
@@ -63,6 +56,7 @@
|
||||
<class>AnalyzeRTStats_Object</class>
|
||||
<desc>Analyze Real-Time Stats</desc>
|
||||
<stats_cfg>datalog_rt_stats.100.4x4.fhi72.yaml</stats_cfg>
|
||||
<service>oai-gnb</service>
|
||||
<node>bulbul</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>gNB-PHY-Test-100-4x4-FHI72</htmlTabRef>
|
||||
<htmlTabName>Timing phytest 100 MHz 4x4 FHI7.2</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
|
||||
<testCase>
|
||||
<class>Custom_Script</class>
|
||||
<desc>Configure system for low-latency RT performance</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/phytest_fhi72_cacofonix/setup_config.sh</script>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<node>cacofonix</node>
|
||||
<images>oai-gnb-fhi72</images>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<node>cacofonix</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Initialize gNB FHI7.2</desc>
|
||||
<node>cacofonix</node>
|
||||
<yaml_path>ci-scripts/yaml_files/phytest_fhi72_cacofonix</yaml_path>
|
||||
<services>oai-gnb</services>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>AnalyzeRTStats_Object</class>
|
||||
<desc>Analyze Real-Time Stats</desc>
|
||||
<stats_cfg>datalog_rt_stats.100.2x2.fhi72.cacofonix.yaml</stats_cfg>
|
||||
<service>oai-gnb</service>
|
||||
<node>cacofonix</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Undeploy_Object</class>
|
||||
<node>cacofonix</node>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Terminate gNB</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/phytest_fhi72_cacofonix</yaml_path>
|
||||
<analysis>
|
||||
<services>oai-gnb=EndsWithBye</services>
|
||||
</analysis>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<node>cacofonix</node>
|
||||
<images>oai-gnb-fhi72</images>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Custom_Script</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Set CPU to idle state, set kernel parameters to default values</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/phytest_fhi72_cacofonix/setup_cleanup.sh</script>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -1,4 +1,16 @@
|
||||
services:
|
||||
dpdk-init:
|
||||
image: docker.io/library/oai-dpdk-init:latest
|
||||
network_mode: host
|
||||
container_name: dpdk-init
|
||||
entrypoint: "/tmp/setup_sriov.sh"
|
||||
privileged: true
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ./setup_sriov_dummy.sh:/tmp/setup_sriov.sh
|
||||
- /lib/modules:/lib/modules
|
||||
- /usr/lib/modules:/usr/lib/modules
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-fhi72}:${TAG:-develop}
|
||||
container_name: oai-gnb-phytest
|
||||
@@ -12,11 +24,24 @@ services:
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- ../../conf_files/gnb.band77.273prb.fhi72.4x4-vvdn-phytest.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev/hugepages:/dev/hugepages
|
||||
cpuset: "8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23"
|
||||
cpuset: "8-23"
|
||||
networks: ["public_net"]
|
||||
depends_on:
|
||||
dpdk-init:
|
||||
condition: service_completed_successfully
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: ci-physim
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "ci-physim"
|
||||
|
||||
@@ -19,19 +19,19 @@ IF_NAME=ens1f0np0
|
||||
C_U_PLANE_MAC_ADD=22:11:55:33:99:55
|
||||
C_U_PLANE_VLAN=123
|
||||
MTU=9000
|
||||
DPDK_DEVBIND_PREFIX=/home/oaicicd/test/dpdk-stable-22.11.7/bin
|
||||
DPDK_DEVBIND_PREFIX=/usr/local/bin
|
||||
NUM_VFs=1
|
||||
sudo ethtool -G $IF_NAME rx 8160 tx 8160
|
||||
sudo sh -c "echo 0 > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
sudo sh -c "echo $NUM_VFs > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
ethtool -G $IF_NAME rx 8160 tx 8160
|
||||
sh -c "echo 0 > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
sh -c "echo $NUM_VFs > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
C_U_PLANE_PCI=$(pci_addr $IF_NAME 0)
|
||||
# this next 2 lines is for C/U planes
|
||||
sudo ip link set $IF_NAME vf 0 mac $C_U_PLANE_MAC_ADD vlan $C_U_PLANE_VLAN spoofchk off mtu $MTU
|
||||
ip link set $IF_NAME vf 0 mac $C_U_PLANE_MAC_ADD vlan $C_U_PLANE_VLAN spoofchk off mtu $MTU
|
||||
sleep 1
|
||||
sudo modprobe iavf
|
||||
sudo ${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --unbind $C_U_PLANE_PCI
|
||||
sudo modprobe vfio-pci
|
||||
sudo ${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --bind vfio-pci $C_U_PLANE_PCI
|
||||
modprobe iavf
|
||||
${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --unbind $C_U_PLANE_PCI
|
||||
modprobe vfio-pci
|
||||
${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --bind vfio-pci $C_U_PLANE_PCI
|
||||
echo "Successfully configured C-PLANE and U-PLANE:
|
||||
- C-PLANE MAC: $C_U_PLANE_MAC_ADD, VLAN: $C_U_PLANE_VLAN, PCI: $C_U_PLANE_PCI"
|
||||
exit 0
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
services:
|
||||
dpdk-init:
|
||||
image: docker.io/library/oai-dpdk-init:latest
|
||||
network_mode: host
|
||||
container_name: dpdk-init
|
||||
entrypoint: "/tmp/setup_sriov.sh"
|
||||
privileged: true
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ./setup_sriov_dummy.sh:/tmp/setup_sriov.sh
|
||||
- /lib/modules:/lib/modules
|
||||
- /usr/lib/modules:/usr/lib/modules
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-fhi72}:${TAG:-develop}
|
||||
container_name: oai-gnb-phytest
|
||||
cap_add:
|
||||
- IPC_LOCK
|
||||
- SYS_NICE
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --phy-test -q -M 273 -m 27 -l 2 -D 231 -T 273 -t 16 -L 2 -U 528 --log_config.global_log_options level,nocolor,time --thread-pool 7,8,9,10,11,12
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev/hugepages:/dev/hugepages
|
||||
cpuset: "0-12"
|
||||
networks: ["public_net"]
|
||||
depends_on:
|
||||
dpdk-init:
|
||||
condition: service_completed_successfully
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: ci-physim
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "ci-physim"
|
||||
Regular → Executable
@@ -0,0 +1,4 @@
|
||||
set -e
|
||||
sudo cpupower idle-set -D 0 > /dev/null
|
||||
sudo sysctl kernel.sched_rt_runtime_us=-1
|
||||
sudo sysctl kernel.timer_migration=0
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
pci_addr()
|
||||
{
|
||||
PF_IF=$1
|
||||
VF_INDEX=$2
|
||||
SYSFS_PATH="/sys/class/net/${PF_IF}/device/virtfn${VF_INDEX}"
|
||||
|
||||
if [ ! -e "$SYSFS_PATH" ]; then
|
||||
echo "VF $VF_INDEX not found for interface $PF_IF"
|
||||
exit 1
|
||||
fi
|
||||
PCI_ADDR=$(basename "$(readlink "$SYSFS_PATH")")
|
||||
echo "$PCI_ADDR"
|
||||
}
|
||||
IF_NAME=ens7f1
|
||||
## O-DU C Plane MAC ADDR and VLAN
|
||||
C_U_PLANE_MAC_ADD=22:11:55:33:99:55
|
||||
C_U_PLANE_VLAN=123
|
||||
MTU=9000
|
||||
DPDK_DEVBIND_PREFIX=/usr/local/bin
|
||||
NUM_VFs=1
|
||||
ethtool -G $IF_NAME rx 8160 tx 8160
|
||||
sh -c "echo 0 > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
sh -c "echo $NUM_VFs > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
C_U_PLANE_PCI=$(pci_addr $IF_NAME 0)
|
||||
# this next 2 lines is for C/U planes
|
||||
ip link set $IF_NAME vf 0 mac $C_U_PLANE_MAC_ADD vlan $C_U_PLANE_VLAN spoofchk off mtu $MTU
|
||||
sleep 1
|
||||
modprobe iavf
|
||||
${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --unbind $C_U_PLANE_PCI
|
||||
modprobe vfio-pci
|
||||
${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --bind vfio-pci $C_U_PLANE_PCI
|
||||
echo "Successfully configured C-PLANE and U-PLANE:
|
||||
- C-PLANE MAC: $C_U_PLANE_MAC_ADD, VLAN: $C_U_PLANE_VLAN, PCI: $C_U_PLANE_PCI"
|
||||
exit 0
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI O-RAN 7.2 Front-haul Docker Compose</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
For instructions on OAI gNB Docker deployment with FH 7.2 RU, please refer to the [README](../sa_fhi_7.2_vvdn_gnb/README.md).
|
||||
@@ -1,42 +0,0 @@
|
||||
services:
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-fhi72:${TAG:-develop}
|
||||
cap_add:
|
||||
- SYS_ADMIN
|
||||
- IPC_LOCK
|
||||
- SYS_NICE
|
||||
cap_drop:
|
||||
- ALL
|
||||
container_name: oai-gnb
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
USE_ADDITIONAL_OPTIONS: --thread-pool 6,7,8,9
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev/hugepages:/dev/hugepages
|
||||
# Please change these values based on your system
|
||||
cpuset: "0,1,2,3,4,5,6,7,8,9"
|
||||
networks:
|
||||
oai-net:
|
||||
ipv4_address: 172.21.18.20
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/opt/oai-gnb/bin/check-prach-io.sh"
|
||||
start_period: 15s
|
||||
start_interval: 500ms
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
networks:
|
||||
oai-net:
|
||||
driver: macvlan
|
||||
name: oai-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.21.16.0/22"
|
||||
ip_range: "172.21.18.20/32"
|
||||
gateway: "172.21.19.254"
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "oai-net"
|
||||
parent: ens7f0
|
||||
@@ -1,22 +0,0 @@
|
||||
set -e
|
||||
sudo cpupower idle-set -D 0 > /dev/null
|
||||
sudo sysctl kernel.sched_rt_runtime_us=-1
|
||||
sudo sysctl kernel.timer_migration=0
|
||||
sudo ethtool -G ens7f1 rx 8160
|
||||
sudo ethtool -G ens7f1 tx 8160
|
||||
sudo ifconfig ens7f1 mtu 9216
|
||||
sudo sh -c 'echo 0 > /sys/class/net/ens7f1/device/sriov_numvfs'
|
||||
sudo sh -c 'echo 2 > /sys/class/net/ens7f1/device/sriov_numvfs'
|
||||
sudo modprobe -r iavf
|
||||
sudo modprobe iavf
|
||||
# this next 2 lines is for C/U planes
|
||||
sudo ip link set ens7f1 vf 0 mac 00:11:22:33:44:66 vlan 3 qos 0 spoofchk off mtu 9216
|
||||
sudo ip link set ens7f1 vf 1 mac 00:11:22:33:44:67 vlan 3 qos 0 spoofchk off mtu 9216
|
||||
sleep 1
|
||||
# These are the DPDK bindings for C/U-planes on vlan 3
|
||||
sudo /usr/local/bin/dpdk-devbind.py --unbind c3:11.0
|
||||
sudo /usr/local/bin/dpdk-devbind.py --unbind c3:11.1
|
||||
sudo modprobe vfio-pci
|
||||
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci c3:11.0
|
||||
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci c3:11.1
|
||||
exit 0
|
||||
@@ -1,87 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI O-RAN 7.2 Front-haul Docker Compose</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||

|
||||
|
||||
This docker-compose is designed to use `OAI-gNB` with a 7.2 compatible Radio Unit. Before using this docker compose you have to configure
|
||||
the host machine as per the [ORAN_FHI7.2_Tutorial](../../../doc/ORAN_FHI7.2_Tutorial.md). The container image used by the docker compose file is tested only on `Ubuntu 22.04` and `RHEL 9.4` docker host.
|
||||
|
||||
## Build Image (Optional)
|
||||
|
||||
Refer to [OAI Docker/Podman Build and Usage Procedures](../../../docker/README.md)
|
||||
|
||||
## Configure Networking
|
||||
|
||||
### SR-IOV Virtual Functions (VFs)
|
||||
|
||||
In docker-compose environment there is no automated method
|
||||
to configure the VFs on the fly. The user will have to manually configure
|
||||
C/U plane VFs before starting the container `OAI-gNB`.
|
||||
|
||||
You can follow the step
|
||||
[configure-network-interfaces-and-dpdk-vfs](../../../doc/ORAN_FHI7.2_Tutorial.md#configure-network-interfaces-and-dpdk-vfs).
|
||||
|
||||
### Interface towards AMF (N2)
|
||||
|
||||
For `N2` interface we are using `macvlan` driver of docker.
|
||||
|
||||
You can use the `bridge` driver, in situation
|
||||
|
||||
- When the core network is running on the same machine
|
||||
- or different machine but you have configured
|
||||
needed `ip route` and forwarding to access the core network from RAN host.
|
||||
|
||||
To configure docker `macvlan` network
|
||||
you need to choose `ipam.config` and `driver_opts.parent` are per your environment
|
||||
|
||||
```
|
||||
oai-net:
|
||||
driver: macvlan
|
||||
name: oai-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.21.16.0/22"
|
||||
ip_range: "172.21.18.20/32"
|
||||
gateway: "172.21.19.254"
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "oai-net"
|
||||
parent: ens7f0
|
||||
```
|
||||
|
||||
To configure `bridge` network you need to choose `ipam.config.subnet` as per your environment.
|
||||
|
||||
```
|
||||
oai-net:
|
||||
driver: bridge
|
||||
name: oai-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "oai-net"
|
||||
```
|
||||
|
||||
## Deploy OAI-gNB Container
|
||||
|
||||
The [configuration file](../../conf_files/gnb.sa.band77.273prb.fhi72.4x4.2L-metanoia.conf) used by docker compose is configured for Metanoia RU.
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
To check the logs
|
||||
|
||||
```bash
|
||||
docker logs oai-gnb -f
|
||||
```
|
||||
@@ -1,41 +0,0 @@
|
||||
services:
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-fhi72:${TAG:-develop}
|
||||
cap_add:
|
||||
- IPC_LOCK
|
||||
- SYS_NICE
|
||||
cap_drop:
|
||||
- ALL
|
||||
container_name: oai-gnb
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
USE_ADDITIONAL_OPTIONS: --thread-pool 7,8,9,10,11,12
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band77.273prb.fhi72.4x4.2L-metanoia.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev/hugepages:/dev/hugepages
|
||||
# Please change these values based on your system
|
||||
cpuset: "0,1,2,3,4,5,6,7,8,9,10,11,12"
|
||||
networks:
|
||||
oai-net:
|
||||
ipv4_address: 172.21.18.20
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/opt/oai-gnb/bin/check-prach-io.sh"
|
||||
start_period: 15s
|
||||
start_interval: 500ms
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
networks:
|
||||
oai-net:
|
||||
driver: macvlan
|
||||
name: oai-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.21.16.0/22"
|
||||
ip_range: "172.21.18.20/32"
|
||||
gateway: "172.21.19.254"
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "oai-net"
|
||||
parent: ens7f0
|
||||
@@ -1,5 +0,0 @@
|
||||
set -e
|
||||
sudo cpupower idle-set -E > /dev/null
|
||||
sudo sysctl kernel.sched_rt_runtime_us=950000
|
||||
sudo sysctl kernel.timer_migration=1
|
||||
exit 0
|
||||
@@ -1,20 +0,0 @@
|
||||
set -e
|
||||
sudo cpupower idle-set -D 0 > /dev/null
|
||||
sudo sysctl kernel.sched_rt_runtime_us=-1
|
||||
sudo sysctl kernel.timer_migration=0
|
||||
sudo ethtool -G ens7f1 rx 8160 tx 8160
|
||||
sudo sh -c 'echo 0 > /sys/class/net/ens7f1/device/sriov_numvfs'
|
||||
sudo sh -c 'echo 3 > /sys/class/net/ens7f1/device/sriov_numvfs'
|
||||
sudo modprobe -r iavf
|
||||
sudo modprobe iavf
|
||||
# this next 2 lines is for C/U planes
|
||||
sudo ip link set ens7f1 vf 0 mac 00:11:22:33:44:55 vlan 3 spoofchk off mtu 9000
|
||||
sudo ip link set ens7f1 vf 1 mac 00:11:22:33:44:54 vlan 3 spoofchk off mtu 9000
|
||||
sleep 1
|
||||
# These are the DPDK bindings for C/U-planes on vlan 1
|
||||
sudo /usr/local/bin/dpdk-devbind.py --unbind c3:11.0
|
||||
sudo /usr/local/bin/dpdk-devbind.py --unbind c3:11.1
|
||||
sudo modprobe vfio-pci
|
||||
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci c3:11.0
|
||||
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci c3:11.1
|
||||
exit 0
|
||||
@@ -1,4 +1,16 @@
|
||||
services:
|
||||
dpdk-init:
|
||||
image: docker.io/library/oai-dpdk-init:latest
|
||||
network_mode: host
|
||||
container_name: dpdk-init
|
||||
entrypoint: "/tmp/setup_sriov.sh"
|
||||
privileged: true
|
||||
devices:
|
||||
- /dev/vfio:/dev/vfio/
|
||||
volumes:
|
||||
- ./setup_sriov_vvdn.sh:/tmp/setup_sriov.sh
|
||||
- /lib/modules:/lib/modules
|
||||
- /usr/lib/modules:/usr/lib/modules
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-fhi72:${TAG:-develop}
|
||||
cap_add:
|
||||
@@ -16,10 +28,13 @@ services:
|
||||
- ../../conf_files/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev/hugepages:/dev/hugepages
|
||||
# Please change these values based on your system
|
||||
cpuset: "0,1,2,3,4,5,6,7,8,9,10,11,12"
|
||||
cpuset: "0-12"
|
||||
networks:
|
||||
oai-net:
|
||||
ipv4_address: 172.21.18.20
|
||||
depends_on:
|
||||
dpdk-init:
|
||||
condition: service_completed_successfully
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/opt/oai-gnb/bin/check-prach-io.sh"
|
||||
start_period: 15s
|
||||
|
||||
Regular → Executable
@@ -0,0 +1,4 @@
|
||||
set -e
|
||||
sudo cpupower idle-set -D 0 > /dev/null
|
||||
sudo sysctl kernel.sched_rt_runtime_us=-1
|
||||
sudo sysctl kernel.timer_migration=0
|
||||
Regular → Executable
+34
-18
@@ -1,21 +1,37 @@
|
||||
set -e
|
||||
sudo cpupower idle-set -D 0 > /dev/null
|
||||
sudo sysctl kernel.sched_rt_runtime_us=-1
|
||||
sudo sysctl kernel.timer_migration=0
|
||||
sudo ethtool -G ens7f1 rx 8160
|
||||
sudo ethtool -G ens7f1 tx 8160
|
||||
sudo sh -c 'echo 0 > /sys/class/net/ens7f1/device/sriov_numvfs'
|
||||
sudo sh -c 'echo 2 > /sys/class/net/ens7f1/device/sriov_numvfs'
|
||||
sudo modprobe -r iavf
|
||||
sudo modprobe iavf
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
pci_addr()
|
||||
{
|
||||
PF_IF=$1
|
||||
VF_INDEX=$2
|
||||
SYSFS_PATH="/sys/class/net/${PF_IF}/device/virtfn${VF_INDEX}"
|
||||
|
||||
if [ ! -e "$SYSFS_PATH" ]; then
|
||||
echo "VF $VF_INDEX not found for interface $PF_IF"
|
||||
exit 1
|
||||
fi
|
||||
PCI_ADDR=$(basename "$(readlink "$SYSFS_PATH")")
|
||||
echo "$PCI_ADDR"
|
||||
}
|
||||
IF_NAME=ens7f1
|
||||
## O-DU C Plane MAC ADDR and VLAN
|
||||
C_U_PLANE_MAC_ADD=76:76:64:6e:00:01
|
||||
C_U_PLANE_VLAN=4
|
||||
MTU=9000
|
||||
DPDK_DEVBIND_PREFIX=/usr/local/bin
|
||||
NUM_VFs=1
|
||||
ethtool -G $IF_NAME rx 8160 tx 8160
|
||||
sh -c "echo 0 > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
sh -c "echo $NUM_VFs > /sys/class/net/$IF_NAME/device/sriov_numvfs"
|
||||
C_U_PLANE_PCI=$(pci_addr $IF_NAME 0)
|
||||
# this next 2 lines is for C/U planes
|
||||
sudo ip link set ens7f1 vf 0 mac 76:76:64:6e:00:01 vlan 4 spoofchk off mtu 9216
|
||||
sudo ip link set ens7f1 vf 1 mac 76:76:64:6e:00:00 vlan 4 spoofchk off mtu 9216
|
||||
ip link set $IF_NAME vf 0 mac $C_U_PLANE_MAC_ADD vlan $C_U_PLANE_VLAN spoofchk off mtu $MTU
|
||||
sleep 1
|
||||
# These are the DPDK bindings for C/U-planes on vlan 4
|
||||
sudo /usr/local/bin/dpdk-devbind.py --unbind c3:11.0
|
||||
sudo /usr/local/bin/dpdk-devbind.py --unbind c3:11.1
|
||||
sudo modprobe vfio-pci
|
||||
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci c3:11.0
|
||||
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci c3:11.1
|
||||
modprobe iavf
|
||||
${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --unbind $C_U_PLANE_PCI
|
||||
modprobe vfio-pci
|
||||
${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --bind vfio-pci $C_U_PLANE_PCI
|
||||
echo "Successfully configured C-PLANE and U-PLANE:
|
||||
- C-PLANE MAC: $C_U_PLANE_MAC_ADD, VLAN: $C_U_PLANE_VLAN, PCI: $C_U_PLANE_PCI"
|
||||
exit 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h
|
||||
index ac5f471..b1acb26 100644
|
||||
index ac5f471..fe27425 100644
|
||||
--- a/fhi_lib/app/src/common.h
|
||||
+++ b/fhi_lib/app/src/common.h
|
||||
@@ -28,7 +28,7 @@
|
||||
@@ -7,7 +7,7 @@ index ac5f471..b1acb26 100644
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
-#define VERSIONX "oran_f_release_v1.0"
|
||||
+#define VERSIONX "oran_f_release_v1.8"
|
||||
+#define VERSIONX "oran_f_release_v1.9"
|
||||
|
||||
#define APP_O_DU 0
|
||||
#define APP_O_RU 1
|
||||
@@ -173,20 +173,18 @@ index eccc4ae..a97fdc6 100644
|
||||
CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF)
|
||||
CPP_FLAGS_FULL_SNC := $(CPP_FLAGS) $(CPP_COMP_SNC) $(INC) $(DEF)
|
||||
diff --git a/fhi_lib/lib/api/xran_fh_o_du.h b/fhi_lib/lib/api/xran_fh_o_du.h
|
||||
index bacf597..18597d6 100644
|
||||
index bacf597..c37e132 100644
|
||||
--- a/fhi_lib/lib/api/xran_fh_o_du.h
|
||||
+++ b/fhi_lib/lib/api/xran_fh_o_du.h
|
||||
@@ -141,8 +141,8 @@ extern "C" {
|
||||
@@ -141,7 +141,7 @@ extern "C" {
|
||||
#define XRAN_MAX_SECTIONS_PER_SYM (XRAN_MAX_SECTIONS_PER_SLOT) /**< Max number of different sections in single slot (section may be equal to RB allocation for UE) */
|
||||
#define XRAN_MIN_SECTIONS_PER_SYM (XRAN_MIN_SECTIONS_PER_SLOT) /**< Min number of different sections in single slot (section may be equal to RB allocation for UE) */
|
||||
|
||||
-#define XRAN_MAX_FRAGMENT (4) /**< Max number of fragmentations in single symbol */
|
||||
-#define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
|
||||
+#define XRAN_MAX_FRAGMENT (7) /**< Max number of fragmentations in single symbol */
|
||||
+#define XRAN_MAX_SET_BFWS (1) //(64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
|
||||
#define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */
|
||||
|
||||
#define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */
|
||||
#define XRAN_N_MAX_BUFFER_SEGMENT XRAN_MAX_PKT_BURST /**< Max number of segments per ms */
|
||||
@@ -419,6 +419,7 @@ struct xran_io_cfg {
|
||||
uint16_t num_rxq; /**< number of RX queues per VF */
|
||||
char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices */
|
||||
@@ -195,15 +193,7 @@ index bacf597..18597d6 100644
|
||||
int32_t bbdev_mode; /**< DPDK for BBDev */
|
||||
uint32_t dpdkIoVaMode; /**< IOVA Mode */
|
||||
uint32_t dpdkMemorySize; /**< DPDK max memory allocation */
|
||||
@@ -713,6 +714,7 @@ struct xran_fh_config {
|
||||
uint16_t max_sections_per_slot; /**< M-Plane settings for section */
|
||||
uint16_t max_sections_per_symbol; /**< M-Plane settings for section */
|
||||
int32_t RunSlotPrbMapBySymbolEnable; /**< enable prb mapping by symbol with multisection*/
|
||||
+ uint8_t LiteOnIgnoreUPSectionIdEnable; /**< handle LiteOn issue where section id on UP packet is wrongly set to 13. */
|
||||
|
||||
uint8_t dssEnable; /**< enable DSS (extension-9) */
|
||||
uint8_t dssPeriod; /**< DSS pattern period for LTE/NR */
|
||||
@@ -1193,6 +1195,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb,
|
||||
@@ -1193,6 +1194,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb,
|
||||
*/
|
||||
int32_t xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond);
|
||||
|
||||
@@ -594,7 +584,7 @@ index 08660f3..b5de607 100644
|
||||
|
||||
time_diff_nSymb = time_diff_us*1000/(interval_us_local*1000/N_SYM_PER_SLOT);
|
||||
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
|
||||
index dc40ad9..1b88013 100644
|
||||
index dc40ad9..5968d01 100644
|
||||
--- a/fhi_lib/lib/src/xran_common.c
|
||||
+++ b/fhi_lib/lib/src/xran_common.c
|
||||
@@ -31,7 +31,10 @@
|
||||
@@ -608,110 +598,7 @@ index dc40ad9..1b88013 100644
|
||||
#include <rte_mbuf.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
@@ -49,6 +52,8 @@
|
||||
#include "xran_printf.h"
|
||||
#include "xran_mlog_lnx.h"
|
||||
|
||||
+#include "xran_frame_struct.h"
|
||||
+
|
||||
static struct timespec sleeptime = {.tv_nsec = 1E3 }; /* 1 us */
|
||||
|
||||
extern int32_t first_call;
|
||||
@@ -529,13 +534,30 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
|
||||
if (pRbMap)
|
||||
{
|
||||
/** Get the prb_elem_id */
|
||||
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ if(0 == p_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
|
||||
+ section_id_tmp = prb_elem_id_tmp = sect_id[i];
|
||||
+ } else {
|
||||
+ u_int8_t mixed_ul_sym_start = 0;
|
||||
+ if (xran_fs_get_slot_type(xran_port, CC_ID[i], tti, XRAN_SLOT_TYPE_SP)) {
|
||||
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID[i], tti);
|
||||
+ }
|
||||
+ u_int8_t section_id_tmp = symb_id[i] - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
total_sections=0;
|
||||
if(pRbMap->prbMap[0].bf_weight.extType == 1)
|
||||
{
|
||||
for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++)
|
||||
{
|
||||
total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs;
|
||||
- if(total_sections >= (sect_id[i] + 1))
|
||||
+ if(total_sections >= (/*sect_id[i]*/ prb_elem_id_tmp + 1))
|
||||
{
|
||||
prb_elem_id[i] = idxElm;
|
||||
break;
|
||||
@@ -544,12 +566,12 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
|
||||
}
|
||||
else
|
||||
{
|
||||
- prb_elem_id[i] = sect_id[i];
|
||||
+ prb_elem_id[i] = prb_elem_id_tmp; /*sect_id[i];*/
|
||||
}
|
||||
|
||||
if (prb_elem_id[i] >= pRbMap->nPrbElm)
|
||||
{
|
||||
- print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm);
|
||||
+ print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", /*sect_id[i]*/ section_id_tmp, prb_elem_id[i], pRbMap->nPrbElm);
|
||||
ret_data[i] = MBUF_FREE;
|
||||
continue;
|
||||
}
|
||||
@@ -615,13 +637,30 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
|
||||
if (pRbMap)
|
||||
{
|
||||
/** Get the prb_elem_id */
|
||||
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ if(0 == p_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
|
||||
+ section_id_tmp = prb_elem_id_tmp = sect_id[i];
|
||||
+ } else {
|
||||
+ u_int8_t mixed_ul_sym_start = 0;
|
||||
+ if (xran_fs_get_slot_type(xran_port, CC_ID[i], tti, XRAN_SLOT_TYPE_SP)) {
|
||||
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID[i], tti);
|
||||
+ }
|
||||
+ u_int8_t section_id_tmp = symb_id[i] - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
total_sections=0;
|
||||
if(pRbMap->prbMap[0].bf_weight.extType == 1)
|
||||
{
|
||||
for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++)
|
||||
{
|
||||
total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs;
|
||||
- if(total_sections >= (sect_id[i] + 1))
|
||||
+ if(total_sections >= (/*sect_id[i]*/ prb_elem_id_tmp + 1))
|
||||
{
|
||||
prb_elem_id[i] = idxElm;
|
||||
break;
|
||||
@@ -630,12 +669,12 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru
|
||||
}
|
||||
else
|
||||
{
|
||||
- prb_elem_id[i] = sect_id[i];
|
||||
+ prb_elem_id[i] = prb_elem_id_tmp; /*sect_id[i];*/
|
||||
}
|
||||
|
||||
if (prb_elem_id[i] >= pRbMap->nPrbElm)
|
||||
{
|
||||
- print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm);
|
||||
+ print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", /*sect_id[i]*/ section_id_tmp, prb_elem_id[i], pRbMap->nPrbElm);
|
||||
ret_data[i] = MBUF_FREE;
|
||||
continue;
|
||||
}
|
||||
@@ -714,11 +753,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
@@ -714,11 +717,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
uint8_t compMeth = 0;
|
||||
uint8_t iqWidth = 0;
|
||||
|
||||
@@ -726,7 +613,7 @@ index dc40ad9..1b88013 100644
|
||||
|
||||
if(first_call == 0)
|
||||
return ret;
|
||||
@@ -733,9 +775,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
@@ -733,9 +739,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
return MBUF_FREE;
|
||||
|
||||
num_bytes = xran_extract_iq_samples(pkt, &iq_samp_buf,
|
||||
@@ -738,7 +625,7 @@ index dc40ad9..1b88013 100644
|
||||
if (num_bytes <= 0)
|
||||
{
|
||||
print_err("num_bytes is wrong [%d]\n", num_bytes);
|
||||
@@ -781,10 +823,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
@@ -781,10 +787,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
|
||||
else
|
||||
{
|
||||
@@ -752,7 +639,7 @@ index dc40ad9..1b88013 100644
|
||||
#ifndef FCN_ADAPT
|
||||
if(valid_res != 0)
|
||||
{
|
||||
@@ -807,8 +848,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
@@ -807,8 +812,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
|
||||
PrachCfg = &(p_dev_ctx->PrachCPConfig);
|
||||
}
|
||||
|
||||
@@ -762,7 +649,7 @@ index dc40ad9..1b88013 100644
|
||||
/* PRACH packet has ruportid = num_eAxc + ant_id */
|
||||
Ant_ID -= PrachCfg->eAxC_offset;
|
||||
symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes;
|
||||
@@ -1412,7 +1452,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc
|
||||
@@ -1412,7 +1416,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc
|
||||
if(XRAN_FILTERINDEX_PRACH_ABC == pPrachCPConfig->filterIdx)
|
||||
{
|
||||
timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
|
||||
@@ -771,7 +658,7 @@ index dc40ad9..1b88013 100644
|
||||
timeOffset += 16;
|
||||
}
|
||||
else
|
||||
@@ -1547,8 +1587,7 @@ int32_t ring_processing_func(void* args)
|
||||
@@ -1547,8 +1551,7 @@ int32_t ring_processing_func(void* args)
|
||||
|
||||
for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){
|
||||
for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) {
|
||||
@@ -1081,18 +968,10 @@ index 4acade1..c939edc 100644
|
||||
for(i = 0; i < xran_ports_num; i++){
|
||||
g_xran_dev_ctx[i] = pCtx;
|
||||
diff --git a/fhi_lib/lib/src/xran_dev.h b/fhi_lib/lib/src/xran_dev.h
|
||||
index 0371a53..778b38d 100644
|
||||
index 0371a53..b417619 100644
|
||||
--- a/fhi_lib/lib/src/xran_dev.h
|
||||
+++ b/fhi_lib/lib/src/xran_dev.h
|
||||
@@ -201,6 +201,7 @@ struct __rte_cache_aligned xran_device_ctx
|
||||
|
||||
int32_t DynamicSectionEna;
|
||||
int32_t RunSlotPrbMapBySymbolEnable;
|
||||
+ uint8_t LiteOnIgnoreUPSectionIdEnable; /**< handle LiteOn issue where section id on UP packet is wrongly set to 13. */
|
||||
int64_t offset_sec;
|
||||
int64_t offset_nsec; //offset to GPS time calcuated based on alpha and beta
|
||||
uint32_t interval_us_local;
|
||||
@@ -254,6 +255,11 @@ struct __rte_cache_aligned xran_device_ctx
|
||||
@@ -254,6 +254,11 @@ struct __rte_cache_aligned xran_device_ctx
|
||||
int32_t sym_up; /**< when we start sym 0 of up with respect to OTA time as measured in symbols */
|
||||
int32_t sym_up_ul;
|
||||
|
||||
@@ -1105,45 +984,17 @@ index 0371a53..778b38d 100644
|
||||
void *TtiCbParam[XRAN_CB_MAX];
|
||||
uint32_t SkipTti[XRAN_CB_MAX];
|
||||
diff --git a/fhi_lib/lib/src/xran_frame_struct.c b/fhi_lib/lib/src/xran_frame_struct.c
|
||||
index fbb1298..44aaf92 100644
|
||||
index fbb1298..385de76 100644
|
||||
--- a/fhi_lib/lib/src/xran_frame_struct.c
|
||||
+++ b/fhi_lib/lib/src/xran_frame_struct.c
|
||||
@@ -519,4 +519,20 @@ int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlot
|
||||
@@ -518,5 +518,3 @@ int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlot
|
||||
|
||||
return xran_fs_slot_symb_type[PortId][nCellIdx][nSfIdxMod][nSymbIdx];
|
||||
}
|
||||
|
||||
+uint32_t xran_fs_get_num_dl_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx)
|
||||
+{
|
||||
+ int32_t nSfIdxMod;
|
||||
+
|
||||
+ nSfIdxMod = xran_fs_slot_limit(PortId, nSlotdx) % ((xran_fs_num_slot_tdd_loop[PortId][nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[PortId][nCellIdx]: 1);
|
||||
+
|
||||
+ return xran_fs_num_dl_sym_sp[PortId][nCellIdx][nSfIdxMod];
|
||||
+}
|
||||
|
||||
+uint32_t xran_fs_get_num_ul_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx)
|
||||
+{
|
||||
+ int32_t nSfIdxMod;
|
||||
+
|
||||
+ nSfIdxMod = xran_fs_slot_limit(PortId, nSlotdx) % ((xran_fs_num_slot_tdd_loop[PortId][nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[PortId][nCellIdx]: 1);
|
||||
+
|
||||
+ return xran_fs_num_ul_sym_sp[PortId][nCellIdx][nSfIdxMod];
|
||||
+}
|
||||
diff --git a/fhi_lib/lib/src/xran_frame_struct.h b/fhi_lib/lib/src/xran_frame_struct.h
|
||||
index 7ed0a3a..8e66945 100644
|
||||
--- a/fhi_lib/lib/src/xran_frame_struct.h
|
||||
+++ b/fhi_lib/lib/src/xran_frame_struct.h
|
||||
@@ -75,6 +75,8 @@ uint32_t xran_fs_slot_limit_init(uint32_t PortId, int32_t tti_interval_us);
|
||||
uint32_t xran_fs_get_max_slot(uint32_t PortId);
|
||||
uint32_t xran_fs_get_max_slot_SFN(uint32_t PortId);
|
||||
int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx);
|
||||
+uint32_t xran_fs_get_num_dl_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx);
|
||||
+uint32_t xran_fs_get_num_ul_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
-
|
||||
-
|
||||
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
|
||||
index 7c472d7..db03d94 100644
|
||||
index 7c472d7..758616d 100644
|
||||
--- a/fhi_lib/lib/src/xran_main.c
|
||||
+++ b/fhi_lib/lib/src/xran_main.c
|
||||
@@ -35,7 +35,11 @@
|
||||
@@ -1847,15 +1698,7 @@ index 7c472d7..db03d94 100644
|
||||
if(pThCtx == NULL){
|
||||
print_err("pThCtx allocation error\n");
|
||||
return XRAN_STATUS_FAIL;
|
||||
@@ -3754,6 +3808,7 @@ xran_open(void *pHandle, struct xran_fh_config* pConf)
|
||||
p_xran_dev_ctx->puschMaskSlot = pConf->puschMaskSlot;
|
||||
p_xran_dev_ctx->DynamicSectionEna = pConf->DynamicSectionEna;
|
||||
p_xran_dev_ctx->RunSlotPrbMapBySymbolEnable = pConf->RunSlotPrbMapBySymbolEnable;
|
||||
+ p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable = pConf->LiteOnIgnoreUPSectionIdEnable;
|
||||
p_xran_dev_ctx->dssEnable = pConf->dssEnable;
|
||||
p_xran_dev_ctx->dssPeriod = pConf->dssPeriod;
|
||||
for(i=0; i<pConf->dssPeriod; i++) {
|
||||
@@ -4034,6 +4089,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
|
||||
@@ -4034,6 +4088,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
|
||||
return tti;
|
||||
}
|
||||
|
||||
@@ -1880,7 +1723,7 @@ index 7c472d7..db03d94 100644
|
||||
int32_t
|
||||
xran_set_debug_stop(int32_t value, int32_t count)
|
||||
{
|
||||
@@ -4208,7 +4281,7 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
|
||||
@@ -4208,7 +4280,7 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
|
||||
int32_t i = 0, j = 0, nPrbElm = 0;
|
||||
int16_t iqwidth = p_PrbMapIn->prbMap[0].iqWidth;
|
||||
struct xran_prb_elm *p_prb_elm_src, *p_prb_elm_dst;
|
||||
@@ -1889,7 +1732,7 @@ index 7c472d7..db03d94 100644
|
||||
int32_t nRBStart_tmp, nRBremain, nStartSymb, nEndSymb, nRBStart, nRBEnd, nRBSize;
|
||||
// int32_t eth_xran_up_headers_sz = sizeof(struct eth_xran_up_pkt_hdr);
|
||||
// int32_t nmaxRB = (mtu - eth_xran_up_headers_sz - RTE_PKTMBUF_HEADROOM)/XRAN_PAYLOAD_1_RB_SZ(iqwidth);
|
||||
@@ -4217,7 +4290,6 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
|
||||
@@ -4217,7 +4289,6 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
|
||||
if (mtu==9600)
|
||||
nmaxRB--; //for some reason when mtu is 9600, only 195 RB can be sent, not 196
|
||||
|
||||
@@ -1897,7 +1740,7 @@ index 7c472d7..db03d94 100644
|
||||
memcpy(p_PrbMapOut, p_PrbMapIn, sizeof(struct xran_prb_map));
|
||||
for(i = 0; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++)
|
||||
{
|
||||
@@ -4292,26 +4364,30 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
|
||||
@@ -4292,27 +4363,23 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str
|
||||
|
||||
for(; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++)
|
||||
{
|
||||
@@ -1906,8 +1749,7 @@ index 7c472d7..db03d94 100644
|
||||
- prbMapTemp[nPrbElm].numSymb++;
|
||||
- }
|
||||
- else
|
||||
+ if((prbMapTemp[i].nRBSize != 0))
|
||||
{
|
||||
- {
|
||||
- nPrbElm++;
|
||||
- prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb;
|
||||
- prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart;
|
||||
@@ -1922,31 +1764,27 @@ index 7c472d7..db03d94 100644
|
||||
-
|
||||
- nRBStart = prbMapTemp[i].nRBStart;
|
||||
- nRBSize = prbMapTemp[i].nRBSize;
|
||||
+ if (false) // Force it to generate multiple prbMapElm, one for each symbol even if they are of the same RBs
|
||||
+ //if((nRBStart == prbMapTemp[i].nRBStart) && (nRBSize == prbMapTemp[i].nRBSize))
|
||||
+ {
|
||||
+ prbMapTemp[nPrbElm].numSymb++;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ nPrbElm++;
|
||||
+ prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb;
|
||||
+ prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart;
|
||||
+ prbMapTemp[nPrbElm].nRBSize = prbMapTemp[i].nRBSize;
|
||||
+ prbMapTemp[nPrbElm].nBeamIndex = prbMapTemp[i].nBeamIndex;
|
||||
+ prbMapTemp[nPrbElm].bf_weight_update = prbMapTemp[i].bf_weight_update;
|
||||
+ prbMapTemp[nPrbElm].compMethod = prbMapTemp[i].compMethod;
|
||||
+ prbMapTemp[nPrbElm].iqWidth = prbMapTemp[i].iqWidth;
|
||||
+ prbMapTemp[nPrbElm].ScaleFactor = prbMapTemp[i].ScaleFactor;
|
||||
+ prbMapTemp[nPrbElm].reMask = prbMapTemp[i].reMask;
|
||||
+ prbMapTemp[nPrbElm].BeamFormingType = prbMapTemp[i].BeamFormingType;
|
||||
- }
|
||||
+ /* force using a separate section for each symbol in one multisection CP (both DL and UL) message;
|
||||
+ * when generating DL UP, symbol index should be within nStartSymb and (nStartSymb + numSymb);
|
||||
+ * nPrbElm doesn't have any affect on UL UP */
|
||||
+ nPrbElm++;
|
||||
+ prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb;
|
||||
+ prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart;
|
||||
+ prbMapTemp[nPrbElm].nRBSize = prbMapTemp[i].nRBSize;
|
||||
+ prbMapTemp[nPrbElm].nBeamIndex = prbMapTemp[i].nBeamIndex;
|
||||
+ prbMapTemp[nPrbElm].bf_weight_update = prbMapTemp[i].bf_weight_update;
|
||||
+ prbMapTemp[nPrbElm].compMethod = prbMapTemp[i].compMethod;
|
||||
+ prbMapTemp[nPrbElm].iqWidth = prbMapTemp[i].iqWidth;
|
||||
+ prbMapTemp[nPrbElm].ScaleFactor = prbMapTemp[i].ScaleFactor;
|
||||
+ prbMapTemp[nPrbElm].reMask = prbMapTemp[i].reMask;
|
||||
+ prbMapTemp[nPrbElm].BeamFormingType = prbMapTemp[i].BeamFormingType;
|
||||
+
|
||||
+ nRBStart = prbMapTemp[i].nRBStart;
|
||||
+ nRBSize = prbMapTemp[i].nRBSize;
|
||||
+ }
|
||||
}
|
||||
+ nRBStart = prbMapTemp[i].nRBStart;
|
||||
+ nRBSize = prbMapTemp[i].nRBSize;
|
||||
}
|
||||
|
||||
for(i = 0; i < nPrbElm; i++)
|
||||
diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c
|
||||
index e1dcb6c..b3c3fae 100644
|
||||
--- a/fhi_lib/lib/src/xran_mem_mgr.c
|
||||
@@ -1980,7 +1818,7 @@ index 7d4a5d0..b9b44ac 100644
|
||||
#endif
|
||||
}
|
||||
diff --git a/fhi_lib/lib/src/xran_rx_proc.c b/fhi_lib/lib/src/xran_rx_proc.c
|
||||
index e7056f4..34b6d3b 100644
|
||||
index e7056f4..4941360 100644
|
||||
--- a/fhi_lib/lib/src/xran_rx_proc.c
|
||||
+++ b/fhi_lib/lib/src/xran_rx_proc.c
|
||||
@@ -35,7 +35,11 @@
|
||||
@@ -1995,127 +1833,16 @@ index e7056f4..34b6d3b 100644
|
||||
|
||||
#include <rte_common.h>
|
||||
#include <rte_eal.h>
|
||||
@@ -339,13 +343,33 @@ int32_t xran_process_srs_sym(void *arg,
|
||||
pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFHSrsRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData;
|
||||
if(pRbMap)
|
||||
{
|
||||
- prbMapElm = &pRbMap->prbMap[sect_id];
|
||||
- if(sect_id >= pRbMap->nPrbElm)
|
||||
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
|
||||
+ section_id_tmp = prb_elem_id_tmp = sect_id;
|
||||
+ } else {
|
||||
+ /** Get the prb_elem_id */
|
||||
+ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx);
|
||||
+ u_int8_t mixed_ul_sym_start = 0;
|
||||
+ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) {
|
||||
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti);
|
||||
+ }
|
||||
+
|
||||
+ section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
+ prbMapElm = &pRbMap->prbMap[prb_elem_id_tmp /*sect_id*/];
|
||||
+ if(/*sect_id*/ prb_elem_id_tmp >= pRbMap->nPrbElm)
|
||||
{
|
||||
- print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm);
|
||||
- *mb_free = MBUF_FREE;
|
||||
- return size;
|
||||
- }
|
||||
+ print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm);
|
||||
+ *mb_free = MBUF_FREE;
|
||||
+ return size;
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -397,7 +421,25 @@ int32_t xran_process_srs_sym(void *arg,
|
||||
else */
|
||||
{
|
||||
struct xran_section_desc *p_sec_desc = NULL;
|
||||
- prbMapElm = &pRbMap->prbMap[sect_id];
|
||||
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
|
||||
+ section_id_tmp = prb_elem_id_tmp = sect_id;
|
||||
+ } else {
|
||||
+ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx);
|
||||
+ u_int8_t mixed_ul_sym_start = 0;
|
||||
+ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) {
|
||||
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti);
|
||||
+ }
|
||||
+ u_int8_t section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ }
|
||||
+
|
||||
+ prbMapElm = &pRbMap->prbMap[prb_elem_id_tmp /*sect_id*/];
|
||||
// sec_desc_idx = 0;//prbMapElm->nSecDesc[symb_id];
|
||||
sec_desc_idx = prbMapElm->nSecDesc[symb_id];
|
||||
|
||||
@@ -537,14 +579,33 @@ int32_t xran_process_rx_sym(void *arg,
|
||||
@@ -537,6 +541,9 @@ int32_t xran_process_rx_sym(void *arg,
|
||||
pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
|
||||
pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData;
|
||||
if(pRbMap){
|
||||
- /** Get the prb_elem_id */
|
||||
+ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13
|
||||
+ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) {
|
||||
+ section_id_tmp = prb_elem_id_tmp = sect_id;
|
||||
+ } else {
|
||||
+ /** Get the prb_elem_id */
|
||||
+ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx);
|
||||
+ u_int8_t mixed_ul_sym_start = 0;
|
||||
+ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) {
|
||||
+ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti);
|
||||
+ }
|
||||
+
|
||||
+ section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000
|
||||
+ //Note for future reference when using MTU 1500
|
||||
+ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500
|
||||
+ if (p_xran_dev_ctx->RunSlotPrbMapBySymbolEnable) {
|
||||
+ sect_id = (pRbMap->nPrbElm == XRAN_NUM_OF_SYMBOL_PER_SLOT) ? symb_id : symb_id - (XRAN_NUM_OF_SYMBOL_PER_SLOT - pRbMap->nPrbElm);
|
||||
+ }
|
||||
+
|
||||
/** Get the prb_elem_id */
|
||||
total_sections=0;
|
||||
if(pRbMap->prbMap[0].bf_weight.extType == 1)
|
||||
{
|
||||
for(i=0 ; i < pRbMap->nPrbElm ; i++)
|
||||
{
|
||||
total_sections += pRbMap->prbMap[i].bf_weight.numSetBFWs;
|
||||
- if(total_sections >= (sect_id + 1))
|
||||
+ if(total_sections >= (/*sect_id*/ section_id_tmp + 1))
|
||||
{
|
||||
prb_elem_id = i;
|
||||
break;
|
||||
@@ -553,7 +614,7 @@ int32_t xran_process_rx_sym(void *arg,
|
||||
}
|
||||
else
|
||||
{
|
||||
- prb_elem_id = sect_id;
|
||||
+ prb_elem_id = prb_elem_id_tmp; /*sect_id*/;
|
||||
}
|
||||
|
||||
prbMapElm = &pRbMap->prbMap[prb_elem_id];
|
||||
@@ -597,7 +658,7 @@ int32_t xran_process_rx_sym(void *arg,
|
||||
if(p_sec_desc){
|
||||
mb = p_sec_desc->pCtrl;
|
||||
if(mb){
|
||||
- rte_pktmbuf_free(mb);
|
||||
+ rte_pktmbuf_free(mb);
|
||||
}
|
||||
p_sec_desc->pData = iq_data_start;
|
||||
p_sec_desc->pCtrl = mbuf;
|
||||
diff --git a/fhi_lib/lib/src/xran_timer.c b/fhi_lib/lib/src/xran_timer.c
|
||||
index 14a6a41..55182d8 100644
|
||||
--- a/fhi_lib/lib/src/xran_timer.c
|
||||
|
||||
@@ -8,7 +8,7 @@ CXXFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen -std=c++11
|
||||
LIBS=-lm
|
||||
XLIBS=-lX11 -lpng -lXft
|
||||
|
||||
all: record record_db replay extract_config textlog enb ue vcd macpdu2wireshark \
|
||||
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
|
||||
extract_input_subframe extract_output_subframe to_vcd extract multi \
|
||||
gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac csv
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, g
|
||||
e->ul_freq_estimate_ue_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, 0, 2048, -10, 80);
|
||||
l = new_framelog(h, database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", "subframe", "chest_t");
|
||||
l = new_framelog(h, database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", "subframe", "chest_f");
|
||||
framelog_set_update_only_at_sf9(l, 0);
|
||||
v = new_view_xy(2048, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE);
|
||||
logger_add_view(l, v);
|
||||
|
||||
@@ -366,6 +366,10 @@ void nr_deconstruct_5g_s_tmsi(const uint64_t fiveg_s_tmsi, uint16_t *amf_set_id,
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b)))
|
||||
|
||||
/* Macro used to perform a circular increment. This implementation is computationally more efficient than using the remainder of the
|
||||
* integer division, and improves code readability when compared to repetitive if... else statements. */
|
||||
#define CIRCULAR_INC(val, inc, size) (((val) + (inc) >= (size)) ? ((val) + (inc) - (size)) : ((val) + (inc)))
|
||||
|
||||
static const char *const duplex_mode_txt[] = {"FDD", "TDD"};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -61,8 +61,8 @@ We tested the category A radio units listed below.
|
||||
|-----------------|---------------------------------------------|
|
||||
|VVDN LPRU |03-v3.0.5 |
|
||||
|LiteON RU |01.00.08/02.00.03/02.00.10 |
|
||||
|Benetel 650 |RAN650-1v1.0.4-dda1bf5|RAN650-1v1.2.2-2fa04bc|
|
||||
|Benetel 550 |RAN550-1v1.0.4-605a25a|RAN550-1v1.2.2-2fa04bc|
|
||||
|Benetel 650 |RAN650-1v1.0.4-dda1bf5/RAN650-1v1.2.2-2fa04bc/RAN650-1v1.4.2-NM-c48047d|
|
||||
|Benetel 550 |RAN550-1v1.0.4-605a25a/RAN550-1v1.2.2-2fa04bc/RAN550-1v1.4.1-M-25fa970/RAN550-1v2.0.5-M-92a9d2c|
|
||||
|Foxconn RPQN |v3.1.15q.551_rc10 |
|
||||
|
||||
Tested libxran releases:
|
||||
@@ -563,13 +563,16 @@ flexran_prach_workaround=disabled
|
||||
dl_tuning_special_slot=0x13b6
|
||||
```
|
||||
|
||||
#### LITEON
|
||||
In addition, PRACH format 0 is also verified with FW v2.0.5. An example gNB config file can be found at [`gnb.sa.band77.273prb.fhi72.2x2-benetel550-long-prach.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.2x2-benetel550-long-prach.conf). On the RU side, the following parameters shall be modified:
|
||||
```bash
|
||||
mimo_mode=1_3
|
||||
prach_format=long
|
||||
prach_freq_offset_dynamic=false
|
||||
lf_prach_compression_enable=true
|
||||
lf_prach_slot_id=0
|
||||
```
|
||||
|
||||
The OAI configuration file [`gnb.sa.band78.273prb.fhi72.4x4-liteon.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf) corresponds to:
|
||||
- TDD pattern `DDDSU`, 2.5ms
|
||||
- Bandwidth 100MHz
|
||||
- MTU 1500
|
||||
- MTU 9216: v02.00.10
|
||||
#### LITEON
|
||||
|
||||
##### RU configuration
|
||||
|
||||
@@ -593,7 +596,15 @@ Once the RU is PTP synced, and RF state and DPD are `Ready`, write `configure te
|
||||
- DU MAC address
|
||||
...
|
||||
|
||||
The configuration mode example:
|
||||
###### FR1
|
||||
|
||||
The OAI configuration file [`gnb.sa.band78.273prb.fhi72.4x4-liteon.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf) corresponds to:
|
||||
- TDD pattern `DDDSU`, 2.5ms
|
||||
- Bandwidth 100MHz
|
||||
- MTU 1500
|
||||
- MTU 9216: v02.00.10
|
||||
|
||||
The RU configuration mode example:
|
||||
```bash
|
||||
compression-bit 9 # set IQ bitwidth for PxSCH/PRACH
|
||||
eAXC_id 4 5 6 7 # set PRACH eAxC IDs
|
||||
@@ -601,6 +612,21 @@ jumboframe 1 # enable jumbo frame
|
||||
...
|
||||
```
|
||||
|
||||
###### FR2
|
||||
|
||||
The OAI configuration file [`gnb.sa.band257.66prb.fhi72.2x2-liteon.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.66prb.fhi72.2x2-liteon.conf) corresponds to:
|
||||
- TDD pattern `DDDDDDDSUU`, 1.25ms
|
||||
- Bandwidth 100MHz
|
||||
- FW v02.00.07
|
||||
- DL uses jumbo frame, UL uses standard MTU of 1500 bytes
|
||||
|
||||
The RU configuration mode example:
|
||||
```bash
|
||||
compression-bit 8 # set IQ bitwidth for PxSCH/PRACH
|
||||
eAXC_id 0 1 # set PRACH eAxC IDs
|
||||
...
|
||||
```
|
||||
|
||||
#### VVDN LPRU
|
||||
|
||||
**Version 3.x**
|
||||
@@ -970,6 +996,14 @@ Edit the sample OAI gNB configuration file and check following parameters:
|
||||
* `GNB_IPV4_ADDRESS_FOR_NGU` shall match your gNB N3 interface IP address
|
||||
* `prach_ConfigurationIndex`
|
||||
* `prach_msg1_FrequencyStart`
|
||||
* `ssPBCH_BlockPower` is average EPRE of the resource elements carrying the secondary synchronization signals, expressed in dBm. It can be estimated using the following formula:
|
||||
|
||||
> ssPBCH_BlockPower = P_TX − 10 x log10(N_RE) + 10 x log10(N_antenna_SSB)
|
||||
|
||||
where:
|
||||
* `P_TX` is the total transmit power of the RU in dBm (configured on the RU).
|
||||
* `N_RE` is the number of resource elements used for the transmission.
|
||||
* `N_antenna_SSB` is the number of antenna ports used for SSB transmission (currently, a single antenna port is used for SSB transmission).
|
||||
* Adjust the frequency, bandwidth and SSB position
|
||||
|
||||
* `L1s` section
|
||||
@@ -1012,6 +1046,7 @@ Edit the sample OAI gNB configuration file and check following parameters:
|
||||
[Memory in DPDK](https://www.dpdk.org/memory-in-dpdk-part-2-deep-dive-into-iova/)
|
||||
* `owdm_enable`: used for eCPRI One-Way Delay Measurements; it depends if the RU supports it; if not set to 1 (enabled), default value is 0 (disabled)
|
||||
* `fh_config`
|
||||
* `RunSlotPrbMapBySymbol`: enable CP multisection (one symbol per section); default value is 0
|
||||
* DU delay profile (`T1a` and `Ta4`): pairs of numbers `(x, y)` specifying minimum and maximum delays
|
||||
* `ru_config`: RU-specific configuration:
|
||||
* `iq_width`: Width of DL/UL IQ samples: if 16, no compression, if <16, applies
|
||||
|
||||
+4
-1
@@ -464,7 +464,10 @@ sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF
|
||||
The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC and circumventing random access. In this case both gNB and eNB need to be run with the `--phy-test` flag. At the gNB this flag does the following
|
||||
- it reads the RRC configuration from the configuration file
|
||||
- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files `rbconfig.raw` and `reconfig.raw` in the current directory
|
||||
- the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload instead of the standard scheduler. The options `-m`, `-l`, `-t`, `-M`, `-T`, `-D`, and `-U` can be used to configure this scheduler. See `./nr-softmodem -h` for more information.
|
||||
- the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload instead of the standard scheduler. The options `-m`, `-l`, `-t`, `-M`, `-T`, `-D`, and `-U` can be used to configure this scheduler.
|
||||
- Options `-Dmod`, and `-Umod` were introduced to enable scheduling PDSCH/PUSCH on slots >= 64 in phy-test mode. (in case of >= 120Khz subcarrier spacing and FDD)
|
||||
- For ex: `-Dmod 2' / '-Umod 2` allocates every 2nd slot for PDSCH or PUSCH respectively.
|
||||
- See `./nr-softmodem -h` for more information.
|
||||
|
||||
At the UE, the `--phy-test` flag will read the binary files `rbconfig.raw` and `reconfig.raw` from the current directory and process them. If you wish to provide a different path for these files, please use the options `--reconfig-file` and `--rbconfig-file`.
|
||||
|
||||
|
||||
+3
-8
@@ -998,9 +998,10 @@ void *ru_thread(void *param)
|
||||
proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP);
|
||||
|
||||
// Do PRACH RU processing
|
||||
prach_item_t *p = find_nr_prach(&gNB->prach_list, proc->frame_rx, proc->tti_rx, SEARCH_EXIST);
|
||||
prach_item_t *p =
|
||||
find_nr_prach(&gNB->prach_list, proc->frame_rx, proc->tti_rx, gNB->frame_parms.nb_antennas_rx, SEARCH_EXIST);
|
||||
if (p) {
|
||||
// need to extract RACH data for lqter processing by rx_nr_prach()
|
||||
// need to extract RACH data for later processing by rx_nr_prach()
|
||||
rx_nr_prach_ru(p, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset);
|
||||
} // end if (prach_id >= 0)
|
||||
} // end if (ru->feprx)
|
||||
@@ -1458,13 +1459,7 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
} /* strcmp(local_rf, "yes") != 0 */
|
||||
|
||||
ru->nb_tx = *param[RU_NB_TX_IDX].uptr;
|
||||
AssertFatal(ru->nb_tx <= NB_ANTENNAS_TX,
|
||||
"Config file has %d TX antennas set, but the compile time max value in NB_ANTENNAS_TX\n",
|
||||
ru->nb_tx);
|
||||
ru->nb_rx = *param[RU_NB_RX_IDX].uptr;
|
||||
AssertFatal(ru->nb_rx <= NB_ANTENNAS_RX,
|
||||
"Config file has %d RX antennas set, but the compile time max value in NB_ANTENNAS_RX\n",
|
||||
ru->nb_rx);
|
||||
ru->att_tx = *param[RU_ATT_TX_IDX].uptr;
|
||||
ru->att_rx = *param[RU_ATT_RX_IDX].uptr;
|
||||
ru->if_frequency = *param[RU_IF_FREQUENCY].u64ptr;
|
||||
|
||||
@@ -55,5 +55,7 @@
|
||||
#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLBM_PHYTEST "Bitmap for DLSCH slots in period (slot 0 starts at LSB)\n"
|
||||
#define CONFIG_HLP_ULBM_PHYTEST "Bitmap for ULSCH slots in period (slot 0 starts at LSB)\n"
|
||||
#define CONFIG_HLP_DLMOD_PHYTEST "For-DLSCH, if val is n, every nth slot in slots per frame will be scheduled. \n"
|
||||
#define CONFIG_HLP_ULMOD_PHYTEST "For ULSCH, if val is n, every nth slot in slots per frame will be scheduled. \n"
|
||||
void wait_gNBs(void);
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
{"T" , CONFIG_HLP_ULBW_PHYTEST, 0, .uptr=&target_ul_bw, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"D" , CONFIG_HLP_DLBM_PHYTEST, 0, .u64ptr=&dlsch_slot_bitmap, .defint64val=0, TYPE_UINT64, 0}, \
|
||||
{"U" , CONFIG_HLP_ULBM_PHYTEST, 0, .u64ptr=&ulsch_slot_bitmap, .defint64val=0, TYPE_UINT64, 0}, \
|
||||
{"Dmod" , CONFIG_HLP_DLMOD_PHYTEST, 0, .uptr=&dlsch_slot_modval, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"Umod" , CONFIG_HLP_ULMOD_PHYTEST, 0, .uptr=&ulsch_slot_modval, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, .iptr=&usrp_tx_thread, .defstrval=0, TYPE_INT, 0}, \
|
||||
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
|
||||
}
|
||||
@@ -39,6 +41,8 @@ extern uint32_t target_ul_bw;
|
||||
extern uint64_t dlsch_slot_bitmap;
|
||||
extern uint64_t ulsch_slot_bitmap;
|
||||
extern char *uecap_file;
|
||||
extern uint32_t dlsch_slot_modval;
|
||||
extern uint32_t ulsch_slot_modval;
|
||||
|
||||
// In nr-gnb.c
|
||||
extern void init_gNB();
|
||||
|
||||
@@ -211,12 +211,6 @@ void nrue_set_ru_params(configmodule_interface_t *cfg)
|
||||
if (RUParamList.numelt <= 0) {
|
||||
nrue_ru_count = 1;
|
||||
nrue_rus = calloc_or_fail(nrue_ru_count, sizeof(nrUE_RU_params_t));
|
||||
AssertFatal(get_nrUE_params()->nb_antennas_tx <= NB_ANTENNAS_TX,
|
||||
"Config file has %d TX antennas set, but the compile time max value in NB_ANTENNAS_TX\n",
|
||||
get_nrUE_params()->nb_antennas_tx);
|
||||
AssertFatal(get_nrUE_params()->nb_antennas_rx <= NB_ANTENNAS_RX,
|
||||
"Config file has %d RX antennas set, but the compile time max value in NB_ANTENNAS_RX\n",
|
||||
get_nrUE_params()->nb_antennas_tx);
|
||||
nrue_rus[0] = (nrUE_RU_params_t){.nb_tx = get_nrUE_params()->nb_antennas_tx,
|
||||
.nb_rx = get_nrUE_params()->nb_antennas_rx,
|
||||
.att_tx = get_nrUE_params()->tx_gain,
|
||||
|
||||
@@ -177,8 +177,6 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id)
|
||||
ue->dci_thres = 0;
|
||||
ue->target_Nid_cell = -1;
|
||||
|
||||
ue->nrUE_config.ntn_config.params_changed = false;
|
||||
|
||||
// initialize all signal buffers
|
||||
init_nr_ue_signal(ue, nb_connected_gNB);
|
||||
|
||||
|
||||
@@ -765,29 +765,23 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
} // Antenna loop
|
||||
}
|
||||
|
||||
int nr_srs_channel_estimation(int ant,
|
||||
int p_index,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t *srs_generated_signal,
|
||||
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
uint32_t *signal_power,
|
||||
uint32_t *noise_power,
|
||||
int16_t *noise_power_per_rb)
|
||||
int nr_srs_ls_channel_estimation(int ant,
|
||||
int p_index,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t *srs_generated_signal,
|
||||
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
|
||||
delay_t *delay)
|
||||
{
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
const uint64_t first_subcarrier = (first_carrier_offset - (ofdm_symbol_size >> 1)) + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
|
||||
const uint8_t N_ap = 1 << srs_pdu->num_ant_ports;
|
||||
const uint8_t K_TC = 2 << srs_pdu->comb_size;
|
||||
@@ -797,40 +791,20 @@ int nr_srs_channel_estimation(int ant,
|
||||
if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) {
|
||||
fd_cdm = 2;
|
||||
}
|
||||
uint16_t subcarrier;
|
||||
|
||||
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS];
|
||||
c16_t srs_estimated_channel_freq_avg[ofdm_symbol_size];
|
||||
memset(srs_ls_estimated_channel, 0, ofdm_symbol_size * N_symb_SRS * sizeof(c16_t));
|
||||
memset(srs_estimated_channel_freq_avg, 0, ofdm_symbol_size * sizeof(c16_t));
|
||||
|
||||
for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++) {
|
||||
uint16_t srs_symbol_offset = srs_symb * ofdm_symbol_size;
|
||||
|
||||
// Additional 4 in the array size is needed to maintain 16 byte memory alignment required for AVX2 instructions in channel
|
||||
// interpolation
|
||||
c16_t srs_est[ofdm_symbol_size + 4] __attribute__((aligned(32)));
|
||||
memset(srs_est, 0, (ofdm_symbol_size + 4) * sizeof(c16_t));
|
||||
|
||||
// Estimate 16 byte memory alignment offset for the first SRS subcarrier to use AVX2 instructions in channel interpolation
|
||||
uint8_t mem_offset = (16 - (((intptr_t)&srs_est[first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb]]) & 0xF))
|
||||
>> 2; // >> 2 <=> /sizeof(int32_t)
|
||||
|
||||
c16_t ls_estimated = {0};
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
|
||||
LOG_I(NR_PHY, "============================== SRS symbol index %d ===========================\n", srs_symb);
|
||||
#endif
|
||||
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb];
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
|
||||
uint16_t subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
|
||||
c16_t *srs_estimated_channel16 = &srs_est[subcarrier_abs];
|
||||
uint16_t subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb], 0, ofdm_symbol_size);
|
||||
|
||||
c16_t ls_estimated = {0};
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
if (k % fd_cdm == 0) {
|
||||
ls_estimated = (c16_t){0, 0};
|
||||
@@ -845,14 +819,13 @@ int nr_srs_channel_estimation(int ant,
|
||||
ls_estimated = c16maddConjShift(generated_srs, received_srs, ls_estimated, nr_srs_info->srs_generated_signal_bits);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier_cdm += K_TC;
|
||||
if (subcarrier_cdm >= ofdm_symbol_size) {
|
||||
subcarrier_cdm = subcarrier_cdm - ofdm_symbol_size;
|
||||
}
|
||||
subcarrier_cdm = CIRCULAR_INC(subcarrier_cdm, K_TC, ofdm_symbol_size);
|
||||
}
|
||||
}
|
||||
|
||||
srs_ls_estimated_channel[srs_symbol_offset + subcarrier] = ls_estimated;
|
||||
for (int ktc = 0; ktc < K_TC && srs_symbol_offset + subcarrier + ktc < ofdm_symbol_size * N_symb_SRS; ktc++) {
|
||||
srs_ls_estimated_channel[srs_symbol_offset + subcarrier + ktc] = ls_estimated;
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
int subcarrier_log = subcarrier - subcarrier_offset;
|
||||
@@ -874,6 +847,140 @@ int nr_srs_channel_estimation(int ant,
|
||||
ls_estimated.i);
|
||||
#endif
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier = CIRCULAR_INC(subcarrier, K_TC, ofdm_symbol_size);
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
// Delay estimation
|
||||
if (srs_symb == 0) {
|
||||
c16_t ch_estimates_time[ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
nr_est_delay(ofdm_symbol_size, srs_ls_estimated_channel, ch_estimates_time, delay);
|
||||
}
|
||||
} // for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nr_srs_noise_power_estimation(uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
uint32_t signal_power,
|
||||
const c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
|
||||
uint32_t *noise_power,
|
||||
int16_t *noise_power_per_rb)
|
||||
{
|
||||
const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index);
|
||||
int tot_subcarriers = m_SRS_b * NR_NB_SC_PER_RB;
|
||||
|
||||
uint16_t subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[0][0], 0, ofdm_symbol_size);
|
||||
|
||||
if (subcarrier + tot_subcarriers < ofdm_symbol_size) {
|
||||
*noise_power = signal_energy_nodc(&srs_received_noise[subcarrier], tot_subcarriers) / tot_subcarriers;
|
||||
} else {
|
||||
int size1 = ofdm_symbol_size - subcarrier;
|
||||
int size2 = tot_subcarriers - size1;
|
||||
uint64_t noise_power_p1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
|
||||
uint64_t noise_power_p2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
|
||||
*noise_power = (noise_power_p1 + noise_power_p2) / tot_subcarriers;
|
||||
}
|
||||
|
||||
// Compute SNR per RB on symbol 0
|
||||
subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[0][0], 0, ofdm_symbol_size);
|
||||
for (int rb = 0; rb < m_SRS_b; rb++) {
|
||||
if (subcarrier + NR_NB_SC_PER_RB < ofdm_symbol_size) {
|
||||
noise_power_per_rb[rb] += signal_energy_nodc(&srs_received_noise[subcarrier], NR_NB_SC_PER_RB);
|
||||
} else {
|
||||
int size1 = ofdm_symbol_size - subcarrier;
|
||||
int size2 = NR_NB_SC_PER_RB - size1;
|
||||
uint32_t noise_power_per_rb1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
|
||||
uint32_t noise_power_per_rb2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
|
||||
noise_power_per_rb[rb] += (noise_power_per_rb1 + noise_power_per_rb2) / NR_NB_SC_PER_RB;
|
||||
}
|
||||
noise_power_per_rb[rb] = max(noise_power_per_rb[rb], 1);
|
||||
subcarrier = CIRCULAR_INC(subcarrier, NR_NB_SC_PER_RB, ofdm_symbol_size);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,
|
||||
"[RB %3i] noise_power_per_rb = %i, SNR_per_rb = %i dB\n",
|
||||
rb,
|
||||
noise_power_per_rb[rb],
|
||||
dB_fixed(signal_power) - dB_fixed(noise_power_per_rb[rb]));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
int32_t signal_power_dB = dB_fixed(signal_power);
|
||||
int32_t noise_power_dB = dB_fixed(*noise_power);
|
||||
LOG_I(NR_PHY,
|
||||
"signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n",
|
||||
signal_power_dB,
|
||||
noise_power_dB,
|
||||
signal_power_dB - noise_power_dB);
|
||||
#endif
|
||||
}
|
||||
|
||||
int nr_srs_channel_interpolation(int ant,
|
||||
int p_index,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
|
||||
int est_delay,
|
||||
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
uint32_t *signal_power,
|
||||
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE])
|
||||
{
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
const uint64_t first_subcarrier = (first_carrier_offset - (ofdm_symbol_size >> 1)) + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
const uint8_t K_TC = 2 << srs_pdu->comb_size;
|
||||
const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index);
|
||||
const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB / K_TC;
|
||||
|
||||
c16_t srs_estimated_channel_freq_avg[ofdm_symbol_size];
|
||||
memset(srs_estimated_channel_freq_avg, 0, ofdm_symbol_size * sizeof(c16_t));
|
||||
|
||||
for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++) {
|
||||
uint16_t srs_symbol_offset = srs_symb * ofdm_symbol_size;
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
|
||||
LOG_I(NR_PHY, "============================== SRS symbol index %d ===========================\n", srs_symb);
|
||||
#endif
|
||||
|
||||
// Additional 4 in the array size is needed to maintain 16 byte memory alignment required for AVX2 instructions in channel
|
||||
// interpolation
|
||||
c16_t srs_est[ofdm_symbol_size + 4] __attribute__((aligned(32)));
|
||||
memset(srs_est, 0, (ofdm_symbol_size + 4) * sizeof(c16_t));
|
||||
|
||||
// Estimate 16 byte memory alignment offset for the first SRS subcarrier to use AVX2 instructions in channel interpolation
|
||||
uint8_t mem_offset =
|
||||
(16 - (((intptr_t)&srs_est[first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb]]) & 0xF)) / sizeof(c16_t);
|
||||
|
||||
uint16_t subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
|
||||
c16_t *srs_estimated_channel16 = &srs_est[subcarrier_abs];
|
||||
|
||||
uint16_t subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb], 0, ofdm_symbol_size);
|
||||
|
||||
int delay_idx = get_delay_idx(est_delay, MAX_DELAY_COMP);
|
||||
const c16_t *srs_delay_table = delay_table[delay_idx];
|
||||
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
|
||||
// Apply delay
|
||||
c16_t ls_estimated = c16mulShift(srs_ls_estimated_channel[srs_symbol_offset + subcarrier], srs_delay_table[subcarrier], 8);
|
||||
|
||||
// Channel interpolation
|
||||
if (srs_pdu->comb_size == 0) {
|
||||
if (k == 0) { // First subcarrier case
|
||||
@@ -905,15 +1012,23 @@ int nr_srs_channel_estimation(int ant,
|
||||
}
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier += K_TC;
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
|
||||
subcarrier = CIRCULAR_INC(subcarrier, K_TC, ofdm_symbol_size);
|
||||
subcarrier_abs += K_TC;
|
||||
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
// Revert delay
|
||||
int inv_delay_idx = get_delay_idx(-est_delay, MAX_DELAY_COMP);
|
||||
const c16_t *srs_inv_delay_table = delay_table[inv_delay_idx];
|
||||
subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
|
||||
subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][0], 0, ofdm_symbol_size);
|
||||
|
||||
for (int k = 0; k < K_TC * M_sc_b_SRS; k++) {
|
||||
srs_est[subcarrier_abs] = c16mulShift(srs_est[subcarrier_abs], srs_inv_delay_table[subcarrier], 8);
|
||||
// Subcarrier increment
|
||||
subcarrier = CIRCULAR_INC(subcarrier, 1, ofdm_symbol_size);
|
||||
subcarrier_abs++;
|
||||
}
|
||||
|
||||
memcpy(&srs_estimated_channel_freq[srs_symbol_offset], &srs_est[mem_offset], ofdm_symbol_size * sizeof(c16_t));
|
||||
|
||||
// Average srs channel estimates over multiple symbols
|
||||
@@ -924,11 +1039,7 @@ int nr_srs_channel_estimation(int ant,
|
||||
ofdm_symbol_size);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb];
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
|
||||
subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb], 0, ofdm_symbol_size);
|
||||
subcarrier_abs = first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
|
||||
|
||||
for (int k = 0; k < K_TC * M_sc_b_SRS; k++) {
|
||||
@@ -956,10 +1067,7 @@ int nr_srs_channel_estimation(int ant,
|
||||
srs_received_noise[srs_symbol_offset + subcarrier].i);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier++;
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
subcarrier = CIRCULAR_INC(subcarrier, 1, ofdm_symbol_size);
|
||||
subcarrier_abs++;
|
||||
}
|
||||
#endif
|
||||
@@ -996,61 +1104,5 @@ int nr_srs_channel_estimation(int ant,
|
||||
return -1;
|
||||
}
|
||||
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
|
||||
if (p_index == 0) {
|
||||
if (subcarrier + tot_subcarriers < ofdm_symbol_size) {
|
||||
*noise_power = signal_energy_nodc(&srs_received_noise[subcarrier], tot_subcarriers) / tot_subcarriers;
|
||||
} else {
|
||||
int size1 = ofdm_symbol_size - subcarrier;
|
||||
int size2 = tot_subcarriers - size1;
|
||||
uint64_t noise_power_p1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
|
||||
uint64_t noise_power_p2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
|
||||
*noise_power = (noise_power_p1 + noise_power_p2) / tot_subcarriers;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute SNR per RB for port 0 and symbol 0
|
||||
if (p_index == 0) {
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
for (int rb = 0; rb < m_SRS_b; rb++) {
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
if (subcarrier + NR_NB_SC_PER_RB < ofdm_symbol_size) {
|
||||
noise_power_per_rb[rb] += signal_energy_nodc(&srs_received_noise[subcarrier], NR_NB_SC_PER_RB);
|
||||
} else {
|
||||
int size1 = ofdm_symbol_size - subcarrier;
|
||||
int size2 = NR_NB_SC_PER_RB - size1;
|
||||
uint32_t noise_power_per_rb1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
|
||||
uint32_t noise_power_per_rb2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
|
||||
noise_power_per_rb[rb] += (noise_power_per_rb1 + noise_power_per_rb2) / NR_NB_SC_PER_RB;
|
||||
}
|
||||
noise_power_per_rb[rb] = max(noise_power_per_rb[rb], 1);
|
||||
subcarrier += NR_NB_SC_PER_RB;
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,
|
||||
"[RB %3i] noise_power_per_rb = %i, SNR_per_rb = %i dB\n",
|
||||
rb,
|
||||
noise_power_per_rb[rb],
|
||||
dB_fixed(*signal_power) - dB_fixed(noise_power_per_rb[rb]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
int32_t signal_power_dB = dB_fixed(*signal_power);
|
||||
int32_t noise_power_dB = dB_fixed(*noise_power);
|
||||
LOG_I(NR_PHY,
|
||||
"signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n",
|
||||
signal_power_dB,
|
||||
noise_power_dB,
|
||||
signal_power_dB - noise_power_dB);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -75,22 +75,43 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pusch);
|
||||
|
||||
int nr_srs_channel_estimation(int ant,
|
||||
int p_index,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t *srs_generated_signal,
|
||||
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
uint32_t *signal_power,
|
||||
uint32_t *noise_power,
|
||||
int16_t *noise_power_per_rb);
|
||||
int nr_srs_ls_channel_estimation(int ant,
|
||||
int p_index,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t *srs_generated_signal,
|
||||
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
|
||||
delay_t *delay);
|
||||
|
||||
int nr_srs_channel_interpolation(int ant,
|
||||
int p_index,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
|
||||
int est_delay,
|
||||
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
|
||||
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
uint32_t *signal_power,
|
||||
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE]);
|
||||
|
||||
void nr_srs_noise_power_estimation(uint16_t ofdm_symbol_size,
|
||||
uint16_t first_carrier_offset,
|
||||
uint8_t N_symb_SRS,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
uint32_t signal_power,
|
||||
const c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
|
||||
uint32_t *noise_power,
|
||||
int16_t *noise_power_per_rb);
|
||||
|
||||
void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *rxdataF_comp,
|
||||
|
||||
@@ -61,38 +61,9 @@
|
||||
|
||||
#define SSS_METRIC_FLOOR_NR (30000)
|
||||
|
||||
/************** VARIABLES *****************************************/
|
||||
|
||||
#define PHASE_HYPOTHESIS_NUMBER (16)
|
||||
#define INDEX_NO_PHASE_DIFFERENCE (3) /* this is for no phase shift case */
|
||||
|
||||
/************** FUNCTION ******************************************/
|
||||
|
||||
static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = {
|
||||
// {pi/3 ---- pi/3, -pi/3 ---- pi/3}
|
||||
{16384, -28377},
|
||||
{20173, -25821},
|
||||
{23571, -22762},
|
||||
{26509, -19260},
|
||||
{28932, -15383},
|
||||
{30791, -11207},
|
||||
{32051, -6813},
|
||||
{32687, -2286},
|
||||
{32687, 2286},
|
||||
{32051, 6813},
|
||||
{30791, 11207},
|
||||
{28932, 15383},
|
||||
{26509, 19260},
|
||||
{23571, 22762},
|
||||
{20173, 25821},
|
||||
{16384, 28377}};
|
||||
|
||||
void init_context_sss_nr(int amp);
|
||||
void free_context_sss_nr(void);
|
||||
|
||||
void insert_sss_nr(int16_t *sss_time,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nid2,
|
||||
int target_Nid_cell,
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
void init_prach_list(prach_list_t *l)
|
||||
{
|
||||
pthread_mutex_init(&l->prach_list_mutex, NULL);
|
||||
for (prach_item_t *p = l->list; p < l->list + NUMBER_OF_NR_PRACH_MAX; p++)
|
||||
*p = (prach_item_t){.frame = -1, .slot = -1};
|
||||
memset(l->list, 0, sizeof(l->list));
|
||||
}
|
||||
|
||||
void free_nr_prach_entry(prach_list_t *l, prach_item_t *p)
|
||||
@@ -48,17 +47,18 @@ void free_nr_prach_entry(prach_list_t *l, prach_item_t *p)
|
||||
pthread_mutex_lock(&l->prach_list_mutex);
|
||||
if (p->frame == -1)
|
||||
LOG_E(NR_PHY_RACH, "Freeing a not allocated prach entry\n");
|
||||
*p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1};
|
||||
*p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1, .nb_rx = p->nb_rx, .prach_buf = (void *)(p + 1)};
|
||||
pthread_mutex_unlock(&l->prach_list_mutex);
|
||||
}
|
||||
|
||||
prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t type)
|
||||
prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, int nb_rx, find_type_t type)
|
||||
{
|
||||
pthread_mutex_lock(&l->prach_list_mutex);
|
||||
prach_item_t *p = l->list;
|
||||
prach_item_t *end = p + NUMBER_OF_NR_PRACH_MAX;
|
||||
AssertFatal(nb_rx, "Error! Number of antennas set to 0.\n");
|
||||
prach_item_t **p = l->list;
|
||||
prach_item_t **end = p + NUMBER_OF_NR_PRACH_MAX;
|
||||
for (; p < end; p++)
|
||||
if (p->frame == frame && (p->slot + p->num_slots - 1) == slot)
|
||||
if ((*p) && (*p)->frame == frame && ((*p)->slot + (*p)->num_slots - 1) == slot)
|
||||
break;
|
||||
if (p == end) {
|
||||
if (type == SEARCH_EXIST) {
|
||||
@@ -66,7 +66,7 @@ prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t ty
|
||||
return NULL;
|
||||
}
|
||||
for (p = l->list; p < end; p++)
|
||||
if (p->frame == -1 && p->slot == -1)
|
||||
if (!(*p) || ((*p)->frame == -1 && (*p)->slot == -1))
|
||||
break;
|
||||
}
|
||||
if (p == end) {
|
||||
@@ -74,14 +74,24 @@ prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t ty
|
||||
return NULL;
|
||||
}
|
||||
// mark it used, it will be filled later
|
||||
p->frame = frame;
|
||||
if (*p && (*p)->nb_rx != nb_rx) {
|
||||
LOG_W(PHY, "rach procedure nb_rx ant changed from %d to %d\n", (*p)->nb_rx, nb_rx);
|
||||
free(*p);
|
||||
*p = NULL;
|
||||
}
|
||||
if (!(*p)) {
|
||||
*p = calloc(1, sizeof(prach_item_t) + sizeof(c16_t) * nb_rx * NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX * NR_PRACH_SEQ_LEN_L);
|
||||
(*p)->prach_buf = (void *)((*p) + 1);
|
||||
}
|
||||
(*p)->nb_rx = nb_rx;
|
||||
(*p)->frame = frame;
|
||||
pthread_mutex_unlock(&l->prach_list_mutex);
|
||||
return p;
|
||||
return (*p);
|
||||
}
|
||||
|
||||
prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
{
|
||||
prach_item_t *prach = find_nr_prach(&gNB->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
prach_item_t *prach = find_nr_prach(&gNB->prach_list, SFN, Slot, gNB->frame_parms.nb_antennas_rx, SEARCH_EXIST_OR_FREE);
|
||||
if (!prach) {
|
||||
LOG_W(PHY, "no free space for a new detected rach, discarding\n");
|
||||
return NULL;
|
||||
@@ -380,7 +390,7 @@ static void rx_nr_prach_ru_internal(prach_item_t *p,
|
||||
rxsigF_tmp[j] = c16add(rxsigF_tmp[j], tmp[k2]);
|
||||
}
|
||||
}
|
||||
memcpy(p->rxsigF[prachOccasion][aa], rxsigF_tmp, sizeof(rxsigF_tmp));
|
||||
memcpy(p->prach_buf[aa][prachOccasion], rxsigF_tmp, sizeof(rxsigF_tmp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +454,7 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion)
|
||||
int32_t prach_ifft[dft_sz] __attribute__((aligned(32)));
|
||||
for (int preamble_index = 0; preamble_index < 64; preamble_index++) {
|
||||
if (LOG_DEBUGFLAG(DEBUG_PRACH)) {
|
||||
int en = dB_fixed(signal_energy((int32_t *)in->rxsigF[occasion][0], N_ZC == 839 ? 840 : 140));
|
||||
int en = dB_fixed(signal_energy((int32_t *)in->prach_buf[0][occasion], N_ZC == 839 ? 840 : 140));
|
||||
if (en > 60)
|
||||
LOG_D(PHY, "frame %d, slot %d : Trying preamble %d \n", in->frame, in->slot, preamble_index);
|
||||
}
|
||||
@@ -520,7 +530,7 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion)
|
||||
|
||||
// Compute DFT of RX signal (conjugate in->rxsigF[occasion], results in conjugate output) for each new rootSequenceIndex
|
||||
if (LOG_DEBUGFLAG(DEBUG_PRACH)) {
|
||||
int en = dB_fixed(signal_energy((int32_t *)in->rxsigF[occasion][0], 840));
|
||||
int en = dB_fixed(signal_energy((int32_t *)in->prach_buf[0][occasion], 840));
|
||||
if (en>60)
|
||||
LOG_D(PHY,
|
||||
"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
|
||||
@@ -549,14 +559,14 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion)
|
||||
|
||||
memset(prach_ifft, 0, sizeof(prach_ifft));
|
||||
if (LOG_DUMPFLAG(DEBUG_PRACH)) {
|
||||
LOG_M("prach_rxF0.m", "prach_rxF0", in->rxsigF[occasion][0], N_ZC, 1, 1);
|
||||
LOG_M("prach_rxF1.m", "prach_rxF1", in->rxsigF[occasion][1], 6144, 1, 1);
|
||||
LOG_M("prach_rxF0.m", "prach_rxF0", in->prach_buf[0][occasion], N_ZC, 1, 1);
|
||||
LOG_M("prach_rxF1.m", "prach_rxF1", in->prach_buf[1][occasion], 6144, 1, 1);
|
||||
}
|
||||
c16_t prachF[dft_sz] __attribute__((aligned(32)));
|
||||
for (int aa = 0; aa < nb_rx; aa++) {
|
||||
// Do componentwise product with Xu* on each antenna
|
||||
for (int offset = 0; offset < N_ZC; offset++) {
|
||||
prachF[offset] = c16MulConjShift(Xu[offset], in->rxsigF[occasion][aa][offset], 15);
|
||||
prachF[offset] = c16MulConjShift(Xu[offset], in->prach_buf[aa][occasion][offset], 15);
|
||||
}
|
||||
memset(prachF + N_ZC, 0, sizeof(*prachF) * (dft_sz - N_ZC));
|
||||
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
|
||||
|
||||
@@ -23,11 +23,7 @@
|
||||
|
||||
//#define NR_SSS_DEBUG
|
||||
|
||||
int nr_generate_sss( c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
nfapi_nr_config_request_scf_t* config,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
int nr_generate_sss(c16_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, int Nid, NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
int16_t x0[NR_SSS_LENGTH];
|
||||
int16_t x1[NR_SSS_LENGTH];
|
||||
@@ -35,7 +31,6 @@ int nr_generate_sss( c16_t *txdataF,
|
||||
const int x1_initial[7] = { 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/// Sequence generation
|
||||
int Nid = config->cell_config.phy_cell_id.value;
|
||||
int Nid2 = Nid % 3;
|
||||
int Nid1 = (Nid - Nid2)/3;
|
||||
|
||||
@@ -59,13 +54,11 @@ int nr_generate_sss( c16_t *txdataF,
|
||||
/// Resource mapping
|
||||
|
||||
// SSS occupies a predefined position (subcarriers 56-182, symbol 2) within the SSB block starting from
|
||||
int k = frame_parms->ssb_start_subcarrier + 56;
|
||||
int l = ssb_start_symbol + 2;
|
||||
c16_t *tx = txdataF + (ssb_start_symbol + 2) * frame_parms->ofdm_symbol_size + frame_parms->ssb_start_subcarrier + 56;
|
||||
|
||||
for (int i = 0; i < NR_SSS_LENGTH; i++) {
|
||||
int16_t d_sss = (1 - 2*x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2*x1[(i + m1) % NR_SSS_LENGTH] ) * 23170;
|
||||
((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15;
|
||||
k++;
|
||||
*tx++ = (c16_t){.r = (amp * d_sss) >> 15};
|
||||
}
|
||||
#ifdef NR_SSS_DEBUG
|
||||
// write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
@@ -60,11 +60,7 @@ int nr_generate_pss(c16_t *txdataF,
|
||||
@param
|
||||
@returns 0 on success
|
||||
*/
|
||||
int nr_generate_sss(c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
int nr_generate_sss(c16_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, int nid, NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/*!
|
||||
\fn void nr_generate_pbch_dmrs
|
||||
@@ -206,7 +202,7 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *, int occasion);
|
||||
|
||||
void rx_nr_prach_ru(prach_item_t *, int32_t **, NR_DL_FRAME_PARMS *frame_parms, int N_TA_offset);
|
||||
|
||||
prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, find_type_t type);
|
||||
prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, int nb_rx, find_type_t type);
|
||||
void nr_fill_pucch(PHY_VARS_gNB *gNB,
|
||||
int frame,
|
||||
int slot,
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
|
||||
void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu)
|
||||
{
|
||||
bool found = false;
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
|
||||
if (pucch->active == false) {
|
||||
@@ -86,11 +85,10 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t
|
||||
pucch->pucch_pdu.bit_len_harq,
|
||||
pucch->pucch_pdu.sr_flag,
|
||||
pucch->pucch_pdu.bit_len_csi_part1);
|
||||
found = true;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
AssertFatal(found, "PUCCH list is full\n");
|
||||
LOG_W(PHY, "PUCCH list is full\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -147,37 +147,25 @@ uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||
int symbol_offset,
|
||||
int ssb_start_subcarrier)
|
||||
{
|
||||
int k_start = 56;
|
||||
int k_end = 183;
|
||||
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
|
||||
|
||||
uint8_t l_sss = (symbol_offset + 2) % fp->symbols_per_slot;
|
||||
|
||||
const int k_start = 56;
|
||||
const int k_end = 183;
|
||||
const unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
|
||||
const uint8_t l_sss = (symbol_offset + 2) % fp->symbols_per_slot;
|
||||
uint32_t rsrp = 0;
|
||||
|
||||
LOG_D(PHY, "In %s: l_sss %d ssb_offset %d\n", __FUNCTION__, l_sss, ssb_offset);
|
||||
int nb_re = 0;
|
||||
|
||||
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||
int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][l_sss * fp->ofdm_symbol_size];
|
||||
|
||||
const c16_t *rxF_sss = &rxdataF[aarx][l_sss * fp->ofdm_symbol_size];
|
||||
for(int k = k_start; k < k_end; k++){
|
||||
int re = (ssb_offset + k) % fp->ofdm_symbol_size;
|
||||
|
||||
#ifdef DEBUG_MEAS_UE
|
||||
LOG_I(PHY, "In %s rxF_sss[%d] %d %d\n", __FUNCTION__, re, rxF_sss[re * 2], rxF_sss[re * 2 + 1]);
|
||||
#endif
|
||||
|
||||
rsrp += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1]));
|
||||
rsrp += squaredMod(rxF_sss[re]);
|
||||
nb_re++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rsrp /= nb_re;
|
||||
|
||||
LOG_D(PHY, "In %s: RSRP/nb_re: %d nb_re :%d\n", __FUNCTION__, rsrp, nb_re);
|
||||
|
||||
return rsrp;
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,6 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *sl_fp = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
int16_t *d;
|
||||
uint16_t Nid1 = 0;
|
||||
uint8_t phase;
|
||||
c16_t *rxF_ext;
|
||||
|
||||
for (int aarx = 0; aarx < sl_fp->nb_antennas_rx; aarx++) {
|
||||
@@ -260,15 +259,16 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue,
|
||||
c16_t *sss = &sss_ext[0][0][0];
|
||||
|
||||
for (uint16_t id1 = 0; id1 < SL_NR_NUM_IDs_IN_SSS; id1++) { // all possible SSS Nid1 values
|
||||
for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
|
||||
for (int phase = -15; phase < 16; phase += 2) { // phase offset between PSS and SSS
|
||||
|
||||
int32_t metric = 0, metric_re = 0;
|
||||
|
||||
const c64_t rot = (c64_t){round(cos(M_PI / 3 / 15 * (phase)) * 32767), round(sin(M_PI / 3 / 15 * (phase)) * 32767)};
|
||||
d = (int16_t *)&ue->SL_UE_PHY_PARAMS.init_params.sl_sss_for_sync[Nid2 * SL_NR_NUM_IDs_IN_SSS + id1];
|
||||
|
||||
// This is the inner product using one particular value of each unknown parameter
|
||||
for (int i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) {
|
||||
metric_re += d[i] * (((int64_t)phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15);
|
||||
// metric is only real part because sss is a pure real signal (imaginary is 0)
|
||||
metric_re += d[i] * ((rot.r * sss[i].r - rot.i * sss[i].i) >> 15);
|
||||
}
|
||||
|
||||
metric = metric_re;
|
||||
|
||||
@@ -49,24 +49,12 @@
|
||||
|
||||
//#define DBG_PSS_NR
|
||||
static time_stats_t generic_time[TIME_LAST];
|
||||
int pss_search_time_nr(const c16_t **rxdata,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
|
||||
bool fo_flag,
|
||||
int is,
|
||||
int target_Nid_cell,
|
||||
int *nid2,
|
||||
int *f_off,
|
||||
int *pssPeak,
|
||||
int *pssAvg,
|
||||
int search_start,
|
||||
int search_length);
|
||||
|
||||
static int16_t primary_synchro_nr2[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0};
|
||||
static int16_t d_pss[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0};
|
||||
static c16_t primary_synchro[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0};
|
||||
int16_t *get_primary_synchro_nr2(const int nid2)
|
||||
{
|
||||
return primary_synchro_nr2[nid2];
|
||||
return d_pss[nid2];
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -86,12 +74,9 @@ int16_t *get_primary_synchro_nr2(const int nid2)
|
||||
void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
{
|
||||
AssertFatal(fp->ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",fp->ofdm_symbol_size);
|
||||
AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2);
|
||||
int16_t d_pss[LENGTH_PSS_NR];
|
||||
AssertFatal(N_ID_2 >= 0 && N_ID_2 <= 2, "Illegal N_ID_2 %d\n", N_ID_2);
|
||||
int16_t x[LENGTH_PSS_NR];
|
||||
|
||||
int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
|
||||
|
||||
#define INITIAL_PSS_NR (7)
|
||||
const int16_t x_initial[INITIAL_PSS_NR] = {0, 1, 1, 0, 1, 1, 1};
|
||||
assert(N_ID_2 < NUMBER_PSS_SEQUENCE);
|
||||
@@ -99,16 +84,15 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
|
||||
for (int i = 0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++)
|
||||
x[i + INITIAL_PSS_NR] = (x[i + 4] + x[i]) % (2);
|
||||
|
||||
int16_t *pss = d_pss[N_ID_2];
|
||||
for (int n=0; n < LENGTH_PSS_NR; n++) {
|
||||
const int m = (n + 43 * N_ID_2) % (LENGTH_PSS_NR);
|
||||
d_pss[n] = 1 - 2*x[m];
|
||||
pss[n] = 1 - 2 * x[m];
|
||||
}
|
||||
|
||||
/* PSS is directly mapped to subcarrier without modulation 38.211 */
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
primary_synchro[N_ID_2][i].r = (d_pss[i] * SHRT_MAX) >> SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
|
||||
primary_synchro2[i] = d_pss[i];
|
||||
primary_synchro[N_ID_2][i].r = (pss[i] * SHRT_MAX) >> SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
|
||||
}
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
@@ -150,12 +134,13 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssbFirstSCS, c16_t pssTime[fp->ofdm_symbol_size])
|
||||
{
|
||||
unsigned int subcarrier_start = get_softmodem_params()->sl_mode == 0 ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL;
|
||||
unsigned int k = fp->first_carrier_offset + ssbFirstSCS + subcarrier_start;
|
||||
if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size;
|
||||
c16_t synchroF_tmp[fp->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
memset(synchroF_tmp, 0, sizeof(synchroF_tmp));
|
||||
unsigned int k = fp->first_carrier_offset + ssbFirstSCS + subcarrier_start;
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
synchroF_tmp[k % fp->ofdm_symbol_size] = primary_synchro[N_ID_2][i];
|
||||
if (k >= fp->ofdm_symbol_size)
|
||||
k -= fp->ofdm_symbol_size;
|
||||
synchroF_tmp[k] = primary_synchro[N_ID_2][i];
|
||||
k++;
|
||||
}
|
||||
|
||||
@@ -182,54 +167,6 @@ void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssb
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* it allows checking that process of idft on a signal and then dft gives same signal with limited errors */
|
||||
|
||||
if ((N_ID_2 == 0) && (length == 256)) {
|
||||
|
||||
LOG_M("pss_f00.m","pss_f00",synchro_tmp,length,1,1);
|
||||
|
||||
|
||||
bzero(synchroF_tmp, size);
|
||||
|
||||
|
||||
|
||||
/* get pss in the time domain by applying an inverse FFT */
|
||||
dft((int16_t)get_dft(length),
|
||||
synchro_tmp, /* complex input */
|
||||
synchroF_tmp, /* complex output */
|
||||
1); /* scaling factor */
|
||||
|
||||
if ((N_ID_2 == 0) && (length == 256)) {
|
||||
LOG_M("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1);
|
||||
}
|
||||
|
||||
/* check Pss */
|
||||
k = length - (LENGTH_PSS_NR/2);
|
||||
|
||||
#define LIMIT_ERROR_FFT (10)
|
||||
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
if (abs(synchroF_tmp[2*k] - primary_synchro[i].r) > LIMIT_ERROR_FFT) {
|
||||
printf("Pss Error[%d] Compute %d Reference %d \n", k, synchroF_tmp[2*k], primary_synchro[i].r);
|
||||
}
|
||||
|
||||
if (abs(synchroF_tmp[2*k+1] - primary_synchro[i].i) > LIMIT_ERROR_FFT) {
|
||||
printf("Pss Error[%d] Compute %d Reference %d\n", (2*k+1), synchroF_tmp[2*k+1], primary_synchro[i].i);
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= length) {
|
||||
k-=length;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -391,50 +328,32 @@ int pss_synchro_nr(const c16_t **rxdata,
|
||||
int *pssAvg)
|
||||
{
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame,1,1);
|
||||
|
||||
LOG_M("rxdata0_rand.m", "rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1);
|
||||
LOG_M("rxdata0_des.m", "rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame, 1, 1);
|
||||
#endif
|
||||
|
||||
start_meas(&generic_time[TIME_PSS]);
|
||||
|
||||
int synchro_position =
|
||||
pss_search_time_nr(rxdata, frame_parms, pssTime, fo_flag, is, target_Nid_cell, nid2, f_off, pssPeak, pssAvg, -1, -1);
|
||||
stop_meas(&generic_time[TIME_PSS]);
|
||||
|
||||
#if TEST_SYNCHRO_TIMING_PSS
|
||||
|
||||
stop_meas(&generic_time[TIME_PSS]);
|
||||
|
||||
int duration_ms = generic_time[TIME_PSS].p_time/(cpuf*1000.0);
|
||||
|
||||
#ifndef NR_UNIT_TEST
|
||||
|
||||
LOG_D(PHY,"PSS execution duration %4d microseconds \n", duration_ms);
|
||||
|
||||
#endif
|
||||
|
||||
int duration_ms = generic_time[TIME_PSS].p_time / (cpuf * 1000.0);
|
||||
#ifndef NR_UNIT_TEST
|
||||
LOG_D(PHY, "PSS execution duration %4d microseconds \n", duration_ms);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
|
||||
if (rate_change != 1) {
|
||||
|
||||
if (rxdata[0] != NULL) {
|
||||
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
free(rxdata[aa]);
|
||||
}
|
||||
|
||||
free(rxdata);
|
||||
}
|
||||
|
||||
restore_frame_context_pss_nr(frame_parms, rate_change);
|
||||
restore_frame_context_pss_nr(frame_parms, rate_change);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -504,11 +423,6 @@ int pss_search_time_nr(const c16_t **rxdata,
|
||||
int search_start,
|
||||
int search_length)
|
||||
{
|
||||
unsigned int n, ar, peak_position, pss_source;
|
||||
int64_t peak_value;
|
||||
int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
|
||||
double ffo_est = 0;
|
||||
|
||||
// Determine search window
|
||||
unsigned int start, length;
|
||||
if (search_start >= 0 && search_length > 0) {
|
||||
@@ -524,11 +438,7 @@ int pss_search_time_nr(const c16_t **rxdata,
|
||||
length = frame_parms->samples_per_frame;
|
||||
}
|
||||
|
||||
AssertFatal(length>0,"illegal length %d\n",length);
|
||||
peak_value = 0;
|
||||
peak_position = 0;
|
||||
pss_source = 0;
|
||||
|
||||
AssertFatal(length > 0, "illegal length %d\n", length);
|
||||
int maxval=0;
|
||||
int max_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
|
||||
for (int j = 0; j < max_size; j++)
|
||||
@@ -542,53 +452,55 @@ int pss_search_time_nr(const c16_t **rxdata,
|
||||
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
|
||||
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
|
||||
|
||||
uint16_t pss_index_start = 0;
|
||||
uint16_t pss_index_end = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
|
||||
int pss_index_start;
|
||||
int pss_index_end;
|
||||
if (target_Nid_cell != -1) {
|
||||
pss_index_start = GET_NID2(target_Nid_cell);
|
||||
pss_index_end = pss_index_start + 1;
|
||||
} else {
|
||||
pss_index_start = 0;
|
||||
pss_index_end = max_size;
|
||||
}
|
||||
|
||||
int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
|
||||
int64_t peak_value = 0;
|
||||
unsigned int peak_position = 0;
|
||||
unsigned int pss_source = 0;
|
||||
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) {
|
||||
for (n = start; n < start + length; n += 4) { //
|
||||
|
||||
int64_t pss_corr_ue=0;
|
||||
for (int n = start; n < start + length; n += 4) { //
|
||||
int64_t pss_corr_ue = 0;
|
||||
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n]
|
||||
* (ar=0..nb_ant_rx) and store the sum in temp[n]; */
|
||||
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
|
||||
|
||||
for (int ar = 0; ar < frame_parms->nb_antennas_rx; ar++) {
|
||||
/* perform correlation of rx data and pss sequence ie it is a dot product */
|
||||
const c32_t result = dot_product(pssTime[pss_index],
|
||||
&(rxdata[ar][n + is * frame_parms->samples_per_frame]),
|
||||
&rxdata[ar][n + is * frame_parms->samples_per_frame],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
shift);
|
||||
const c64_t r64 = {.r = result.r, .i = result.i};
|
||||
pss_corr_ue += squaredMod(r64);
|
||||
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
|
||||
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
|
||||
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
|
||||
//((short*)&synchro_out)[1] += ((int*) &result)[1]; /* imaginary part */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* calculate the absolute value of sync_corr[n] */
|
||||
avg[pss_index]+=pss_corr_ue;
|
||||
avg[pss_index] += pss_corr_ue;
|
||||
if (pss_corr_ue > peak_value) {
|
||||
peak_value = pss_corr_ue;
|
||||
peak_position = n;
|
||||
pss_source = pss_index;
|
||||
|
||||
|
||||
#ifdef DEBUG_PSS_NR
|
||||
printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[n]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
avg[pss_index] /= (length / 4);
|
||||
}
|
||||
|
||||
if (fo_flag){
|
||||
|
||||
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
|
||||
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012.
|
||||
double ffo_est = 0;
|
||||
if (fo_flag) {
|
||||
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
|
||||
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th
|
||||
// International Conference on Communications and Networking in China, 2012.
|
||||
|
||||
// Computing cross-correlation at peak on half the symbol size for first half of data
|
||||
c32_t r1 = dot_product(pssTime[pss_source],
|
||||
@@ -606,15 +518,11 @@ int pss_search_time_nr(const c16_t **rxdata,
|
||||
ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI;
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
printf("ffo %lf\n",ffo_est);
|
||||
printf("ffo %lf\n", ffo_est);
|
||||
#endif
|
||||
}
|
||||
|
||||
// computing absolute value of frequency offset
|
||||
*f_off = ffo_est*frame_parms->subcarrier_spacing;
|
||||
|
||||
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++)
|
||||
avg[pss_index] /= (length / 4);
|
||||
*f_off = ffo_est * frame_parms->subcarrier_spacing;
|
||||
|
||||
*nid2 = pss_source;
|
||||
*pssPeak = dB_fixed64(peak_value);
|
||||
@@ -631,22 +539,18 @@ int pss_search_time_nr(const c16_t **rxdata,
|
||||
ffo_est);
|
||||
|
||||
if ((search_start < 0 || search_length == 0) && peak_value < 5 * avg[pss_source])
|
||||
return(-1);
|
||||
|
||||
return (-1);
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
static int debug_cnt = 0;
|
||||
|
||||
if (debug_cnt == 0) {
|
||||
if (is)
|
||||
LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1);
|
||||
LOG_M("rxdata1.m", "rxd0", rxdata[frame_parms->samples_per_frame], length, 1, 1);
|
||||
else
|
||||
LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1);
|
||||
LOG_M("rxdata0.m", "rxd0", rxdata[0], length, 1, 1);
|
||||
} else {
|
||||
debug_cnt++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return peak_position;
|
||||
|
||||
@@ -109,71 +109,8 @@ void init_context_sss_nr(int amp)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : insert_sss_nr
|
||||
*
|
||||
* PARAMETERS : pointer to input buffer for which sss in inserted
|
||||
* amp amplitude applied to input
|
||||
* frame parameters for cell identity
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : Allow to generate a reference sss sequence according to cell identity
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
//#define DEBUG_SSS_NR
|
||||
//#define DEBUG_PLOT_SSS
|
||||
void insert_sss_nr(int16_t *sss_time,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
const unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
int Nid2 = GET_NID2(frame_parms->Nid_cell);
|
||||
int Nid1 = GET_NID1(frame_parms->Nid_cell);
|
||||
|
||||
/* call of IDFT should be done with ordered input as below
|
||||
*
|
||||
* n input samples
|
||||
* <------------------------------------------------>
|
||||
* 0 n
|
||||
* are written into input buffer for IFFT in this order
|
||||
* -------------------------------------------------
|
||||
* |xxxxxxx N/2 xxxxxxxx|
|
||||
* --------------------------------------------------
|
||||
* ^ ^ ^ ^ ^
|
||||
* | | | | |
|
||||
* n/2 end of n=0 start of n/2-1
|
||||
* sss sss
|
||||
*
|
||||
* Frequencies
|
||||
* positives negatives
|
||||
* 0 (+N/2)(-N/2)
|
||||
* |-----------------------><-------------------------|
|
||||
*
|
||||
* sample 0 is for continuous frequency which is not used here
|
||||
*/
|
||||
|
||||
unsigned int k = ofdm_symbol_size - ((LENGTH_SSS_NR/2)+1);
|
||||
c16_t synchroF_tmp[2048] __attribute__((aligned(32)));
|
||||
c16_t synchro_tmp[2048] __attribute__((aligned(32)));
|
||||
bzero(synchroF_tmp, sizeof(synchroF_tmp));
|
||||
|
||||
/* SSS is directly mapped to subcarrier */
|
||||
for (int i=0; i<LENGTH_SSS_NR; i++) {
|
||||
synchroF_tmp[k % ofdm_symbol_size].r = d_sss[Nid2][Nid1][i];
|
||||
k++;
|
||||
}
|
||||
|
||||
/* get sss in the frequency domain by applying an inverse FFT */
|
||||
idft(IDFT_2048,
|
||||
(int16_t *)synchroF_tmp, /* complex input */
|
||||
(int16_t *)synchro_tmp, /* complex output */
|
||||
1); /* scaling factor */
|
||||
|
||||
/* then get final sss in time */
|
||||
memcpy(sss_time, synchro_tmp, ofdm_symbol_size * sizeof(c16_t));
|
||||
}
|
||||
// #define DEBUG_SSS_NR
|
||||
// #define DEBUG_PLOT_SSS
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
@@ -187,7 +124,7 @@ void insert_sss_nr(int16_t *sss_time,
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
static void pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nid2,
|
||||
c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR],
|
||||
c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR])
|
||||
@@ -199,148 +136,60 @@ static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *pss_ext2 = pss_ext[aarx];
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
// This is H*(PSS) = R* \cdot PSS
|
||||
const int tmp_re = pss_ext2[i].r * pss[i];
|
||||
const int tmp_im = -pss_ext2[i].i * pss[i];
|
||||
|
||||
const int32_t amp = tmp_re * tmp_re + tmp_im * tmp_im;
|
||||
const c16_t tmp = (c16_t){pss_ext2[i].r * pss[i], -pss_ext2[i].i * pss[i]};
|
||||
const int32_t amp = squaredMod(tmp);
|
||||
const int shift = log2_approx(amp) / 2;
|
||||
// This is R(SSS) \cdot H*(PSS)
|
||||
const c16_t tmp = {(tmp_re * sss_ext2[i].r - tmp_im * sss_ext2[i].i) >> shift,
|
||||
(tmp_re * sss_ext2[i].i + tmp_im * sss_ext2[i].r) >> shift};
|
||||
// printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]);
|
||||
// printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2);
|
||||
// MRC on RX antennas
|
||||
if (aarx == 0) {
|
||||
sss_ext2[i].r = tmp.r;
|
||||
sss_ext2[i].i = tmp.i;
|
||||
} else {
|
||||
sss_ext2[i].r += tmp.r;
|
||||
sss_ext2[i].i += tmp.i;
|
||||
}
|
||||
const c16_t new_sss = c16mulShift(tmp, sss_ext2[i], shift);
|
||||
if (aarx == 0)
|
||||
sss_ext2[i] = new_sss;
|
||||
else
|
||||
sss_ext2[i] = c16add(sss_ext2[i], new_sss);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
LOG_M("pssrx.m","pssrx",pss,LENGTH_PSS_NR,1,1);
|
||||
LOG_M("pss_ext.m","pssext",pss_ext2,LENGTH_PSS_NR,1,1);
|
||||
LOG_M("psschest.m","pssch",chest,LENGTH_PSS_NR,1,1);
|
||||
#endif
|
||||
#if 0
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" sss ext 2 [%d] %d %d at address %p\n", i, sss_ext2[2*i], sss_ext2[2*i+1]);
|
||||
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i]);
|
||||
printf(" sss ext 3 [%d] %d %d at address %p\n", i, sss_ext3[2*i], sss_ext3[2*i+1]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// sss_ext now contains the compensated SSS
|
||||
return(0);
|
||||
// sss_ext[0] now contains the compensated SSS
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : do_pss_sss_extract
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : it allows extracting sss from samples buffer
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* NAME : pss_sss_extract_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : it allows extracting sss from samples buffer
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static int do_pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
static void pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR],
|
||||
c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR],
|
||||
uint8_t doPss,
|
||||
uint8_t doSss,
|
||||
int ssb_start_subcarrier,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
|
||||
{
|
||||
AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n");
|
||||
AssertFatal(frame_parms->nb_antennas_rx > 0, "nb antennas as sss_ext is not set to any value\n");
|
||||
const unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
const int pss_symbol = 0;
|
||||
const int sss_symbol =
|
||||
get_softmodem_params()->sl_mode == 0 ? (SSS_SYMBOL_NB - PSS_SYMBOL_NB) : (SSS0_SL_SYMBOL_NB - PSS0_SL_SYMBOL_NB);
|
||||
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
int pss_symbol = 0;
|
||||
int sss_symbol = get_softmodem_params()->sl_mode == 0 ?
|
||||
(SSS_SYMBOL_NB - PSS_SYMBOL_NB) :
|
||||
(SSS0_SL_SYMBOL_NB - PSS0_SL_SYMBOL_NB) ;
|
||||
unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
|
||||
c16_t *pss_rxF = rxdataF[aarx] + pss_symbol * ofdm_symbol_size;
|
||||
c16_t *sss_rxF = rxdataF[aarx] + sss_symbol * ofdm_symbol_size;
|
||||
|
||||
c16_t *pss_rxF_ext = pss_ext[aarx];
|
||||
c16_t *sss_rxF_ext = sss_ext[aarx];
|
||||
|
||||
unsigned int k = frame_parms->first_carrier_offset + ssb_start_subcarrier
|
||||
+ ((get_softmodem_params()->sl_mode == 0) ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL);
|
||||
|
||||
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
if (doPss) {
|
||||
pss_rxF_ext[i] = pss_rxF[k];
|
||||
}
|
||||
|
||||
if (doSss) {
|
||||
sss_rxF_ext[i] = sss_rxF[k];
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
pss_rxF_ext[i] = pss_rxF[k];
|
||||
sss_rxF_ext[i] = sss_rxF[k];
|
||||
k++;
|
||||
if (k == frame_parms->ofdm_symbol_size) k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int16_t *p = (int16_t *)sss_rxF_ext;
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" sss ext 2 [%d] %d %d at address %p\n", i, p[2*i], p[2*i+1], &p[2*i]);
|
||||
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i], &d_sss[0][0][i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
int16_t *p2 = (int16_t *)pss_rxF_ext;
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" pss_rxF_ext [%d] %d %d at address %p\n", i, p2[2*i], p2[2*i+1], &p2[2*i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pss_sss_extract_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION :
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR],
|
||||
c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR],
|
||||
int ssb_start_subcarrier,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
||||
{
|
||||
return do_pss_sss_extract_nr(frame_parms,
|
||||
pss_ext,
|
||||
sss_ext,
|
||||
1 /* doPss */,
|
||||
1 /* doSss */,
|
||||
ssb_start_subcarrier,
|
||||
rxdataF);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -366,44 +215,22 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
||||
{
|
||||
uint8_t i;
|
||||
c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR];
|
||||
c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR];
|
||||
uint8_t Nid2 = GET_NID2(nid2);
|
||||
uint16_t Nid1;
|
||||
uint8_t phase;
|
||||
int32_t metric, metric_re;
|
||||
int16_t *d;
|
||||
|
||||
const int Nid2 = GET_NID2(nid2);
|
||||
|
||||
// pss sss extraction
|
||||
pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, ssb_start_subcarrier, rxdataF); /* subframe */
|
||||
|
||||
#ifdef DEBUG_PLOT_SSS
|
||||
|
||||
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1);
|
||||
write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1);
|
||||
write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int16_t *p = (int16_t *)sss_ext[0];
|
||||
int16_t *p2 = (int16_t *)pss_ext[0];
|
||||
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
|
||||
printf("sss ext [%i] : %d %d \n", i, p[2*i], p[2*i+1]);
|
||||
|
||||
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
|
||||
printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]);
|
||||
}
|
||||
write_output("pss_ext.m", "pss_ext", pss_ext, LENGTH_PSS_NR, 1, 1);
|
||||
#endif
|
||||
|
||||
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
|
||||
// and do channel estimation and compensation based on PSS
|
||||
|
||||
pss_ch_est_nr(frame_parms, nid2, pss_ext, sss_ext);
|
||||
|
||||
// now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h
|
||||
@@ -411,91 +238,56 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
c16_t *sss = sss_ext[0];
|
||||
|
||||
#ifdef DEBUG_PLOT_SSS
|
||||
|
||||
write_output("sss_ext.m","sss_ext",sss_ext[0],LENGTH_SSS_NR,1,1);
|
||||
write_output("sss_ref.m","sss_ref", d_sss,LENGTH_SSS_NR,1,1);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* simulate of a phase shift on the signal */
|
||||
|
||||
int phase_shift_index = 0;
|
||||
|
||||
phase_shift_samples(sss, LENGTH_SSS_NR, phase_re_nr[phase_shift_index], phase_im_nr[phase_shift_index]);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int16_t *ps = (int16_t *)pss_ext;
|
||||
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
printf("sss ref [%i] : %d \n", i, d_sss[0][0][i]);
|
||||
printf("sss ext [%i] : %d %d \n", i, sss[i].r, sss[i].i);
|
||||
|
||||
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
|
||||
printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for phase evaluation, one uses an array of possible phase shifts */
|
||||
/* then a correlation is done between received signal with a shift pĥase and the reference signal */
|
||||
/* Computation of signal with shift phase is based on below formula */
|
||||
/* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
|
||||
/* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
|
||||
|
||||
uint16_t Nid1_start = 0;
|
||||
uint16_t Nid1_end = N_ID_1_NUMBER;
|
||||
int Nid1_start = 0;
|
||||
int Nid1_end = N_ID_1_NUMBER;
|
||||
if (target_Nid_cell != -1) {
|
||||
Nid1_start = GET_NID1(target_Nid_cell);
|
||||
Nid1_end = Nid1_start + 1;
|
||||
}
|
||||
|
||||
for (Nid1 = Nid1_start; Nid1 < Nid1_end; Nid1++) { // all possible Nid1 values
|
||||
for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
|
||||
|
||||
metric = 0;
|
||||
metric_re = 0;
|
||||
|
||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||
|
||||
// This is the inner product using one particular value of each unknown parameter
|
||||
for (i=0; i < LENGTH_SSS_NR; i++) {
|
||||
metric_re += d[i] * ((phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> SCALING_METRIC_SSS_NR);
|
||||
const int phase_to_try[] = {0, 2, -2, 4, -4, 6, -6, 8, -8, 10, -10, 12, -12, 14, -14};
|
||||
for (int idx = 0; idx < sizeofArray(phase_to_try); idx++) { // phase offset between PSS and SSS
|
||||
const c64_t rot =
|
||||
(c64_t){round(cos(M_PI / 3 / 15 * (phase_to_try[idx])) * 32767), round(sin(M_PI / 3 / 15 * (phase_to_try[idx])) * 32767)};
|
||||
for (int n1 = Nid1_start; n1 < Nid1_end; n1++) { // all possible Nid1 values
|
||||
int64_t metric = 0;
|
||||
int16_t *d = d_sss[Nid2][n1];
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
// metric is only real part because sss is a pure real signal (imaginary is 0)
|
||||
metric += d[i] * (rot.r * sss[i].r - rot.i * sss[i].i);
|
||||
}
|
||||
|
||||
metric = metric_re;
|
||||
|
||||
metric >>= SCALING_METRIC_SSS_NR;
|
||||
// if the current metric is better than the last save it
|
||||
if (metric > *tot_metric) {
|
||||
*tot_metric = metric;
|
||||
*Nid_cell = Nid2 + (3 * Nid1);
|
||||
*phase_max = phase;
|
||||
*Nid_cell = Nid2 + (3 * n1);
|
||||
*phase_max = idx;
|
||||
|
||||
#ifdef DEBUG_SSS_NR
|
||||
|
||||
LOG_D(PHY,"(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",phase, Nid1, metric, *tot_metric, *phase_max);
|
||||
|
||||
LOG_D(PHY,
|
||||
"(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",
|
||||
phase,
|
||||
n1,
|
||||
metric,
|
||||
*tot_metric,
|
||||
*phase_max);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// we try progressively rotation between pss and sss
|
||||
// but pss and sss are in phase at emission
|
||||
// rotation means doppler variation, or very noisy pss detection
|
||||
if (*tot_metric >= SSS_METRIC_FLOOR_NR)
|
||||
break;
|
||||
}
|
||||
|
||||
//#ifdef DEBUG_SSS_NR
|
||||
#define SSS_METRIC_FLOOR_NR (30000)
|
||||
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
|
||||
Nid2 = GET_NID2(*Nid_cell);
|
||||
Nid1 = GET_NID1(*Nid_cell);
|
||||
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
|
||||
}
|
||||
// #endif
|
||||
|
||||
int re = 0;
|
||||
int im = 0;
|
||||
if (Nid1 == Nid1_end) {
|
||||
if (*tot_metric < SSS_METRIC_FLOOR_NR) {
|
||||
LOG_D(PHY,
|
||||
"Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n",
|
||||
*tot_metric,
|
||||
@@ -503,15 +295,19 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
*Nid_cell);
|
||||
return false;
|
||||
}
|
||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||
for(i = 0; i<LENGTH_SSS_NR; i++) {
|
||||
re += d[i] * sss[i].r;
|
||||
im += d[i] * sss[i].i;
|
||||
|
||||
int Nid1 = GET_NID1(*Nid_cell);
|
||||
LOG_D(PHY, "Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
|
||||
int16_t *d = d_sss[Nid2][Nid1];
|
||||
c32_t sig_sum = {};
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
sig_sum.r += d[i] * sss[i].r;
|
||||
sig_sum.i += d[i] * sss[i].i;
|
||||
}
|
||||
double ffo_sss = atan2(im,re)/M_PI/4.3;
|
||||
double ffo_sss = atan2(sig_sum.i, sig_sum.r) / M_PI / 4.3;
|
||||
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
|
||||
|
||||
double ffo_pss = ((double)freq_offset_pss) / frame_parms->subcarrier_spacing;
|
||||
double ffo_pss = (double)freq_offset_pss / frame_parms->subcarrier_spacing;
|
||||
LOG_D(NR_PHY,
|
||||
"SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
|
||||
*Nid_cell,
|
||||
|
||||
@@ -23,6 +23,8 @@ uint32_t target_dl_bw = 50;
|
||||
uint32_t target_dl_Nl;
|
||||
uint32_t target_ul_Nl;
|
||||
char *uecap_file;
|
||||
uint32_t dlsch_slot_modval;
|
||||
uint32_t ulsch_slot_modval;
|
||||
#include <executables/nr-softmodem.h>
|
||||
|
||||
int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;}
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "common/cmake_defs.h"
|
||||
#include "defs_nr_common.h"
|
||||
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "PHY/defs_nr_sl_UE.h"
|
||||
|
||||
@@ -141,14 +141,14 @@ typedef struct {
|
||||
int restricted_set;
|
||||
int numerology_index;
|
||||
int nb_rx;
|
||||
c16_t rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX][NB_ANTENNAS_RX][NR_PRACH_SEQ_LEN_L];
|
||||
c16_t (*Xu)[839];
|
||||
time_stats_t *rx_prach;
|
||||
c16_t (*prach_buf)[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX][NR_PRACH_SEQ_LEN_L];
|
||||
} prach_item_t;
|
||||
|
||||
typedef struct {
|
||||
/// prach commands
|
||||
prach_item_t list[NUMBER_OF_NR_PRACH_MAX];
|
||||
prach_item_t *list[NUMBER_OF_NR_PRACH_MAX];
|
||||
/// mutex for prach_list access
|
||||
pthread_mutex_t prach_list_mutex;
|
||||
} prach_list_t;
|
||||
|
||||
@@ -51,7 +51,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
|
||||
rach_ind->slot = slot;
|
||||
rach_ind->number_of_pdus = 0;
|
||||
|
||||
prach_item_t *prach_id = find_nr_prach(&gNB->prach_list, frame, slot, SEARCH_EXIST);
|
||||
prach_item_t *prach_id = find_nr_prach(&gNB->prach_list, frame, slot, gNB->frame_parms.nb_antennas_rx, SEARCH_EXIST);
|
||||
if (!prach_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
|
||||
bitmap);
|
||||
|
||||
nr_generate_pss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg->cell_config.phy_cell_id.value, fp);
|
||||
|
||||
uint16_t slots_per_hf = (fp->slots_per_frame) >> 1;
|
||||
int n_hf = slot < slots_per_hf ? 0 : 1;
|
||||
@@ -880,32 +880,49 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
|
||||
stop_meas(&gNB->get_srs_signal_stats);
|
||||
|
||||
uint32_t signal_power_avg = 0;
|
||||
uint32_t noise_power_avg = 0;
|
||||
int16_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||
memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t));
|
||||
c16_t srs_ls_estimated_channel[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS];
|
||||
|
||||
if (*srs_est >= 0) {
|
||||
start_meas(&gNB->srs_channel_estimation_stats);
|
||||
|
||||
delay_t delay = {0};
|
||||
for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) {
|
||||
for (int p_ind = 0; p_ind < N_ap; p_ind++) {
|
||||
delay_t delay_aux = {0};
|
||||
nr_srs_ls_channel_estimation(ant_rx_ind,
|
||||
p_ind,
|
||||
ofdm_symbol_size,
|
||||
frame_parms->first_carrier_offset,
|
||||
N_symb_SRS,
|
||||
srs_pdu,
|
||||
nr_srs_info,
|
||||
nr_srs_info->srs_generated_signal[p_ind],
|
||||
srs_received_signal[ant_rx_ind],
|
||||
srs_ls_estimated_channel[ant_rx_ind][p_ind],
|
||||
&delay_aux);
|
||||
if (delay_aux.delay_max_val > delay.delay_max_val)
|
||||
delay = delay_aux;
|
||||
}
|
||||
}
|
||||
|
||||
for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) {
|
||||
uint32_t noise_power = 0;
|
||||
for (int p_ind = 0; p_ind < N_ap; p_ind++) {
|
||||
uint32_t signal_power = 0;
|
||||
nr_srs_channel_estimation(ant_rx_ind,
|
||||
p_ind,
|
||||
ofdm_symbol_size,
|
||||
frame_parms->first_carrier_offset,
|
||||
N_symb_SRS,
|
||||
srs_pdu,
|
||||
nr_srs_info,
|
||||
nr_srs_info->srs_generated_signal[p_ind],
|
||||
srs_received_signal[ant_rx_ind],
|
||||
srs_received_noise[ant_rx_ind],
|
||||
srs_estimated_channel_freq[ant_rx_ind][p_ind],
|
||||
srs_estimated_channel_time[ant_rx_ind][p_ind],
|
||||
srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
|
||||
&signal_power,
|
||||
&noise_power,
|
||||
noise_power_per_rb);
|
||||
nr_srs_channel_interpolation(ant_rx_ind,
|
||||
p_ind,
|
||||
ofdm_symbol_size,
|
||||
frame_parms->first_carrier_offset,
|
||||
N_symb_SRS,
|
||||
srs_pdu,
|
||||
nr_srs_info,
|
||||
srs_ls_estimated_channel[ant_rx_ind][p_ind],
|
||||
delay.est_delay,
|
||||
srs_received_noise[ant_rx_ind],
|
||||
srs_estimated_channel_freq[ant_rx_ind][p_ind],
|
||||
srs_estimated_channel_time[ant_rx_ind][p_ind],
|
||||
srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
|
||||
&signal_power,
|
||||
frame_parms->delay_table);
|
||||
|
||||
signal_power_avg += signal_power;
|
||||
|
||||
@@ -913,7 +930,7 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
|
||||
T_INT(gNB->Mod_id),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(slot_rx),
|
||||
T_INT(0),
|
||||
T_INT(ant_rx_ind),
|
||||
T_INT(p_ind),
|
||||
T_BUFFER(srs_estimated_channel_freq[ant_rx_ind][p_ind], N_symb_SRS * ofdm_symbol_size * sizeof(c16_t)));
|
||||
@@ -922,17 +939,35 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
|
||||
T_INT(gNB->Mod_id),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(slot_rx),
|
||||
T_INT(0),
|
||||
T_INT(ant_rx_ind),
|
||||
T_INT(p_ind),
|
||||
T_BUFFER(srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
|
||||
NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size * sizeof(c16_t)));
|
||||
}
|
||||
noise_power_avg += noise_power;
|
||||
}
|
||||
|
||||
signal_power_avg /= (nb_antennas_rx * N_ap);
|
||||
noise_power_avg /= nb_antennas_rx;
|
||||
signal_power_avg = max(signal_power_avg, 1);
|
||||
|
||||
uint32_t noise_power_avg = 0;
|
||||
int16_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||
memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t));
|
||||
for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) {
|
||||
uint32_t noise_power_per_ant = 0;
|
||||
nr_srs_noise_power_estimation(ofdm_symbol_size,
|
||||
frame_parms->first_carrier_offset,
|
||||
N_symb_SRS,
|
||||
srs_pdu,
|
||||
nr_srs_info,
|
||||
signal_power_avg,
|
||||
srs_received_noise[ant_rx_ind],
|
||||
&noise_power_per_ant,
|
||||
noise_power_per_rb);
|
||||
noise_power_avg += noise_power_per_ant;
|
||||
}
|
||||
|
||||
noise_power_avg /= nb_antennas_rx;
|
||||
gNB->srs->snr = dB_fixed(signal_power_avg) - dB_fixed(max(noise_power_avg, 1));
|
||||
|
||||
const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index);
|
||||
|
||||
@@ -563,7 +563,10 @@ int main(int argc, char **argv){
|
||||
|
||||
phy_init_nr_gNB(gNB);
|
||||
nr_phy_init_RU(ru);
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_list.list[0].pdu;
|
||||
|
||||
prach_item_t *prach_data = calloc(1,sizeof(prach_item_t));
|
||||
gNB->prach_list.list[0] = prach_data;
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &prach_data->pdu;
|
||||
prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
|
||||
prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs));
|
||||
prach_pdu->prach_format = prach_format;
|
||||
@@ -765,26 +768,30 @@ int main(int argc, char **argv){
|
||||
nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config;
|
||||
nfapi_nr_num_prach_fd_occasions_t *occ = &cfg->num_prach_fd_occasions_list[prach_pdu->num_ra];
|
||||
prach_pdu->num_prach_ocas=1;
|
||||
prach_item_t in = {.frame = frame,
|
||||
.slot = slot,
|
||||
.pdu = *prach_pdu,
|
||||
.rootSequenceIndex = occ->prach_root_sequence_index.value,
|
||||
.numrootSequenceIndex = occ->num_root_sequences.value,
|
||||
.msg1_frequencystart = occ->k1.value,
|
||||
.mu = cfg->prach_sub_c_spacing.value,
|
||||
.prach_sequence_length = cfg->prach_sequence_length.value,
|
||||
.restricted_set = cfg->restricted_set_config.value,
|
||||
.numerology_index = gNB->frame_parms.numerology_index,
|
||||
.nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value,
|
||||
.Xu = gNB->X_u,
|
||||
.rx_prach = &gNB->rx_prach};
|
||||
rx_nr_prach_ru(&in, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset);
|
||||
prach_item_t *in = malloc(sizeof(prach_item_t)
|
||||
+ sizeof(c16_t) * gNB->gNB_config.carrier_config.num_rx_ant.value
|
||||
* NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX * NR_PRACH_SEQ_LEN_L);
|
||||
*in = (prach_item_t){.frame = frame,
|
||||
.slot = slot,
|
||||
.pdu = *prach_pdu,
|
||||
.rootSequenceIndex = occ->prach_root_sequence_index.value,
|
||||
.numrootSequenceIndex = occ->num_root_sequences.value,
|
||||
.msg1_frequencystart = occ->k1.value,
|
||||
.mu = cfg->prach_sub_c_spacing.value,
|
||||
.prach_sequence_length = cfg->prach_sequence_length.value,
|
||||
.restricted_set = cfg->restricted_set_config.value,
|
||||
.numerology_index = gNB->frame_parms.numerology_index,
|
||||
.nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value,
|
||||
.Xu = gNB->X_u,
|
||||
.rx_prach = &gNB->rx_prach,
|
||||
.prach_buf = (void *)(in + 1)};
|
||||
rx_nr_prach_ru(in, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset);
|
||||
if (n_frames == 1)
|
||||
LOG_I(PHY,
|
||||
"ncs %d,num_seq %d\n",
|
||||
prach_pdu->num_cs,
|
||||
prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value);
|
||||
rx_prach_out_t out = rx_nr_prach(&in, prachOccasion);
|
||||
rx_prach_out_t out = rx_nr_prach(in, prachOccasion);
|
||||
|
||||
// printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", out.max_preamble_energy, out.max_preamble,
|
||||
// preamble_tx);
|
||||
@@ -807,13 +814,13 @@ int main(int argc, char **argv){
|
||||
LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1);
|
||||
LOG_M("ru_prach_rxsigF0.m", "rxsF0", in.rxsigF[0][0], N_ZC, 1, 1);
|
||||
LOG_M("ru_prach_rxsigF0.m", "rxsF0", in->prach_buf[0][0], N_ZC, 1, 1);
|
||||
LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
|
||||
LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
|
||||
#endif
|
||||
}
|
||||
free(in);
|
||||
}
|
||||
|
||||
printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors));
|
||||
if (input_fd)
|
||||
break;
|
||||
@@ -833,7 +840,7 @@ int main(int argc, char **argv){
|
||||
nr_phy_free_RU(ru);
|
||||
free(RC.ru[0]);
|
||||
free(RC.ru);
|
||||
|
||||
free(prach_data);
|
||||
phy_free_nr_gNB(gNB);
|
||||
// allocated in set_tdd_config_nr()
|
||||
int nb_slots_to_set = (1<<mu)*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
|
||||
@@ -1255,6 +1255,11 @@ static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray)
|
||||
if (GNBparamarray[GNB_DU_SIBS_IDX].numelt == 0)
|
||||
return NULL;
|
||||
|
||||
if (!IS_SA_MODE(get_softmodem_params())) {
|
||||
LOG_E(GNB_APP, "DU SIBs only supported in SA mode, we'll skip them!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seq_arr_t *du_SIBs = malloc(sizeof(seq_arr_t));
|
||||
seq_arr_init(du_SIBs, sizeof(nr_SIBs_t));
|
||||
for (int i = 0; i < GNBparamarray[GNB_DU_SIBS_IDX].numelt; i++) {
|
||||
@@ -1795,6 +1800,11 @@ static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray)
|
||||
if (GNBparamarray[GNB_CU_SIBS_IDX].numelt == 0)
|
||||
return NULL;
|
||||
|
||||
if (!IS_SA_MODE(get_softmodem_params())) {
|
||||
LOG_E(GNB_APP, "CU SIBs only supported in SA mode, we'll skip them!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seq_arr_t *SIBs = malloc(sizeof(seq_arr_t));
|
||||
seq_arr_init(SIBs, sizeof(nr_SIBs_t));
|
||||
for (int i = 0; i < GNBparamarray[GNB_CU_SIBS_IDX].numelt; i++) {
|
||||
|
||||
@@ -42,17 +42,24 @@
|
||||
|
||||
/* This function checks whether the given Dl/UL slot is set
|
||||
in the input bitmap (per period), which is a mask indicating in which
|
||||
slot to transmit (among those available in the TDD configuration) */
|
||||
static bool is_xlsch_in_slot(uint64_t bitmap, slot_t slot)
|
||||
slot to transmit (among those available in the TDD configuration)
|
||||
This function also checks if Dmod/Umod option is set, then the slot will be
|
||||
scheduled in case slot % val == 0.
|
||||
Use Dmod/Umod in case of FDD FR2. */
|
||||
static bool is_xlsch_in_slot(uint64_t bitmap, uint32_t modval, slot_t slot)
|
||||
{
|
||||
AssertFatal(slot < 64, "Unable to handle periods with length larger than 64 slots in phy-test mode\n");
|
||||
return (bitmap >> slot) & 0x01;
|
||||
AssertFatal(modval || slot < 64, "Slot >= 64 cannot be scheduled using options 'D/U', use 'Dmod/Umod' option\n");
|
||||
|
||||
bool val1 = (bitmap >> slot) & 0x01;
|
||||
bool val2 = (modval && (slot % modval == 0));
|
||||
return (val1 || val2);
|
||||
}
|
||||
|
||||
uint32_t target_dl_mcs = 9;
|
||||
uint32_t target_dl_Nl = 1;
|
||||
uint32_t target_dl_bw = 50;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
uint32_t dlsch_slot_modval = 0;
|
||||
|
||||
/* schedules whole bandwidth for first user, all the time */
|
||||
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
@@ -62,7 +69,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
int slot_period = slot % mac->frame_structure.numb_slots_period;
|
||||
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot_period))
|
||||
if (!is_xlsch_in_slot(dlsch_slot_bitmap, dlsch_slot_modval, slot_period))
|
||||
return;
|
||||
NR_UE_info_t *UE = mac->UE_info.connected_ue_list[0];
|
||||
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||
@@ -218,6 +225,7 @@ uint32_t target_ul_mcs = 9;
|
||||
uint32_t target_ul_bw = 50;
|
||||
uint32_t target_ul_Nl = 1;
|
||||
uint64_t ulsch_slot_bitmap = (1 << 8);
|
||||
uint32_t ulsch_slot_modval = 0;
|
||||
void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch)
|
||||
{
|
||||
int frame = pp_pusch->frame;
|
||||
@@ -267,7 +275,7 @@ void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_p
|
||||
* limitations). Note that if K2 or the TDD configuration is changed, below
|
||||
* conditions might exclude each other and never be true */
|
||||
int slot_period = sched_slot % nr_mac->frame_structure.numb_slots_period;
|
||||
if (!is_xlsch_in_slot(ulsch_slot_bitmap, slot_period))
|
||||
if (!is_xlsch_in_slot(ulsch_slot_bitmap, ulsch_slot_modval, slot_period))
|
||||
return;
|
||||
|
||||
// TODO implement beam procedures for phy-test mode
|
||||
|
||||
@@ -486,6 +486,30 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf
|
||||
if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) sib1);
|
||||
LOG_A(NR_RRC, "SIB1 decoded\n");
|
||||
|
||||
plmn_id_t *plmn_id = malloc_or_fail(sizeof(plmn_id_t));
|
||||
|
||||
/* selected_plmn_identity is one-indexed */
|
||||
AssertFatal(rrc->selected_plmn_identity > 0, "No PLMN selected");
|
||||
/* only one PLMN info block is currently supported*/
|
||||
NR_PLMN_Identity_t *plmn = sib1->cellAccessRelatedInfo.plmn_IdentityInfoList.list.array[0]
|
||||
->plmn_IdentityList.list.array[rrc->selected_plmn_identity - 1];
|
||||
|
||||
/* Convert MCC */
|
||||
plmn_id->mcc = (*plmn->mcc->list.array[0]) * 100 + (*plmn->mcc->list.array[1]) * 10 + (*plmn->mcc->list.array[2]);
|
||||
|
||||
plmn_id->mnc_digit_length = plmn->mnc.list.count;
|
||||
|
||||
/* Convert MNC (2 or 3 digits) */
|
||||
if (plmn->mnc.list.count == 3) {
|
||||
plmn_id->mnc = (*plmn->mnc.list.array[0]) * 100 + (*plmn->mnc.list.array[1]) * 10 + (*plmn->mnc.list.array[2]);
|
||||
} else {
|
||||
plmn_id->mnc = (*plmn->mnc.list.array[0]) * 10 + (*plmn->mnc.list.array[1]);
|
||||
}
|
||||
|
||||
nr_ue_nas_t *nas = get_ue_nas_info(rrc->ue_id);
|
||||
nas->sn_id = plmn_id;
|
||||
|
||||
nr_timer_start(&SI_info->sib1_timer);
|
||||
SI_info->sib1_validity = true;
|
||||
if (rrc->nrRrcState == RRC_STATE_IDLE_NR) {
|
||||
|
||||
@@ -101,26 +101,13 @@ static fgmm_msg_header_t set_mm_header(fgs_nas_msg_t type, Security_header_t sec
|
||||
return mm_header;
|
||||
}
|
||||
|
||||
static void servingNetworkName(uint8_t *msg, char *imsiStr, int mnc_size)
|
||||
static void servingNetworkName(uint8_t *msg, plmn_id_t *plmn_id)
|
||||
{
|
||||
// SNN-network-identifier in TS 24.501
|
||||
// TS 24.501: If the MNC of the serving PLMN has two digits, then a zero is added at the beginning.
|
||||
|
||||
// MNC
|
||||
char mnc[4];
|
||||
if (mnc_size == 2) {
|
||||
snprintf(mnc, sizeof(mnc), "0%c%c", imsiStr[3], imsiStr[4]);
|
||||
} else {
|
||||
snprintf(mnc, sizeof(mnc), "%c%c%c", imsiStr[3], imsiStr[4], imsiStr[5]);
|
||||
}
|
||||
|
||||
// MCC
|
||||
char mcc[4];
|
||||
snprintf(mcc, sizeof(mcc), "%c%c%c", imsiStr[0], imsiStr[1], imsiStr[2]);
|
||||
|
||||
int size = 64;
|
||||
|
||||
snprintf((char *)msg, size, "5G:mnc%3s.mcc%3s.3gppnetwork.org", mnc, mcc);
|
||||
snprintf((char *)msg, size, "5G:mnc%03d.mcc%03d.3gppnetwork.org", plmn_id->mnc, plmn_id->mcc);
|
||||
}
|
||||
|
||||
static const char *print_info(uint8_t id, const text_info_t *array, uint8_t array_size)
|
||||
@@ -505,11 +492,11 @@ static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc)
|
||||
return 19;
|
||||
}
|
||||
|
||||
void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, uicc_t *uicc)
|
||||
void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, plmn_id_t *plmn_id)
|
||||
{
|
||||
uint8_t S[100] = {0};
|
||||
S[0] = 0x6B;
|
||||
servingNetworkName(S + 1, uicc->imsiStr, uicc->nmc_size);
|
||||
servingNetworkName(S + 1, plmn_id);
|
||||
int netNamesize = strlen((char *)S + 1);
|
||||
S[1 + netNamesize] = (netNamesize & 0xff00) >> 8;
|
||||
S[2 + netNamesize] = (netNamesize & 0x00ff);
|
||||
@@ -548,7 +535,7 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
|
||||
memcpy(output, out + 16, 16);
|
||||
}
|
||||
|
||||
void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc)
|
||||
void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], plmn_id_t *plmn_id)
|
||||
{
|
||||
uint8_t S[100] = {0};
|
||||
uint8_t key[32] = {0};
|
||||
@@ -556,7 +543,7 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[
|
||||
memcpy(&key[0], ck, 16);
|
||||
memcpy(&key[16], ik, 16); // KEY
|
||||
S[0] = 0x6A;
|
||||
servingNetworkName(S + 1, uicc->imsiStr, uicc->nmc_size);
|
||||
servingNetworkName(S + 1, plmn_id);
|
||||
int netNamesize = strlen((char *)S + 1);
|
||||
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
|
||||
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
|
||||
@@ -570,11 +557,11 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[
|
||||
kdf(key, data, 32, kausf);
|
||||
}
|
||||
|
||||
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc)
|
||||
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], plmn_id_t *plmn_id)
|
||||
{
|
||||
uint8_t S[100] = {0};
|
||||
S[0] = 0x6C; // FC
|
||||
servingNetworkName(S + 1, uicc->imsiStr, uicc->nmc_size);
|
||||
servingNetworkName(S + 1, plmn_id);
|
||||
int netNamesize = strlen((char *)S + 1);
|
||||
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
|
||||
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
|
||||
@@ -641,14 +628,14 @@ static void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas)
|
||||
uint8_t ck[16], ik[16];
|
||||
f2345(nas->uicc->key, rand, resTemp, ck, ik, ak, nas->uicc->opc);
|
||||
|
||||
transferRES(ck, ik, resTemp, rand, output, nas->uicc);
|
||||
transferRES(ck, ik, resTemp, rand, output, nas->sn_id);
|
||||
|
||||
for (int index = 0; index < 6; index++) {
|
||||
sqn[index] = buf[26 + index];
|
||||
}
|
||||
|
||||
derive_kausf(ck, ik, sqn, kausf, nas->uicc);
|
||||
derive_kseaf(kausf, kseaf, nas->uicc);
|
||||
derive_kausf(ck, ik, sqn, kausf, nas->sn_id);
|
||||
derive_kseaf(kausf, kseaf, nas->sn_id);
|
||||
derive_kamf(kseaf, kamf, 0x0000, nas->uicc);
|
||||
derive_kgnb(kamf, nas->security.nas_count_ul, kgnb);
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ typedef struct {
|
||||
int t3446;
|
||||
/* NAS Key Set Identifier associated to the security context */
|
||||
uint8_t *ksi;
|
||||
plmn_id_t *sn_id;
|
||||
} nr_ue_nas_t;
|
||||
|
||||
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);
|
||||
|
||||
@@ -16,10 +16,10 @@ add_library(oran_fhlib_5g MODULE
|
||||
oran-init.c
|
||||
)
|
||||
|
||||
set(F_VERSION 6.1.8)
|
||||
set(F_VERSION 6.1.9)
|
||||
|
||||
find_package(xran REQUIRED)
|
||||
if(xran_VERSION MATCHES "5.*")
|
||||
if(xran_VERSION VERSION_GREATER_EQUAL 5 AND xran_VERSION VERSION_LESS 6)
|
||||
message(FATAL_ERROR "xran E release not supported starting from tag 2026.w08.\nPlease switch to F version ${F_VERSION}")
|
||||
elseif(xran_VERSION VERSION_EQUAL F_VERSION)
|
||||
target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE)
|
||||
|
||||
+29
-48
@@ -178,55 +178,55 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
|
||||
nr_prach_info_t prach_info = get_prach_info(0);
|
||||
|
||||
uint16_t N_ZC, num_prbu;
|
||||
if ((prach_info.format & 0xff) < 4) {
|
||||
N_ZC = 839;
|
||||
num_prbu = 70;
|
||||
prach_info.N_dur = 1;
|
||||
} else {
|
||||
N_ZC = 139;
|
||||
num_prbu = 12;
|
||||
}
|
||||
|
||||
int prach_start_sym = prach_info.start_symbol;
|
||||
int prach_end_sym = prach_info.N_dur + prach_start_sym;
|
||||
struct xran_ru_config *ru_conf = &fh_cfg->ru_conf;
|
||||
int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology;
|
||||
int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology;
|
||||
|
||||
int tti = slots_per_frame * (frame) + (slot);
|
||||
uint32_t subframe = slot / slots_per_subframe;
|
||||
// PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4
|
||||
uint32_t is_prach_frame = (frame % prach_info.x == prach_info.y);
|
||||
uint32_t is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (slot % slots_per_subframe));
|
||||
|
||||
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
|
||||
/* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */
|
||||
if (is_prach_slot) {
|
||||
if (!ru->prach_buf) {
|
||||
LOG_W(HW, "we get rach data from ru, but it is not scheduled %d.%d\n", frame, slot);
|
||||
return -1;
|
||||
}
|
||||
if (ru->prach_buf) {
|
||||
for (sym_idx = prach_start_sym; sym_idx < prach_end_sym; sym_idx++) {
|
||||
for (int aa = 0; aa < ru->nb_rx; aa++) {
|
||||
int16_t *dst, *src;
|
||||
int idx = 0;
|
||||
oran_buf_list_t *bufs = get_xran_buffers(aa / nb_rx_per_ru);
|
||||
// hardcoded to use only first prach occasion
|
||||
dst = (int16_t *)ru->prach_buf[0][aa];
|
||||
dst = (int16_t *)ru->prach_buf[aa][0];
|
||||
src = (int16_t *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx].pData;
|
||||
/* convert Network order to host order */
|
||||
if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_NONE) {
|
||||
if (sym_idx == prach_start_sym) {
|
||||
for (idx = 0; idx < 139 * 2; idx++) {
|
||||
for (idx = 0; idx < N_ZC * 2; idx++) {
|
||||
dst[idx] = ((int16_t)ntohs(src[idx + g_kbar]));
|
||||
}
|
||||
} else {
|
||||
for (idx = 0; idx < 139 * 2; idx++) {
|
||||
for (idx = 0; idx < N_ZC * 2; idx++) {
|
||||
dst[idx] += ((int16_t)ntohs(src[idx + g_kbar]));
|
||||
}
|
||||
}
|
||||
} else if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_BLKFLOAT) {
|
||||
|
||||
int16_t local_dst[12 * 2 * N_SC_PER_PRB] __attribute__((aligned(64)));
|
||||
int16_t local_dst[num_prbu * 2 * N_SC_PER_PRB] __attribute__((aligned(64)));
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
struct xranlib_decompress_request bfp_decom_req = {};
|
||||
struct xranlib_decompress_response bfp_decom_rsp = {};
|
||||
int payload_len = (3 * ru_conf->iqWidth_PRACH + 1) * 12; // 12 = closest number of PRBs to 139 REs
|
||||
int payload_len = (3 * ru_conf->iqWidth_PRACH + 1) * num_prbu;
|
||||
|
||||
bfp_decom_req.data_in = (int8_t *)src;
|
||||
bfp_decom_req.numRBs = 12; // closest number of PRBs to 139 REs
|
||||
bfp_decom_req.numRBs = num_prbu;
|
||||
bfp_decom_req.len = payload_len;
|
||||
bfp_decom_req.compMethod = XRAN_COMPMETHOD_BLKFLOAT;
|
||||
bfp_decom_req.iqWidth = ru_conf->iqWidth_PRACH;
|
||||
@@ -235,21 +235,20 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
bfp_decom_rsp.len = 0;
|
||||
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
armral_bfp_decompression(ru_conf->iqWidth_PRACH, 12, (int8_t *)src, (int16_t *)local_dst);
|
||||
armral_bfp_decompression(ru_conf->iqWidth_PRACH, num_prbu, (int8_t *)src, (int16_t *)local_dst);
|
||||
#else
|
||||
AssertFatal(1 == 0, "BFP decompression not supported on this architecture");
|
||||
#endif
|
||||
// note: this is hardwired for 139 point PRACH sequence, kbar=2
|
||||
if (sym_idx == prach_start_sym)
|
||||
for (idx = 0; idx < (139 * 2); idx++)
|
||||
for (idx = 0; idx < (N_ZC * 2); idx++)
|
||||
dst[idx] = local_dst[idx + g_kbar];
|
||||
else
|
||||
for (idx = 0; idx < (139 * 2); idx++)
|
||||
for (idx = 0; idx < (N_ZC * 2); idx++)
|
||||
dst[idx] += (local_dst[idx + g_kbar]);
|
||||
} // COMPMETHOD_BLKFLOAT
|
||||
} // aa
|
||||
} // symb_indx
|
||||
} // is_prach_slot
|
||||
} // ru->prach_buf
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -543,7 +542,6 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
// Need to use --continuous-tx so that this routine will be triggered in RX slot.
|
||||
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
|
||||
for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) {
|
||||
int first = 1; // The first UL symbol
|
||||
const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf;
|
||||
// skip processing this slot is TX (no RX in this slot)
|
||||
if (!is_tdd_ul_guard_slot(frame_conf, slot)) {
|
||||
@@ -581,17 +579,10 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
pRbElm->nBeamIndex = 0;
|
||||
}
|
||||
} else {
|
||||
if (first) {
|
||||
// ant_id / no of antenna per beam gives the beam_nb
|
||||
pRbElm->nBeamIndex =
|
||||
ru->beam_id[ant_id / (ru->nb_rx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT + sym_idx];
|
||||
// In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly.
|
||||
if (pRbElm->nBeamIndex == -1) {
|
||||
pRbElm->nBeamIndex = 0;
|
||||
} else {
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
// ant_id / no of antenna per beam gives the beam_nb
|
||||
int16_t beam_id = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT + sym_idx];
|
||||
if (beam_id != -1)
|
||||
pRbElm->nBeamIndex = beam_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -663,13 +654,6 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
for (uint32_t idxElm = 0; idxElm < pPrbMap->nPrbElm; idxElm++) {
|
||||
struct xran_section_desc *p_sec_desc = NULL;
|
||||
struct xran_prb_elm *p_prbMapElm = &pPrbMap->prbMap[idxElm];
|
||||
if (sym_idx == 0) {
|
||||
// ant_id / no of antenna per beam gives the beam_nb
|
||||
p_prbMapElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT];
|
||||
// In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly.
|
||||
if (p_prbMapElm->nBeamIndex == -1)
|
||||
p_prbMapElm->nBeamIndex = 0;
|
||||
}
|
||||
|
||||
// radio-transport fragmentation is not supported in xran F release;
|
||||
// E-bit = 1 => each ethernet frame is considered as the last fragment;
|
||||
@@ -700,13 +684,10 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
if (p_prbMapElm->nBeamIndex == -1)
|
||||
p_prbMapElm->nBeamIndex = 0;
|
||||
} else {
|
||||
if (sym_idx == 0) {
|
||||
// ant_id / no of antenna per beam gives the beam_nb
|
||||
p_prbMapElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT];
|
||||
// In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly.
|
||||
if (p_prbMapElm->nBeamIndex == -1)
|
||||
p_prbMapElm->nBeamIndex = 0;
|
||||
}
|
||||
// ant_id / no of antenna per beam gives the beam_nb
|
||||
int16_t beam_id = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT + sym_idx];
|
||||
if ( beam_id != -1)
|
||||
p_prbMapElm->nBeamIndex = beam_id;
|
||||
}
|
||||
|
||||
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
|
||||
|
||||
@@ -432,12 +432,10 @@ void print_fh_config(const struct xran_fh_config *fh_config)
|
||||
#if defined F_RELEASE
|
||||
printf("\
|
||||
RunSlotPrbMapBySymbolEnable %d\n\
|
||||
LiteOnIgnoreUPSectionIdEnable %d\n\
|
||||
dssEnable %d\n\
|
||||
dssPeriod %d\n\
|
||||
technology[XRAN_MAX_DSS_PERIODICITY] (not filled as DSS disabled)\n",
|
||||
fh_config->RunSlotPrbMapBySymbolEnable,
|
||||
fh_config->LiteOnIgnoreUPSectionIdEnable,
|
||||
fh_config->dssEnable,
|
||||
fh_config->dssPeriod);
|
||||
#endif
|
||||
@@ -777,8 +775,7 @@ static bool set_fh_prach_config(void *mplane_api,
|
||||
const uint32_t max_num_ant,
|
||||
const paramdef_t *prachp,
|
||||
int nprach,
|
||||
struct xran_prach_config *prach_config,
|
||||
bool liteon_prach_eAxC_offset)
|
||||
struct xran_prach_config *prach_config)
|
||||
{
|
||||
const split7_config_t *s7cfg = &oai0->split7;
|
||||
|
||||
@@ -814,11 +811,8 @@ static bool set_fh_prach_config(void *mplane_api,
|
||||
xran_mplane_t *xran_mplane = (xran_mplane_t *)mplane_api;
|
||||
prach_config->eAxC_offset = xran_mplane->prach_offset;
|
||||
#else
|
||||
uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr;
|
||||
if (liteon_prach_eAxC_offset)
|
||||
prach_config->eAxC_offset = offset;
|
||||
else
|
||||
prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant;
|
||||
const paramdef_t *pd = gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET);
|
||||
prach_config->eAxC_offset = pd->paramflags & PARAMFLAG_PARAMSET ? *pd->u8ptr : max_num_ant;
|
||||
#endif
|
||||
|
||||
g_kbar = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_KBAR)->uptr;
|
||||
@@ -964,13 +958,9 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
fh_config->prachEnable = 1; // enable PRACH
|
||||
fh_config->srsEnable = 0; // enable SRS; used only if XRAN_CATEGORY_B
|
||||
// For LiteOn E release, no need to take care of prach eAxC_offset. xran lib is hacked to handle it.
|
||||
bool liteon_prach_eAxC_offset = false;
|
||||
#if defined F_RELEASE
|
||||
fh_config->srsEnableCp = 0; // enable SRS CP; used only if XRAN_CATEGORY_B
|
||||
fh_config->SrsDelaySym = 0; // number of SRS delay symbols; used only if XRAN_CATEGORY_B
|
||||
fh_config->RunSlotPrbMapBySymbolEnable = *gpd(fhp, nfh, ORAN_CONFIG_RunSlotPrbMapBySymbol)->uptr; // enable RunSlotPrbMapBySymbol
|
||||
fh_config->LiteOnIgnoreUPSectionIdEnable = *gpd(fhp, nfh, ORAN_CONFIG_LiteOnIgnoreUPSectionId)->uptr; // enable LiteOnIgnoreUPSectionId
|
||||
liteon_prach_eAxC_offset = fh_config->LiteOnIgnoreUPSectionIdEnable;
|
||||
#endif
|
||||
fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU
|
||||
fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU
|
||||
@@ -982,7 +972,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
fh_config->GPS_Alpha = 0; // refers to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns); offset_nsec = (pConf->GPS_Beta - offset_sec * 100) * 1e7 + pConf->GPS_Alpha
|
||||
fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100
|
||||
|
||||
if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf, liteon_prach_eAxC_offset))
|
||||
if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf))
|
||||
return false;
|
||||
/* SRS only used if XRAN_CATEGORY_B
|
||||
Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */
|
||||
@@ -1014,6 +1004,8 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
fh_config->max_sections_per_symbol = 0; // not used in xran
|
||||
|
||||
#if defined F_RELEASE
|
||||
fh_config->RunSlotPrbMapBySymbolEnable = *gpd(fhp, nfh, ORAN_CONFIG_CP_MULTISECTION)->uptr; // enable PRB mapping by symbol with multisection
|
||||
|
||||
fh_config->dssEnable = 0; // enable DSS (extension-9)
|
||||
fh_config->dssPeriod = 0; // DSS pattern period for LTE/NR
|
||||
// fh_config->technology[XRAN_MAX_DSS_PERIODICITY] // technology array represents slot is LTE(0)/NR(1); used only if DSS enabled
|
||||
|
||||
@@ -315,16 +315,8 @@ static void oran_allocate_buffers(void *handle,
|
||||
};
|
||||
|
||||
#if defined F_RELEASE
|
||||
uint32_t size_of_prb_map;
|
||||
if (fh_config->RunSlotPrbMapBySymbolEnable) {
|
||||
// For Liteon FR2 with RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[14]
|
||||
size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (XRAN_NUM_OF_SYMBOL_PER_SLOT);
|
||||
}
|
||||
else {
|
||||
// For non-Liteon w/o RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[1]
|
||||
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu);
|
||||
size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
||||
}
|
||||
uint32_t numPrbElm = (fh_config->RunSlotPrbMapBySymbolEnable) ? XRAN_NUM_OF_SYMBOL_PER_SLOT : xran_get_num_prb_elm(&dlPm, mtu);
|
||||
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
||||
#endif
|
||||
|
||||
// PDSCH
|
||||
|
||||
@@ -106,8 +106,7 @@
|
||||
|
||||
#define CONFIG_STRING_ORAN_FH "fh_config"
|
||||
|
||||
#define ORAN_CONFIG_RunSlotPrbMapBySymbol "RunSlotPrbMapBySymbol"
|
||||
#define ORAN_CONFIG_LiteOnIgnoreUPSectionId "LiteOnIgnoreUPSectionId"
|
||||
#define ORAN_CONFIG_CP_MULTISECTION "RunSlotPrbMapBySymbol"
|
||||
#define ORAN_FH_CONFIG_T1A_CP_DL "T1a_cp_dl"
|
||||
#define ORAN_FH_CONFIG_T1A_CP_UL "T1a_cp_ul"
|
||||
#define ORAN_FH_CONFIG_T1A_UP "T1a_up"
|
||||
@@ -117,8 +116,7 @@
|
||||
|
||||
// clang-format off
|
||||
#define ORAN_FH_DESC { \
|
||||
{ORAN_CONFIG_RunSlotPrbMapBySymbol, "RunSlotPrbMapBySymbol\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
|
||||
{ORAN_CONFIG_LiteOnIgnoreUPSectionId, "Liteon Ignore Section Id\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
|
||||
{ORAN_CONFIG_CP_MULTISECTION, "RunSlotPrbMapBySymbol\n", PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT32, 0}, \
|
||||
{ORAN_FH_CONFIG_T1A_CP_DL, "T1a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
|
||||
{ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
|
||||
{ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \
|
||||
@@ -145,7 +143,7 @@
|
||||
|
||||
// clang-format off
|
||||
#define ORAN_PRACH_DESC {\
|
||||
{ORAN_PRACH_CONFIG_EAXC_OFFSET, "RU's eAxC offset for PRACH\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=0, TYPE_UINT8, 0}, \
|
||||
{ORAN_PRACH_CONFIG_EAXC_OFFSET, "RU's eAxC offset for PRACH\n", 0, .u8ptr=NULL, .defuintval=0, TYPE_UINT8, 0}, \
|
||||
{ORAN_PRACH_CONFIG_KBAR, "PRACH guard interval\n", 0, .uptr=NULL, .defuintval=4, TYPE_UINT, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -213,16 +213,31 @@ int trx_oran_ctlrecv(openair0_device_t *device, void *msg, ssize_t msg_len)
|
||||
|
||||
void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
|
||||
{
|
||||
prach_item_t *prach_id = find_nr_prach(&ru->gNB_list[0]->prach_list, *frame, *slot, SEARCH_EXIST);
|
||||
ru_info_t ru_info = {
|
||||
.nb_rx = ru->nb_rx * ru->num_beams_period,
|
||||
.nb_tx = ru->nb_tx * ru->num_beams_period,
|
||||
.rxdataF = ru->common.rxdataF,
|
||||
.beam_id = ru->common.beam_id,
|
||||
.num_beams_period = ru->num_beams_period,
|
||||
.prach_buf = prach_id ? prach_id->rxsigF : NULL,
|
||||
.prach_buf = NULL,
|
||||
};
|
||||
|
||||
prach_item_t *prach_id = find_nr_prach(&ru->gNB_list[0]->prach_list, *frame, *slot, ru->nr_frame_parms->nb_antennas_rx, SEARCH_EXIST);
|
||||
if (prach_id) {
|
||||
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
|
||||
int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology;
|
||||
uint32_t subframe = *slot / slots_per_subframe; // `slot` = slot in which PRACH is received
|
||||
// PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4
|
||||
nr_prach_info_t prach_info = get_prach_info(0);
|
||||
bool is_prach_frame = (*frame % prach_info.x == prach_info.y);
|
||||
bool is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (prach_id->slot % slots_per_subframe)); // `prach_id->slot` = slot in which PRACH is scheduled
|
||||
if (is_prach_slot) {
|
||||
ru_info.prach_buf = prach_id->prach_buf;
|
||||
} else {
|
||||
LOG_W(HW, "[%d.%d] Expected PRACH reception of scheduled slot %d\n", *frame, *slot, prach_id->slot);
|
||||
}
|
||||
}
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
int f, sl;
|
||||
LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]);
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common/cmake_defs.h"
|
||||
#include "xran_fh_o_du.h"
|
||||
#include "openair1/PHY/impl_defs_nr.h"
|
||||
#include "openair1/PHY/TOOLS/tools_defs.h"
|
||||
#include "openair1/PHY/defs_common.h"
|
||||
/*
|
||||
* Structure added to bear the information needed from OAI RU
|
||||
*/
|
||||
@@ -52,7 +52,7 @@ typedef struct ru_info_s {
|
||||
int num_beams_period;
|
||||
|
||||
// Needed for Prach
|
||||
c16_t (*prach_buf)[NB_ANTENNAS_RX][NR_PRACH_SEQ_LEN_L];
|
||||
c16_t (*prach_buf)[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX][NR_PRACH_SEQ_LEN_L];
|
||||
} ru_info_t;
|
||||
|
||||
/** @brief Reads RX data (PRACH/PUSCH) of next slot.
|
||||
|
||||
@@ -1019,7 +1019,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t,
|
||||
signal_energy(static_cast<int32_t *>(samplesVoid[0][0]), nsamps));
|
||||
|
||||
/* trace only first antenna */
|
||||
T(T_USRP_TX_ANT0, T_INT(timestamp), T_BUFFER(samplesVoid[0], (int)sampleToByte(nsamps, 1)));
|
||||
T(T_USRP_TX_ANT0, T_INT(timestamp), T_BUFFER(samplesVoid[0][0], (int)sampleToByte(nsamps, 1)));
|
||||
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ interface.
|
||||
|
||||
The `vrtsim` architecture follows a server-client model:
|
||||
|
||||
- **Server (gNB)**: On startup, the server writes a file, default location is
|
||||
- **Server (gNB)**: On startup, the server writes connection information to a
|
||||
file as provided in `--vrtsim.descriptor`, default location is
|
||||
`/tmp/vrtsim_connection`. This file contains information required by the client
|
||||
to establish communication.
|
||||
- **Client (UE)**: The client reads this file from, verifies its contents, and uses
|
||||
@@ -31,6 +32,13 @@ Additionally on gNB use `vrtsim.role server` and optionally
|
||||
`vrtsim.timescale <timescale>` to set the timescale. Timescale 1.0
|
||||
is the default and means realtime.
|
||||
|
||||
To use `vrtsim` in containers, you have to enable inter-process communication,
|
||||
and mount the directory of the connection information in a shared volume
|
||||
between server and clients. For instance, in docker and default
|
||||
`vrtsim.connection_descriptor`, set `ipc: host` and share the server's and
|
||||
client's `/tmp` directory through a volume. For an example, refer to
|
||||
[this docker-compose file](../../ci-scripts/yaml_files/5g_vrtsim_cirdb/docker-compose.yaml).
|
||||
|
||||
Channel modelling can be enabled by adding `vrtsim.chanmod 1` to the
|
||||
command line and should work the same as channel modelling in rfsimulator,
|
||||
see rfsimulator [documentation](../rfsimulator/README.md) with a slight difference:
|
||||
|
||||
@@ -1133,5 +1133,6 @@ __attribute__((__visibility__("default"))) int device_init(openair0_device_t *de
|
||||
LOG_A(HW, "VRTSIM: Noise power %d sample value\n", noise_power);
|
||||
init_noise_device(noise_power);
|
||||
}
|
||||
openair0_cfg->rx_gain[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 5;
|
||||
ssPBCH_BlockPower = 0;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = 0;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = 0;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = 0;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
+122
-90
@@ -1,87 +1,94 @@
|
||||
Active_gNBs = ( "oai-du");
|
||||
Active_gNBs = ( "inria-gnb");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "oai-du";
|
||||
gNB_ID = 0xe99;
|
||||
cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "inria-gnb";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 97; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
|
||||
nr_cellid = 1;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 4;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
maxMIMO_layers = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
force_UL256qam_off = 1;
|
||||
min_rxtxtime = 4;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741)
|
||||
absoluteFrequencySSB = 649920; #JF maybe we should adjust a bit
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3300.24 MHz
|
||||
dl_absoluteFrequencyPointA = 646724;
|
||||
# center frequency = 28701.12 MHz
|
||||
# selected SSB frequency = 28691.04 MHz
|
||||
absoluteFrequencySSB = 2090683;
|
||||
dl_frequencyBand = 257;
|
||||
# frequency point A = 28653.6 MHz
|
||||
dl_absoluteFrequencyPointA = 2090059;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 273;
|
||||
dl_subcarrierSpacing = 3;
|
||||
dl_carrierBandwidth = 66;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
|
||||
initialDLBWPlocationAndBandwidth = 1099;
|
||||
#
|
||||
initialDLBWPlocationAndBandwidth = 17875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
initialDLBWPsubcarrierSpacing = 3;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPcontrolResourceSetZero = 2;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
ul_frequencyBand = 257;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 273;
|
||||
ul_subcarrierSpacing = 3;
|
||||
ul_carrierBandwidth = 66;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 1099;
|
||||
initialULBWPlocationAndBandwidth = 17875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
initialULBWPsubcarrierSpacing = 3;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 148; # JF check this and other PRACH related params
|
||||
prach_ConfigurationIndex = 135;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 12;
|
||||
preambleReceivedTargetPower = -96;
|
||||
zeroCorrelationZoneConfig = 15;
|
||||
preambleReceivedTargetPower = -118;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
preambleTransMax = 8;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
powerRampingStep = 2;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
|
||||
#one (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
@@ -94,12 +101,15 @@ gNBs =
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
msg1_SubcarrierSpacing = 3,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
msg3_DeltaPreamble = 1;
|
||||
|
||||
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
|
||||
msg3_DeltaPreamble = 0;
|
||||
p0_NominalWithGrant = -90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
@@ -108,30 +118,38 @@ gNBs =
|
||||
p0_nominal = -90;
|
||||
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
ssb_periodicityServingCell = 1;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
subcarrierSpacing = 3;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
referenceSubcarrierSpacing = 3;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 5; #6;
|
||||
nrofDownlinkSlots = 3; #7;
|
||||
dl_UL_TransmissionPeriodicity = 3;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 1; #2;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
ssPBCH_BlockPower = -10;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
@@ -140,60 +158,71 @@ gNBs =
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ({ ipv4 = "172.21.6.103"; });
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ({ ipv4 = "172.21.6.4"; });
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.18.20";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.18.20";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.51";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.51";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 220;
|
||||
pucch_TargetSNRx10 = 220;
|
||||
ul_bler_target_upper=.35;
|
||||
ul_bler_target_lower=.15;
|
||||
pusch_FailureThres = 100;
|
||||
ul_max_mcs = 28;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
pusch_FailureThres = 1000;
|
||||
#ul_bler_target_upper =.02;
|
||||
#ul_bler_target_lower =.01;
|
||||
#dl_bler_target_upper =.15;
|
||||
#dl_bler_target_lower =.05
|
||||
set_analog_beamforming = "lophy";
|
||||
beam_duration = 1;
|
||||
beams_per_period = 1;
|
||||
beam_weights = [1];
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 130;
|
||||
pucch0_dtx_threshold = 80;
|
||||
pusch_dtx_threshold = 10;
|
||||
prach_dtx_threshold = 250;
|
||||
pucch0_dtx_threshold = 100;
|
||||
pusch_dtx_threshold = -200;
|
||||
max_ldpc_iterations = 10;
|
||||
tx_amp_backoff_dB = 12; #9; needs to match O-RU configuration # JF important to check
|
||||
L1_rx_thread_core = 3;
|
||||
L1_tx_thread_core = 4; # relevant after merge of l1_tx_thread
|
||||
phase_compensation = 0; # needs to match O-RU configuration # JF to be tested
|
||||
tx_amp_backoff_dB = 18;
|
||||
L1_rx_thread_core = 10;
|
||||
L1_tx_thread_core = 11;
|
||||
phase_compensation = 1;
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 4;
|
||||
nb_rx = 4;
|
||||
nb_tx = 2;
|
||||
nb_rx = 2;
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
bands = [257];
|
||||
nr_scs_for_raster = 3;
|
||||
max_pdschReferenceSignalPower = -40;
|
||||
max_rxgain = 60;
|
||||
#sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 6;
|
||||
sl_ahead = 10; #5;
|
||||
tr_preference = "raw_if4p5"; # important: activate FHI7.2
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
ru_thread_core = 9;
|
||||
sl_ahead = 10;
|
||||
tr_preference = "raw_if4p5";
|
||||
do_precoding = 0;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -216,34 +245,37 @@ security = {
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="info";
|
||||
f1ap_log_level ="info";
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
pdcp_log_level = "info";
|
||||
rrc_log_level = "info";
|
||||
ngap_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:c3:11.0", "0000:c3:11.1");
|
||||
dpdk_iova_mode = "VA";
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
ru_addr = ("00:E0:0C:00:AE:06", "00:E0:0C:00:AE:06");
|
||||
mtu = 9000;
|
||||
dpdk_devices = ("0000:c1:11.0", "0000:c1:11.1"); # one VF can be used as well
|
||||
system_core = 6;
|
||||
io_core = 7;
|
||||
worker_cores = (8);
|
||||
ru_addr = ("E8:C7:4F:1E:C7:5B", "E8:C7:4F:1E:C7:5B");
|
||||
mtu = 9216;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (285, 470);
|
||||
T1a_cp_ul = (285, 429);
|
||||
T1a_up = (125, 350);
|
||||
Ta4 = (110, 180);
|
||||
RunSlotPrbMapBySymbol = 1;
|
||||
T1a_cp_dl = (110, 111);
|
||||
T1a_cp_ul = (69, 70);
|
||||
T1a_up = (30, 64);
|
||||
Ta4 = (30, 64);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
iq_width = 8;
|
||||
iq_width_prach = 8;
|
||||
};
|
||||
prach_config = {
|
||||
eAxC_offset = 0;
|
||||
kbar = 0;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@@ -144,7 +144,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -7;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
+43
-42
@@ -11,7 +11,7 @@ gNBs =
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 97; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
|
||||
nr_cellid = 1;
|
||||
|
||||
@@ -20,10 +20,9 @@ gNBs =
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pdsch_AntennaPorts_N1 = 1;
|
||||
maxMIMO_layers = 2;
|
||||
pusch_AntennaPorts = 4;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
# force_UL256qam_off = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
@@ -33,12 +32,12 @@ gNBs =
|
||||
# n_TimingAdvanceOffset = 0;
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# center frequency = 3350.01 MHz
|
||||
# selected SSB frequency = 3349.92 MHz
|
||||
absoluteFrequencySSB = 623328;
|
||||
dl_frequencyBand = 78;
|
||||
# frequency point A = 3300.87 MHz
|
||||
dl_absoluteFrequencyPointA = 620052;
|
||||
# center frequency = 3950.4 MHz
|
||||
# selected SSB frequency = 3950.4 MHz
|
||||
absoluteFrequencySSB = 663360;
|
||||
dl_frequencyBand = 77;
|
||||
# frequency point A = 3901.26 MHz
|
||||
dl_absoluteFrequencyPointA = 660084;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
@@ -58,7 +57,7 @@ gNBs =
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
ul_frequencyBand = 77;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
@@ -74,7 +73,7 @@ gNBs =
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 152;
|
||||
prach_ConfigurationIndex = 7;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
@@ -85,10 +84,10 @@ gNBs =
|
||||
preambleTransMax = 8;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
powerRampingStep = 3;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
|
||||
#one (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
@@ -97,11 +96,11 @@ gNBs =
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex_PR = 1;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
@@ -145,9 +144,8 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -15;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
@@ -161,12 +159,12 @@ gNBs =
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ({ ipv4 = "172.21.6.103"; });
|
||||
amf_ip_address = ({ ipv4 = "172.21.6.5";});
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.18.20";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.18.20";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.130";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.130";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
@@ -177,13 +175,13 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 100;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
dl_bler_target_upper = .35;
|
||||
dl_bler_target_lower = .15;
|
||||
ul_bler_target_upper = .35;
|
||||
ul_bler_target_lower = .15;
|
||||
pusch_FailureThres = 1000;
|
||||
pusch_TargetSNRx10 = 180;
|
||||
pucch_TargetSNRx10 = 180;
|
||||
# dl_bler_target_upper = .35;
|
||||
# dl_bler_target_lower = .15;
|
||||
# ul_bler_target_upper = .35;
|
||||
# ul_bler_target_lower = .15;
|
||||
pusch_FailureThres = 100;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
@@ -192,13 +190,13 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 90;
|
||||
pucch0_dtx_threshold = 80;
|
||||
prach_dtx_threshold = 100;
|
||||
pucch0_dtx_threshold = 10;
|
||||
pusch_dtx_threshold = 10;
|
||||
max_ldpc_iterations = 15;
|
||||
tx_amp_backoff_dB = 12; # needs to match O-RU configuration
|
||||
L1_rx_thread_core = 3;
|
||||
L1_tx_thread_core = 4;
|
||||
L1_rx_thread_core = 6;
|
||||
L1_tx_thread_core = 7;
|
||||
phase_compensation = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
@@ -206,17 +204,17 @@ L1s = (
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 4;
|
||||
nb_rx = 4;
|
||||
nb_tx = 2;
|
||||
nb_rx = 2;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 5;
|
||||
sl_ahead = 10;
|
||||
ru_thread_core = 8;
|
||||
sl_ahead = 5;
|
||||
tr_preference = "raw_if4p5"; # important: activate FHI7.2
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
@@ -253,20 +251,23 @@ log_config :
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:c3:11.0", "0000:c3:11.1");
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
ru_addr = ("70:b3:d5:e1:5b:81", "70:b3:d5:e1:5b:81");
|
||||
dpdk_devices = ("0000:6f:01.0");
|
||||
system_core = 9;
|
||||
io_core = 10;
|
||||
worker_cores = (11);
|
||||
ru_addr = ("8c:1f:64:d1:11:1e");
|
||||
mtu = 9216;
|
||||
fh_config = ({
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
Ta4 = (0, 831);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
prach_config = {
|
||||
eAxC_offset = 8;
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -142,7 +142,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1; #2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ gNBs =
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 0;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ gNBs =
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 1; #2;
|
||||
nrofUplinkSymbols = 4;
|
||||
ssPBCH_BlockPower = -10;
|
||||
ssPBCH_BlockPower = -11;
|
||||
}
|
||||
);
|
||||
# ------- SCTP definitions
|
||||
|
||||
Reference in New Issue
Block a user