Merge branch 'aw2s-n41' of https://gitlab.eurecom.fr/oai/openairinterface5g into aw2s-n41
This commit is contained in:
@@ -529,28 +529,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") {
|
||||
when {
|
||||
expression {doFullTestsuite}
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU')
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210')
|
||||
}
|
||||
}
|
||||
failure {
|
||||
script {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Test OAI UE - FDD - Band 20 - B200") {
|
||||
when {
|
||||
expression {doFullTestsuite}
|
||||
|
||||
@@ -36,7 +36,7 @@ eNBs =
|
||||
Nid_cell = 0;
|
||||
N_RB_DL = 100;
|
||||
Nid_cell_mbsfn = 0;
|
||||
nb_antenna_ports = 1;
|
||||
nb_antenna_ports = 2;
|
||||
nb_antennas_tx = 2;
|
||||
nb_antennas_rx = 2;
|
||||
tx_gain = 90;
|
||||
|
||||
@@ -232,7 +232,7 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
pusch_proc_threads = 2;
|
||||
pusch_proc_threads = 8;
|
||||
prach_dtx_threshold = 120;
|
||||
pucch0_dtx_threshold = 150;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
pusch_proc_threads = 2;
|
||||
pusch_proc_threads = 8;
|
||||
prach_dtx_threshold = 120;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -44,6 +44,7 @@ ENB_PROCESS_ASSERTION = -12
|
||||
ENB_PROCESS_REALTIME_ISSUE = -13
|
||||
ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
|
||||
ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15
|
||||
ENB_REAL_TIME_PROCESSING_ISSUE = -16
|
||||
HSS_PROCESS_FAILED = -2
|
||||
HSS_PROCESS_OK = +2
|
||||
MME_PROCESS_FAILED = -3
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#this is a configuration file
|
||||
#used to build real time processing statistics
|
||||
#for 5G NR phy test (gNB terminate)
|
||||
Title : Processing Time (us)
|
||||
ColNames :
|
||||
- Metric
|
||||
- Average
|
||||
- Max
|
||||
- Average vs Reference Deviation (Reference Value ; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 120.0
|
||||
feptx_prec : 8.0
|
||||
feptx_ofdm : 50.0
|
||||
feptx_total : 75.0
|
||||
L1 Tx processing thread 0 : 300.0
|
||||
L1 Tx processing thread 1 : 300.0
|
||||
DLSCH encoding : 230.0
|
||||
L1 Rx processing : 175.0
|
||||
PUSCH inner-receiver : 100.0
|
||||
PUSCH decoding : 180.0
|
||||
DL & UL scheduling timing stats : 37.0
|
||||
UL Indication : 38.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
feptx_prec : 1.25
|
||||
feptx_ofdm : 1.25
|
||||
feptx_total : 1.25
|
||||
L1 Tx processing thread 0 : 1.25
|
||||
L1 Tx processing thread 1 : 1.25
|
||||
DLSCH encoding : 1.25
|
||||
L1 Rx processing : 1.25
|
||||
PUSCH inner-receiver : 1.25
|
||||
PUSCH decoding : 1.25
|
||||
DL & UL scheduling timing stats : 1.25
|
||||
UL Indication : 1.25
|
||||
@@ -155,6 +155,11 @@ def GetParametersFromXML(action):
|
||||
elif action == 'Initialize_eNB':
|
||||
RAN.eNB_Trace=test.findtext('eNB_Trace')
|
||||
RAN.eNB_Stats=test.findtext('eNB_Stats')
|
||||
datalog_rt_stats_file=test.findtext('rt_stats_cfg')
|
||||
if datalog_rt_stats_file is None:
|
||||
RAN.datalog_rt_stats_file='datalog_rt_stats.default.yaml'
|
||||
else:
|
||||
RAN.datalog_rt_stats_file=datalog_rt_stats_file
|
||||
RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
|
||||
eNB_instance=test.findtext('eNB_instance')
|
||||
USRPIPAddress=test.findtext('USRP_IPAddress')
|
||||
|
||||
+11
-4
@@ -92,6 +92,7 @@ class RANManagement():
|
||||
self.epcPcapFile = ''
|
||||
self.runtime_stats= ''
|
||||
self.datalog_rt_stats={}
|
||||
self.datalog_rt_stats_file='datalog_rt_stats.default.yaml'
|
||||
self.eNB_Trace = '' #if 'yes', Tshark will be launched at initialization
|
||||
self.eNB_Stats = '' #if 'yes', Statistics Monitor will be launched at initialization
|
||||
self.USRPIPAddress = ''
|
||||
@@ -722,6 +723,9 @@ class RANManagement():
|
||||
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze, HTML)
|
||||
if (logStatus < 0):
|
||||
HTML.CreateHtmlTestRow('N/A', 'KO', logStatus)
|
||||
#display rt stats for gNB only
|
||||
if len(self.datalog_rt_stats)!=0 and nodeB_prefix == 'g':
|
||||
HTML.CreateHtmlDataLogTable(self.datalog_rt_stats)
|
||||
self.prematureExit = True
|
||||
self.eNBmbmsEnables[int(self.eNB_instance)] = False
|
||||
return
|
||||
@@ -810,6 +814,7 @@ class RANManagement():
|
||||
#NSA specific log markers
|
||||
nsa_markers ={'SgNBReleaseRequestAcknowledge': [],'FAILURE': [], 'scgFailureInformationNR-r15': [], 'SgNBReleaseRequest': []}
|
||||
nodeB_prefix_found = False
|
||||
RealTimeProcessingIssue = False
|
||||
|
||||
line_cnt=0 #log file line counter
|
||||
for line in enb_log_file.readlines():
|
||||
@@ -1011,7 +1016,7 @@ class RANManagement():
|
||||
#the following part takes the *_stats.log files as source (not the stdout log file)
|
||||
|
||||
#the datalog config file has to be loaded
|
||||
datalog_rt_stats_file='datalog_rt_stats.yaml'
|
||||
datalog_rt_stats_file=self.datalog_rt_stats_file
|
||||
if (os.path.isfile(datalog_rt_stats_file)):
|
||||
yaml_file=datalog_rt_stats_file
|
||||
elif (os.path.isfile('ci-scripts/'+datalog_rt_stats_file)):
|
||||
@@ -1127,8 +1132,7 @@ class RANManagement():
|
||||
#check if there is a fail => will render the test as failed
|
||||
for k in datalog_rt_stats['Data']:
|
||||
if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
|
||||
#setting prematureExit is ok although not the best option
|
||||
self.prematureExit=False #temp for debug : do not stop the test if RT stats are excedeed
|
||||
RealTimeProcessingIssue = True
|
||||
else:
|
||||
statMsg = 'No real time stats found in the log file\n'
|
||||
logging.debug('No real time stats found in the log file')
|
||||
@@ -1162,7 +1166,10 @@ class RANManagement():
|
||||
logging.debug(statMsg)
|
||||
htmleNBFailureMsg += htmlMsg
|
||||
|
||||
|
||||
if RealTimeProcessingIssue:
|
||||
logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with real time processing issue! \u001B[0m')
|
||||
htmleNBFailureMsg += 'Fail due to real time processing issue\n'
|
||||
global_status = CONST.ENB_REAL_TIME_PROCESSING_ISSUE
|
||||
if uciStatMsgCount > 0:
|
||||
statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
|
||||
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Trace>yes</eNB_Trace>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Trace>yes</eNB_Trace>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Trace>yes</eNB_Trace>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Trace>yes</eNB_Trace>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -111,7 +111,6 @@ services:
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oai-smf:latest
|
||||
entrypoint: /bin/bash -c "/openair-smf/bin/oai_smf -c /openair-smf/bin/oai-smf.conf -o"
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- INSTANCE=0
|
||||
@@ -140,12 +139,13 @@ services:
|
||||
- REGISTER_NRF=yes
|
||||
- DISCOVER_UPF=yes
|
||||
- USE_FQDN_DNS=yes
|
||||
- DNN_NI0=oai
|
||||
- DNN_NI2=oai.ipv4
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- oai-amf
|
||||
volumes:
|
||||
- ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
|
||||
- ./oai-smf.conf:/openair-smf/bin/oai-smf.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
|
||||
interval: 10s
|
||||
|
||||
@@ -1,133 +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
|
||||
################################################################################
|
||||
|
||||
SMF =
|
||||
{
|
||||
FQDN = "oai-smf-svc";
|
||||
INSTANCE = 0; # 0 is the default
|
||||
PID_DIRECTORY = "/var/run"; # /var/run is the default
|
||||
|
||||
INTERFACES :
|
||||
{
|
||||
N4 :
|
||||
{
|
||||
# SMF binded interface for N4 communication (UPF)
|
||||
INTERFACE_NAME = "eth0"; # YOUR NETWORK CONFIG HERE
|
||||
IPV4_ADDRESS = "read";
|
||||
};
|
||||
|
||||
SBI :
|
||||
{
|
||||
# SMF binded interface for SBI interface (e.g., communication with AMF, UDM)
|
||||
INTERFACE_NAME = "eth0"; # YOUR NETWORK CONFIG HERE
|
||||
IPV4_ADDRESS = "read";
|
||||
PORT = 80; # YOUR NETWORK CONFIG HERE (default: 80)
|
||||
HTTP2_PORT = 9090; # YOUR NETWORK CONFIG HERE
|
||||
API_VERSION = "v1"; # YOUR SMF API VERSION CONFIG HERE
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
# Pool of UE assigned IP addresses
|
||||
# Do not make IP pools overlap
|
||||
# first IPv4 address X.Y.Z.1 is reserved for GTP network device on UPF
|
||||
IP_ADDRESS_POOL :
|
||||
{
|
||||
IPV4_LIST = (
|
||||
{RANGE = "12.1.1.2 - 12.1.1.128";}, # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
|
||||
{RANGE = "12.1.1.129 - 12.1.1.224";}, # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
|
||||
{RANGE = "10.10.10.2 - 10.10.10.253";} # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
|
||||
|
||||
);
|
||||
IPV6_LIST = (
|
||||
{PREFIX = "2001:1:2::/64";}, # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
|
||||
{PREFIX = "3001:1:2::/64";}, # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
|
||||
{PREFIX = "4001:1:2::/64";} # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
|
||||
);
|
||||
};
|
||||
|
||||
DNN_LIST = (
|
||||
# IPV4_POOL, IPV6_POOL are index in IPV4_LIST, IPV6_LIST, PDU_SESSION_TYPE choice in {IPv4, IPv6, IPv4v6}
|
||||
{DNN_NI = "default"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 2; IPV6_POOL = -1},
|
||||
{DNN_NI = "carrier.com"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 1; IPV6_POOL = -1},
|
||||
{DNN_NI = "oai"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 0; IPV6_POOL = -1}
|
||||
);
|
||||
|
||||
# DNS address communicated to UEs
|
||||
DEFAULT_DNS_IPV4_ADDRESS = "192.168.18.129"; # YOUR DNS CONFIG HERE
|
||||
DEFAULT_DNS_SEC_IPV4_ADDRESS = "192.168.18.129"; # YOUR DNS CONFIG HERE
|
||||
DEFAULT_DNS_IPV6_ADDRESS = "2001:4860:4860::8888"; # YOUR DNS CONFIG HERE
|
||||
DEFAULT_DNS_SEC_IPV6_ADDRESS = "2001:4860:4860::8844"; # YOUR DNS CONFIG HERE
|
||||
|
||||
SUPPORT_FEATURES:
|
||||
{
|
||||
# STRING, {"yes", "no"},
|
||||
REGISTER_NRF = "yes"; # Set to yes if SMF resgisters to an NRF
|
||||
DISCOVER_UPF = "yes"; # Set to yes to enable UPF discovery and selection
|
||||
FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS = "no"; # Non standard feature, normally should be set to "no",
|
||||
# but you may need to set to yes for UE that do not explicitly request a PDN address through NAS signalling
|
||||
USE_LOCAL_SUBSCRIPTION_INFO = "yes"; # Set to yes if SMF uses local subscription information instead of from an UDM
|
||||
USE_FQDN_DNS = "yes"; # Set to yes if AMF/UDM/NRF/UPF will relying on a DNS to resolve FQDN
|
||||
}
|
||||
|
||||
AMF :
|
||||
{
|
||||
IPV4_ADDRESS = "0.0.0.0"; # YOUR AMF CONFIG HERE
|
||||
PORT = 80; # YOUR AMF CONFIG HERE (default: 80)
|
||||
API_VERSION = "v1"; # YOUR AMF API VERSION FOR SBI CONFIG HERE
|
||||
FQDN = "oai-amf" # YOUR AMF FQDN CONFIG HERE
|
||||
};
|
||||
|
||||
UDM :
|
||||
{
|
||||
IPV4_ADDRESS = "127.0.0.1"; # YOUR UDM CONFIG HERE
|
||||
PORT = 80; # YOUR UDM CONFIG HERE (default: 80)
|
||||
API_VERSION = "v1"; # YOUR UDM API VERSION FOR SBI CONFIG HERE
|
||||
FQDN = "localhost" # YOUR UDM FQDN CONFIG HERE
|
||||
};
|
||||
|
||||
NRF :
|
||||
{
|
||||
IPV4_ADDRESS = "192.168.71.130"; # YOUR NRF CONFIG HERE
|
||||
PORT = 80; # YOUR NRF CONFIG HERE (default: 80)
|
||||
API_VERSION = "v1"; # YOUR NRF API VERSION FOR SBI CONFIG HERE
|
||||
FQDN = "oai-nrf" # YOUR NRF FQDN CONFIG HERE
|
||||
};
|
||||
|
||||
UPF_LIST = (
|
||||
{IPV4_ADDRESS = "192.168.71.134" ; FQDN = "oai-spgwu"} # YOUR UPF CONFIG HERE
|
||||
);
|
||||
|
||||
LOCAL_CONFIGURATION :
|
||||
{
|
||||
SESSION_MANAGEMENT_SUBSCRIPTION_LIST = (
|
||||
{ NSSAI_SST = 222, NSSAI_SD = "123", DNN = "default", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
|
||||
QOS_PROFILE_5QI = 7, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
|
||||
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"},
|
||||
{ NSSAI_SST = 1; NSSAI_SD = "1", DNN = "oai", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
|
||||
QOS_PROFILE_5QI = 6, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
|
||||
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"}
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
This page is only valid for an `Ubuntu18` host.
|
||||
|
||||
**NOTE: this version (2021-10-05) is valid for the `v1.1.0` and `v1.2.0` versions of the `OAI 5G CN`.**
|
||||
**NOTE: this version (2022-01-27) has been updated for the `v1.3.0` version of the `OAI 5G CN`.**
|
||||
|
||||
**TABLE OF CONTENTS**
|
||||
|
||||
@@ -76,9 +76,9 @@ $ docker image tag rdefosseoai/oai-nr-ue:develop oai-nr-ue:develop
|
||||
$ docker logout
|
||||
```
|
||||
|
||||
**CAUTION: 2021/10/05 with the release `v1.2.0` of the `CN5G`, the previous version was not compatible any-more.**
|
||||
**CAUTION: 2022/01/27 with the release `v1.3.0` of the `CN5G`, the previous version was not compatible any-more.**
|
||||
|
||||
**This new version is working for both the `v1.1.0` and `v1.2.0` of the `CN5G`.**
|
||||
**This new version is working only with the `v1.3.0` of the `CN5G`.**
|
||||
|
||||
# 2. Deploy containers #
|
||||
|
||||
|
||||
@@ -111,7 +111,6 @@ services:
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oai-smf:latest
|
||||
entrypoint: /bin/bash -c "/openair-smf/bin/oai_smf -c /openair-smf/bin/oai-smf.conf -o"
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- INSTANCE=0
|
||||
@@ -140,12 +139,13 @@ services:
|
||||
- REGISTER_NRF=yes
|
||||
- DISCOVER_UPF=yes
|
||||
- USE_FQDN_DNS=yes
|
||||
- DNN_NI0=oai
|
||||
- DNN_NI2=oai.ipv4
|
||||
depends_on:
|
||||
- oai-nrf
|
||||
- oai-amf
|
||||
volumes:
|
||||
- ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
|
||||
- ./oai-smf.conf:/openair-smf/bin/oai-smf.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
|
||||
interval: 10s
|
||||
|
||||
@@ -1,133 +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
|
||||
################################################################################
|
||||
|
||||
SMF =
|
||||
{
|
||||
FQDN = "oai-smf-svc";
|
||||
INSTANCE = 0; # 0 is the default
|
||||
PID_DIRECTORY = "/var/run"; # /var/run is the default
|
||||
|
||||
INTERFACES :
|
||||
{
|
||||
N4 :
|
||||
{
|
||||
# SMF binded interface for N4 communication (UPF)
|
||||
INTERFACE_NAME = "eth0"; # YOUR NETWORK CONFIG HERE
|
||||
IPV4_ADDRESS = "read";
|
||||
};
|
||||
|
||||
SBI :
|
||||
{
|
||||
# SMF binded interface for SBI interface (e.g., communication with AMF, UDM)
|
||||
INTERFACE_NAME = "eth0"; # YOUR NETWORK CONFIG HERE
|
||||
IPV4_ADDRESS = "read";
|
||||
PORT = 80; # YOUR NETWORK CONFIG HERE (default: 80)
|
||||
HTTP2_PORT = 9090; # YOUR NETWORK CONFIG HERE
|
||||
API_VERSION = "v1"; # YOUR SMF API VERSION CONFIG HERE
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
# Pool of UE assigned IP addresses
|
||||
# Do not make IP pools overlap
|
||||
# first IPv4 address X.Y.Z.1 is reserved for GTP network device on UPF
|
||||
IP_ADDRESS_POOL :
|
||||
{
|
||||
IPV4_LIST = (
|
||||
{RANGE = "12.1.1.2 - 12.1.1.128";}, # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
|
||||
{RANGE = "12.1.1.129 - 12.1.1.224";}, # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
|
||||
{RANGE = "10.10.10.2 - 10.10.10.253";} # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
|
||||
|
||||
);
|
||||
IPV6_LIST = (
|
||||
{PREFIX = "2001:1:2::/64";}, # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
|
||||
{PREFIX = "3001:1:2::/64";}, # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
|
||||
{PREFIX = "4001:1:2::/64";} # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
|
||||
);
|
||||
};
|
||||
|
||||
DNN_LIST = (
|
||||
# IPV4_POOL, IPV6_POOL are index in IPV4_LIST, IPV6_LIST, PDU_SESSION_TYPE choice in {IPv4, IPv6, IPv4v6}
|
||||
{DNN_NI = "default"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 2; IPV6_POOL = -1},
|
||||
{DNN_NI = "carrier.com"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 1; IPV6_POOL = -1},
|
||||
{DNN_NI = "oai"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 0; IPV6_POOL = -1}
|
||||
);
|
||||
|
||||
# DNS address communicated to UEs
|
||||
DEFAULT_DNS_IPV4_ADDRESS = "192.168.18.129"; # YOUR DNS CONFIG HERE
|
||||
DEFAULT_DNS_SEC_IPV4_ADDRESS = "192.168.18.129"; # YOUR DNS CONFIG HERE
|
||||
DEFAULT_DNS_IPV6_ADDRESS = "2001:4860:4860::8888"; # YOUR DNS CONFIG HERE
|
||||
DEFAULT_DNS_SEC_IPV6_ADDRESS = "2001:4860:4860::8844"; # YOUR DNS CONFIG HERE
|
||||
|
||||
SUPPORT_FEATURES:
|
||||
{
|
||||
# STRING, {"yes", "no"},
|
||||
REGISTER_NRF = "yes"; # Set to yes if SMF resgisters to an NRF
|
||||
DISCOVER_UPF = "yes"; # Set to yes to enable UPF discovery and selection
|
||||
FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS = "no"; # Non standard feature, normally should be set to "no",
|
||||
# but you may need to set to yes for UE that do not explicitly request a PDN address through NAS signalling
|
||||
USE_LOCAL_SUBSCRIPTION_INFO = "yes"; # Set to yes if SMF uses local subscription information instead of from an UDM
|
||||
USE_FQDN_DNS = "yes"; # Set to yes if AMF/UDM/NRF/UPF will relying on a DNS to resolve FQDN
|
||||
}
|
||||
|
||||
AMF :
|
||||
{
|
||||
IPV4_ADDRESS = "0.0.0.0"; # YOUR AMF CONFIG HERE
|
||||
PORT = 80; # YOUR AMF CONFIG HERE (default: 80)
|
||||
API_VERSION = "v1"; # YOUR AMF API VERSION FOR SBI CONFIG HERE
|
||||
FQDN = "oai-amf" # YOUR AMF FQDN CONFIG HERE
|
||||
};
|
||||
|
||||
UDM :
|
||||
{
|
||||
IPV4_ADDRESS = "127.0.0.1"; # YOUR UDM CONFIG HERE
|
||||
PORT = 80; # YOUR UDM CONFIG HERE (default: 80)
|
||||
API_VERSION = "v1"; # YOUR UDM API VERSION FOR SBI CONFIG HERE
|
||||
FQDN = "localhost" # YOUR UDM FQDN CONFIG HERE
|
||||
};
|
||||
|
||||
NRF :
|
||||
{
|
||||
IPV4_ADDRESS = "192.168.71.130"; # YOUR NRF CONFIG HERE
|
||||
PORT = 80; # YOUR NRF CONFIG HERE (default: 80)
|
||||
API_VERSION = "v1"; # YOUR NRF API VERSION FOR SBI CONFIG HERE
|
||||
FQDN = "oai-nrf" # YOUR NRF FQDN CONFIG HERE
|
||||
};
|
||||
|
||||
UPF_LIST = (
|
||||
{IPV4_ADDRESS = "192.168.71.134" ; FQDN = "oai-spgwu"} # YOUR UPF CONFIG HERE
|
||||
);
|
||||
|
||||
LOCAL_CONFIGURATION :
|
||||
{
|
||||
SESSION_MANAGEMENT_SUBSCRIPTION_LIST = (
|
||||
{ NSSAI_SST = 222, NSSAI_SD = "123", DNN = "default", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
|
||||
QOS_PROFILE_5QI = 7, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
|
||||
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"},
|
||||
{ NSSAI_SST = 1; NSSAI_SD = "1", DNN = "oai", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
|
||||
QOS_PROFILE_5QI = 6, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
|
||||
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"}
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# authors Laurent Thomas
|
||||
#
|
||||
#######################################
|
||||
|
||||
if [ ! -f /etc/os-release ]; then
|
||||
echo "No /etc/os-release file found. You're likely on an unsupported distro."
|
||||
exit 1
|
||||
@@ -472,7 +473,7 @@ if ! check_supported_distribution; then
|
||||
echo_error "Your distribution $(get_distribution_release) is not supported by oai !"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set_openair_env
|
||||
echo_info "Installing packages"
|
||||
check_install_ubuntu_packages
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ configmodule_interface_t *load_configmodule(int argc,
|
||||
cfgptr = calloc(sizeof(configmodule_interface_t),1);
|
||||
/* argv_info is used to memorize command line options which have been recognized */
|
||||
/* and to detect unrecognized command line options which might have been specified */
|
||||
cfgptr->argv_info = calloc(sizeof(int32_t), argc);
|
||||
cfgptr->argv_info = calloc(sizeof(int32_t), argc+10);
|
||||
/* argv[0] is the exec name, always Ok */
|
||||
cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED;
|
||||
|
||||
|
||||
@@ -500,6 +500,12 @@ int get_subband_size(int NPRB,int size) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// from start symbol index and nb or symbols to symbol occupation bitmap in a slot
|
||||
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) {
|
||||
return ((1<<nrOfSymbols)-1)<<startSymbolIndex;
|
||||
}
|
||||
|
||||
int get_SLIV(uint8_t S, uint8_t L) {
|
||||
return ( (uint16_t)(((L-1)<=7)? (14*(L-1)+S) : (14*(15-L)+(13-S))) );
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
|
||||
int get_subband_size(int NPRB,int size);
|
||||
void SLIV2SL(int SLIV,int *S,int *L);
|
||||
int get_dmrs_port(int nl, uint16_t dmrs_ports);
|
||||
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
|
||||
int get_nb_periods_per_frame(uint8_t tdd_period);
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A[ru_thread] --> RFin>block rx_rf] --> feprx
|
||||
feprx --> half-slot --> end_feprx
|
||||
feprx --> second-thread -- block_end_feprx --> end_feprx>feprx]
|
||||
end_feprx --> rx_nr_prach_ru
|
||||
rx_nr_prach_ru -- block_queue_singleton --> resp_L1>resp L1]
|
||||
resp_L1 -- async launch --> rx_func
|
||||
resp_L1 -- immediate return --> RFin
|
||||
|
||||
subgraph rxfunc
|
||||
rx_func_implem[rx_func]
|
||||
subgraph rxfuncbeg
|
||||
handle_nr_slot_ind
|
||||
--> rnti_to_remove-mgmt
|
||||
--> L1_nr_prach_procedures
|
||||
--> apply_nr_rotation_ul
|
||||
end
|
||||
subgraph phy_procedures_gNB_uespec_RX
|
||||
fill_ul_rb_mask
|
||||
--> pucch(decode each gNB->pucch)
|
||||
-->nr_fill_ul_indication
|
||||
--> nr_ulsch_procedures
|
||||
--> nr_ulsch_decoding
|
||||
--> segInParallel[[all segments decode in parallel]]
|
||||
--> barrier_end_of_ulsch_decoding
|
||||
end
|
||||
subgraph NR_UL_indication
|
||||
handle_nr_rach
|
||||
--> handle_nr_uci
|
||||
--> handle_nr_ulsch
|
||||
subgraph gNB_dlsch_ulsch_scheduler
|
||||
run_pdcp
|
||||
--> nr_rrc_trigger
|
||||
--> schedule_xxxx
|
||||
end
|
||||
handle_nr_ulsch --> gNB_dlsch_ulsch_scheduler
|
||||
subgraph NR_Schedule_response
|
||||
L1_tx_free3>L1_tx_free]
|
||||
--> handle_nr_nfapi_xxx_pdu
|
||||
--> sendTxFilled((L1_tx_filled))
|
||||
--> nr_fill_ul_xxx
|
||||
--> nr_fill_prach
|
||||
end
|
||||
gNB_dlsch_ulsch_scheduler --> NR_Schedule_response
|
||||
end
|
||||
rx_func_implem --> rxfuncbeg
|
||||
rxfuncbeg --> phy_procedures_gNB_uespec_RX
|
||||
phy_procedures_gNB_uespec_RX --> NR_UL_indication
|
||||
-- block_queue_block_PNF_monolithic --> L1_tx_free2>L1 tx filled]
|
||||
-- async launch --> tx_func
|
||||
L1_tx_free2 -- send_msg --> rsp((resp_L1))
|
||||
end
|
||||
rx_func --> rxfunc
|
||||
|
||||
|
||||
subgraph tx_func
|
||||
direction LR
|
||||
subgraph phy_procedures_gNB_TX
|
||||
dcitop[nr_generate dci top]
|
||||
--> nr_generate_csi_rs
|
||||
--> apply_nr_rotation
|
||||
-- send_msg --> end_tx_func((L1_tx_out))
|
||||
end
|
||||
subgraph tx_reorder_thread
|
||||
L1_tx_out>L1_tx_out]
|
||||
--> reorder{re order} --> reorder
|
||||
reorder --> ru_tx_func
|
||||
reorder --> L1_tx_free((L1_tx_free))
|
||||
ru_tx_func --> feptx_prec
|
||||
--> feptx_ofdm
|
||||
end
|
||||
end
|
||||
|
||||
```
|
||||
@@ -17,6 +17,70 @@ body {
|
||||
|
||||
</style>
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A[ru_thread] --> RFin>block rx_rf] --> feprx
|
||||
feprx --> half-slot --> end_feprx
|
||||
feprx --> second-thread -- block_end_feprx --> end_feprx>feprx]
|
||||
end_feprx --> rx_nr_prach_ru
|
||||
rx_nr_prach_ru -- block_queue --> resp_L1>resp L1]
|
||||
resp_L1 -- async launch --> rx_func
|
||||
resp_L1 -- immediate return --> RFin
|
||||
|
||||
subgraph rxfunc
|
||||
rx_func_implem[rx_func]
|
||||
subgraph rxfuncbeg
|
||||
handle_nr_slot_ind
|
||||
--> rnti_to_remove-mgmt
|
||||
--> L1_nr_prach_procedures
|
||||
--> apply_nr_rotation_ul
|
||||
end
|
||||
subgraph phy_procedures_gNB_uespec_RX
|
||||
fill_ul_rb_mask
|
||||
--> pucch(decode each gNB->pucch)
|
||||
-->nr_fill_ul_indication
|
||||
--> nr_ulsch_procedures
|
||||
--> nr_ulsch_decoding
|
||||
--> segInParallel[[all segments decode in parallel]]
|
||||
--> barrier_end_of_ulsch_decoding
|
||||
end
|
||||
subgraph NR_UL_indication
|
||||
handle_nr_rach
|
||||
--> handle_nr_uci
|
||||
--> handle_nr_ulsch
|
||||
--> gNB_dlsch_ulsch_scheduler
|
||||
--> NR_Schedule_response
|
||||
end
|
||||
rx_func_implem --> rxfuncbeg
|
||||
rxfuncbeg --> phy_procedures_gNB_uespec_RX
|
||||
phy_procedures_gNB_uespec_RX --> NR_UL_indication
|
||||
-- block_queue --> L1_tx_free2>L1 tx free]
|
||||
-- async launch --> tx_func
|
||||
L1_tx_free2 -- send_msg --> rsp((resp_L1))
|
||||
end
|
||||
rx_func --> rxfunc
|
||||
|
||||
|
||||
subgraph tx
|
||||
direction LR
|
||||
subgraph tx_func2
|
||||
phy_procedures_gNB_TX
|
||||
--> dcitop[nr_generate dci top]
|
||||
--> nr_generate_csi_rs
|
||||
--> apply_nr_rotation
|
||||
-- send_msg --> end_tx_func((L1_tx_out))
|
||||
end
|
||||
subgraph tx_reorder_thread
|
||||
L1_tx_out>L1_tx_out]
|
||||
--> reorder{re order} --> reorder
|
||||
reorder --> ru_tx_func
|
||||
reorder --> L1_tx_free((L1_tx_free))
|
||||
ru_tx_func --> feptx_prec
|
||||
--> feptx_ofdm
|
||||
end
|
||||
tx_func2 --> tx_reorder_thread
|
||||
end
|
||||
```
|
||||
|
||||
This tuto for 5G gNB design, with Open Cells main
|
||||
{: .text-center}
|
||||
|
||||
+75
-71
@@ -87,7 +87,6 @@
|
||||
#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
|
||||
#include <openair1/PHY/NR_TRANSPORT/nr_dlsch.h>
|
||||
#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
|
||||
//#define DEBUG_THREADS 1
|
||||
|
||||
//#define USRP_DEBUG 1
|
||||
// Fix per CC openair rf/if device update
|
||||
@@ -114,7 +113,6 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
|
||||
void tx_func(void *param) {
|
||||
|
||||
processingData_L1tx_t *info = (processingData_L1tx_t *) param;
|
||||
PHY_VARS_gNB *gNB = info->gNB;
|
||||
int frame_tx = info->frame;
|
||||
int slot_tx = info->slot;
|
||||
|
||||
@@ -122,35 +120,9 @@ void tx_func(void *param) {
|
||||
frame_tx,
|
||||
slot_tx,
|
||||
1);
|
||||
info->slot = -1;
|
||||
//if ((frame_tx&127) == 0) dump_pdsch_stats(fd,gNB);
|
||||
|
||||
// If the later of the 2 L1 tx thread finishes first,
|
||||
// we wait for the earlier one to finish and start the RU thread
|
||||
// to avoid realtime issues with USRP
|
||||
|
||||
// Start RU TX processing.
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
|
||||
processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
|
||||
LOG_D(PHY,"waiting for previous tx to finish, next slot %d,%d\n",syncMsg->next_slot,slot_tx);
|
||||
while (syncMsg->next_slot != slot_tx) {
|
||||
pushNotifiedFIFO(gNB->resp_RU_tx, res);
|
||||
res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
|
||||
syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
|
||||
}
|
||||
LOG_D(PHY,"previous tx finished, next slot %d,%d\n",syncMsg->next_slot,slot_tx);
|
||||
syncMsg->frame_tx = frame_tx;
|
||||
syncMsg->slot_tx = slot_tx;
|
||||
syncMsg->next_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, frame_tx, slot_tx);
|
||||
syncMsg->timestamp_tx = info->timestamp_tx;
|
||||
syncMsg->ru = gNB->RU_list[0];
|
||||
res->key = slot_tx;
|
||||
pushTpool(gNB->threadPool, res);
|
||||
}
|
||||
|
||||
void rx_func(void *param) {
|
||||
|
||||
processingData_L1_t *info = (processingData_L1_t *) param;
|
||||
PHY_VARS_gNB *gNB = info->gNB;
|
||||
int frame_rx = info->frame_rx;
|
||||
@@ -275,15 +247,12 @@ void rx_func(void *param) {
|
||||
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
|
||||
processingData_L1tx_t *syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
while (syncMsg->slot != slot_tx) {
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx, res);
|
||||
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
|
||||
syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
}
|
||||
processingData_L1tx_t *syncMsg;
|
||||
// Its a FIFO so it maitains the order in which the MAC fills the messages
|
||||
// so no need for checking for right slot
|
||||
res = pullTpool(gNB->L1_tx_filled, gNB->threadPool);
|
||||
syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
syncMsg->gNB = gNB;
|
||||
AssertFatal(syncMsg->slot == slot_tx, "Thread message slot and logical slot number do not match\n");
|
||||
syncMsg->timestamp_tx = info->timestamp_tx;
|
||||
res->key = slot_tx;
|
||||
pushTpool(gNB->threadPool, res);
|
||||
@@ -331,8 +300,8 @@ void rx_func(void *param) {
|
||||
}
|
||||
static void dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output) {
|
||||
int stroff = 0;
|
||||
stroff += print_meas_log(gNB->phy_proc_tx_0, "L1 Tx processing thread 0", NULL, NULL, output);
|
||||
stroff += print_meas_log(gNB->phy_proc_tx_1, "L1 Tx processing thread 1", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(gNB->phy_proc_tx[0], "L1 Tx processing thread 0", NULL, NULL, output);
|
||||
//stroff += print_meas_log(gNB->phy_proc_tx[1], "L1 Tx processing thread 1", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output+stroff);
|
||||
@@ -367,8 +336,8 @@ void *nrL1_stats_thread(void *param) {
|
||||
fd=fopen("nrL1_stats.log","w");
|
||||
AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n");
|
||||
|
||||
reset_meas(gNB->phy_proc_tx_0);
|
||||
reset_meas(gNB->phy_proc_tx_1);
|
||||
reset_meas(gNB->phy_proc_tx[0]);
|
||||
//reset_meas(gNB->phy_proc_tx[1]);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->ul_indication_stats);
|
||||
@@ -389,6 +358,52 @@ void *nrL1_stats_thread(void *param) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// This thread reads the finished L1 tx jobs from threaPool
|
||||
// and pushes RU tx thread in the right order. It works only
|
||||
// two parallel L1 tx threads.
|
||||
void *tx_reorder_thread(void* param) {
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
notifiedFIFO_elt_t *resL1Reserve = NULL;
|
||||
|
||||
|
||||
resL1Reserve=pullTpool(gNB->L1_tx_out, gNB->threadPool);
|
||||
int next_tx_slot=((processingData_L1tx_t *)NotifiedFifoData(resL1Reserve))->slot;
|
||||
|
||||
while (!oai_exit) {
|
||||
notifiedFIFO_elt_t *resL1;
|
||||
if (resL1Reserve) {
|
||||
resL1=resL1Reserve;
|
||||
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
|
||||
LOG_E(PHY,"order mistake");
|
||||
resL1Reserve=NULL;
|
||||
resL1 = pullTpool(gNB->L1_tx_out, gNB->threadPool);
|
||||
}
|
||||
} else {
|
||||
resL1 = pullTpool(gNB->L1_tx_out, gNB->threadPool);
|
||||
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
|
||||
if (resL1Reserve)
|
||||
LOG_E(PHY,"error, have a stored packet, then a second one\n");
|
||||
resL1Reserve=resL1;
|
||||
resL1 = pullTpool(gNB->L1_tx_out, gNB->threadPool);
|
||||
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot)
|
||||
LOG_E(PHY,"error, pull two msg, none is good\n");
|
||||
}
|
||||
}
|
||||
processingData_L1tx_t *syncMsgL1= (processingData_L1tx_t *)NotifiedFifoData(resL1);
|
||||
processingData_RU_t syncMsgRU;
|
||||
syncMsgRU.frame_tx = syncMsgL1->frame;
|
||||
syncMsgRU.slot_tx = syncMsgL1->slot;
|
||||
syncMsgRU.timestamp_tx = syncMsgL1->timestamp_tx;
|
||||
syncMsgRU.ru = gNB->RU_list[0];
|
||||
next_tx_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, syncMsgRU.frame_tx, syncMsgRU.slot_tx);
|
||||
pushNotifiedFIFO(gNB->L1_tx_free, resL1);
|
||||
if (resL1==resL1Reserve)
|
||||
resL1Reserve=NULL;
|
||||
ru_tx_func((void*)&syncMsgRU);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void init_gNB_Tpool(int inst) {
|
||||
PHY_VARS_gNB *gNB;
|
||||
gNB = RC.gNB[inst];
|
||||
@@ -420,40 +435,29 @@ void init_gNB_Tpool(int inst) {
|
||||
pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning
|
||||
|
||||
// L1 TX result FIFO
|
||||
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->resp_L1_tx);
|
||||
gNB->L1_tx_free = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
gNB->L1_tx_filled = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
gNB->L1_tx_out = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->L1_tx_free);
|
||||
initNotifiedFIFO(gNB->L1_tx_filled);
|
||||
initNotifiedFIFO(gNB->L1_tx_out);
|
||||
|
||||
// we create 2 threads for L1 tx processing
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,tx_func);
|
||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
init_DLSCH_struct(gNB, msgDataTx);
|
||||
msgDataTx->slot = -1;
|
||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||
reset_meas(&msgDataTx->phy_proc_tx);
|
||||
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
|
||||
|
||||
msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,tx_func);
|
||||
msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
init_DLSCH_struct(gNB, msgDataTx);
|
||||
msgDataTx->slot = -1;
|
||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||
reset_meas(&msgDataTx->phy_proc_tx);
|
||||
gNB->phy_proc_tx_1 = &msgDataTx->phy_proc_tx;
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
|
||||
|
||||
// RU TX result FIFO
|
||||
gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->resp_RU_tx);
|
||||
notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_RU_t),0,gNB->resp_RU_tx,ru_tx_func);
|
||||
processingData_RU_t *msgData = (processingData_RU_t*)msgRUTx->msgData;
|
||||
int first_tx_slot = sf_ahead*gNB->frame_parms.slots_per_subframe;
|
||||
msgData->next_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, 0, first_tx_slot-1);
|
||||
pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning
|
||||
|
||||
if (!get_softmodem_params()->emulate_l1) {
|
||||
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
|
||||
for (int i=0; i < 1; i++) {
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_out,tx_func);
|
||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
init_DLSCH_struct(gNB, msgDataTx);
|
||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||
reset_meas(&msgDataTx->phy_proc_tx);
|
||||
gNB->phy_proc_tx[i] = &msgDataTx->phy_proc_tx;
|
||||
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
|
||||
}
|
||||
|
||||
if (!get_softmodem_params()->emulate_l1)
|
||||
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
|
||||
|
||||
threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder", -1, OAI_PRIORITY_RT_MAX);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-4
@@ -1471,11 +1471,9 @@ void *ru_thread( void *param ) {
|
||||
|
||||
res = pullNotifiedFIFO(gNB->resp_L1);
|
||||
delNotifiedFIFO_elt(res);
|
||||
res = pullNotifiedFIFO(gNB->resp_L1_tx);
|
||||
res = pullNotifiedFIFO(gNB->L1_tx_free);
|
||||
delNotifiedFIFO_elt(res);
|
||||
res = pullNotifiedFIFO(gNB->resp_L1_tx);
|
||||
delNotifiedFIFO_elt(res);
|
||||
res = pullNotifiedFIFO(gNB->resp_RU_tx);
|
||||
res = pullNotifiedFIFO(gNB->L1_tx_free);
|
||||
delNotifiedFIFO_elt(res);
|
||||
|
||||
ru_thread_status = 0;
|
||||
|
||||
@@ -1101,41 +1101,10 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
|
||||
|
||||
notifiedFIFO_elt_t *l1tx_message_extract(PHY_VARS_gNB *gNB, int frame, int slot) {
|
||||
notifiedFIFO_elt_t *res;
|
||||
notifiedFIFO_elt_t *freeRes = NULL;
|
||||
|
||||
// check first message
|
||||
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
if (msgTx->slot == slot) {
|
||||
return res;
|
||||
}
|
||||
if (msgTx->slot == -1) {
|
||||
freeRes = res;
|
||||
}
|
||||
|
||||
// check second message
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,res);
|
||||
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
|
||||
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
if (msgTx->slot == slot) {
|
||||
return res;
|
||||
}
|
||||
if (msgTx->slot == -1) {
|
||||
freeRes = res;
|
||||
}
|
||||
|
||||
if (freeRes) {
|
||||
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
msgTx->num_pdsch_slot=0;
|
||||
msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
|
||||
msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
|
||||
msgTx->slot = slot;
|
||||
msgTx->frame = frame;
|
||||
return freeRes;
|
||||
}
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,res);
|
||||
AssertFatal(1==0, "It means both L1 Tx messages are still waiting to be processed. This happens when L1 Tx processing is too slow. Message slot %d, scheduled slot %d\n",
|
||||
msgTx->slot, slot);
|
||||
//TODO: This needs to be reworked for nfapi to work
|
||||
res = pullTpool(gNB->L1_tx_free, gNB->threadPool);
|
||||
return res;
|
||||
}
|
||||
|
||||
int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req) {
|
||||
@@ -1153,15 +1122,15 @@ int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
|
||||
proc = &gNB->proc.L1_proc;
|
||||
|
||||
if (req->numPdus > 0) {
|
||||
if (req->ul_dci_pdu_list[req->numPdus-1].PDUType == 0) { // copy only the last PDU (PHY can have only one UL PDCCH pdu)
|
||||
msgTx->ul_pdcch_pdu = req->ul_dci_pdu_list[req->numPdus-1]; // copy the last pdu
|
||||
}
|
||||
else {
|
||||
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), req->numPdus-1, req->ul_dci_pdu_list[req->numPdus-1].PDUType);
|
||||
for (int i=0; i<req->numPdus; i++) {
|
||||
if (req->ul_dci_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) // only possible value 0: PDCCH PDU
|
||||
msgTx->ul_pdcch_pdu[i] = req->ul_dci_pdu_list[i];
|
||||
else
|
||||
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), req->numPdus-1, req->ul_dci_pdu_list[req->numPdus-1].PDUType);
|
||||
}
|
||||
}
|
||||
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,res);
|
||||
pushNotifiedFIFO(gNB->L1_tx_filled,res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1238,8 +1207,7 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
|
||||
if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) {
|
||||
// we trust the scheduler sends only one PDCCH PDU per slot
|
||||
msgTx->pdcch_pdu = dl_tti_pdu_list[i].pdcch_pdu; // fills the last received PDCCH PDU
|
||||
msgTx->pdcch_pdu[i] = dl_tti_pdu_list[i].pdcch_pdu; // copies all the received PDCCH PDUs
|
||||
}
|
||||
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) {
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]);
|
||||
@@ -1269,7 +1237,7 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
|
||||
else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
|
||||
}
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,res);
|
||||
pushNotifiedFIFO(gNB->L1_tx_filled,res);
|
||||
}
|
||||
|
||||
if(req->vendor_extension)
|
||||
|
||||
@@ -353,6 +353,8 @@ typedef struct {
|
||||
} fapi_nr_ul_config_request_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
//uint16_t sfn;
|
||||
//uint16_t slot;
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint8_t number_pdus;
|
||||
|
||||
@@ -1402,9 +1402,6 @@ typedef struct
|
||||
} nfapi_nr_ul_dci_request_t;
|
||||
*/
|
||||
|
||||
// normally one PDU per coreset per BWP
|
||||
#define NFAPI_NR_MAX_UL_DCI_PDUS 4
|
||||
|
||||
typedef struct {
|
||||
/// only possible value 0: PDCCH PDU
|
||||
uint16_t PDUType;
|
||||
@@ -1418,7 +1415,7 @@ typedef struct {
|
||||
uint16_t SFN;
|
||||
uint16_t Slot;
|
||||
uint8_t numPdus;
|
||||
nfapi_nr_ul_dci_request_pdus_t ul_dci_pdu_list[NFAPI_NR_MAX_UL_DCI_PDUS];
|
||||
nfapi_nr_ul_dci_request_pdus_t ul_dci_pdu_list[NFAPI_NR_MAX_NB_CORESETS];
|
||||
} nfapi_nr_ul_dci_request_t;
|
||||
|
||||
//3.4.5 slot_errors
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include <openair1/PHY/MODULATION/nr_modulation.h>
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
|
||||
#if 0
|
||||
void phy_config_harq_ue(module_id_t Mod_id,
|
||||
|
||||
@@ -254,20 +254,16 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
void nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *ul_dci_pdu,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
processingData_L1tx_t *msgTx,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
|
||||
AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
|
||||
for (int i=0; i<msgTx->num_ul_pdcch; i++)
|
||||
nr_generate_dci(gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
for (int i=0; i<msgTx->num_dl_pdcch; i++)
|
||||
nr_generate_dci(gNB,&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
|
||||
if (pdcch_pdu) {
|
||||
nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
}
|
||||
if (ul_dci_pdu) {
|
||||
nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,11 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
|
||||
uint16_t N_RB);
|
||||
|
||||
void nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *ul_pdcch_pdu,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
processingData_L1tx_t *msgTx,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
void nr_pdcch_scrambling(uint32_t *in,
|
||||
uint32_t size,
|
||||
|
||||
@@ -294,8 +294,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
||||
uint32_t A = rel15->TBSize[0]<<3;
|
||||
|
||||
if ( dlsch->rnti != SI_RNTI )
|
||||
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, dlsch->rnti, frame, slot,0, 0);
|
||||
if ( rel15->rnti != SI_RNTI)
|
||||
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
|
||||
|
||||
NR_gNB_SCH_STATS_t *stats=NULL;
|
||||
int first_free=-1;
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#define ScaleZone 4
|
||||
#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
|
||||
|
||||
int otg_enabled;
|
||||
|
||||
const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
|
||||
const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
|
||||
|
||||
+10
-5
@@ -594,6 +594,8 @@ typedef struct gNB_L1_proc_t_s {
|
||||
pthread_t L1_stats_thread;
|
||||
/// pthread structure for printing time meas
|
||||
pthread_t process_stats_thread;
|
||||
/// pthread structure for reordering L1 tx thread messages
|
||||
pthread_t pthread_tx_reorder;
|
||||
/// flag to indicate first RX acquisition
|
||||
int first_rx;
|
||||
/// flag to indicate first TX transmission
|
||||
@@ -844,8 +846,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/*
|
||||
time_stats_t phy_proc;
|
||||
*/
|
||||
time_stats_t *phy_proc_tx_0;
|
||||
time_stats_t *phy_proc_tx_1;
|
||||
time_stats_t *phy_proc_tx[2];
|
||||
time_stats_t phy_proc_rx;
|
||||
time_stats_t rx_prach;
|
||||
/*
|
||||
@@ -886,7 +887,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
*/
|
||||
notifiedFIFO_t *respDecode;
|
||||
notifiedFIFO_t *resp_L1;
|
||||
notifiedFIFO_t *resp_L1_tx;
|
||||
notifiedFIFO_t *L1_tx_free;
|
||||
notifiedFIFO_t *L1_tx_filled;
|
||||
notifiedFIFO_t *L1_tx_out;
|
||||
notifiedFIFO_t *resp_RU_tx;
|
||||
tpool_t *threadPool;
|
||||
int nbDecode;
|
||||
@@ -951,12 +954,14 @@ typedef struct processingData_L1tx {
|
||||
int slot;
|
||||
openair0_timestamp timestamp_tx;
|
||||
PHY_VARS_gNB *gNB;
|
||||
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu;
|
||||
nfapi_nr_ul_dci_request_pdus_t ul_pdcch_pdu;
|
||||
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS];
|
||||
nfapi_nr_ul_dci_request_pdus_t ul_pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS];
|
||||
NR_gNB_CSIRS_t csirs_pdu[NUMBER_OF_NR_CSIRS_MAX];
|
||||
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2];
|
||||
NR_gNB_SSB_t ssb[64];
|
||||
uint16_t num_pdsch_slot;
|
||||
int num_dl_pdcch;
|
||||
int num_ul_pdcch;
|
||||
time_stats_t phy_proc_tx;
|
||||
} processingData_L1tx_t;
|
||||
|
||||
|
||||
@@ -82,8 +82,7 @@ const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812,
|
||||
{ -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
|
||||
};
|
||||
|
||||
//int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
|
||||
const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 27};
|
||||
const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
|
||||
|
||||
//for SNR to MI conversion 7 th order Polynomial coeff
|
||||
const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
|
||||
|
||||
@@ -83,9 +83,6 @@ const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812,
|
||||
{ -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
|
||||
};
|
||||
|
||||
//int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
|
||||
const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 27};
|
||||
|
||||
//for SNR to MI conversion 7 th order Polynomial coeff
|
||||
const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
|
||||
const double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
|
||||
|
||||
@@ -72,8 +72,7 @@ const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812,
|
||||
{ -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
|
||||
};
|
||||
|
||||
//int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
|
||||
const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 27};
|
||||
const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
|
||||
|
||||
//for SNR to MI conversion 7 th order Polynomial coeff
|
||||
const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
|
||||
|
||||
@@ -148,6 +148,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
AssertFatal(RC.gNB[Mod_id]!=NULL,"RC.gNB[%d] is null\n",Mod_id);
|
||||
|
||||
gNB = RC.gNB[Mod_id];
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
|
||||
int slot_type = nr_slot_select(cfg,frame,slot);
|
||||
|
||||
uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs;
|
||||
uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus;
|
||||
@@ -155,63 +158,57 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs;
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC){
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
if (DL_req != NULL && TX_req!=NULL && (number_dl_pdu > 0 || number_ul_dci_pdu > 0 || number_ul_tti_pdu > 0))
|
||||
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
|
||||
frame,slot,
|
||||
DL_req->SFN,DL_req->Slot,number_dl_pdu,
|
||||
TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
|
||||
number_ul_dci_pdu,number_ul_tti_pdu);
|
||||
|
||||
int pdcch_received=0;
|
||||
msgTx->num_pdsch_slot=0;
|
||||
msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
|
||||
msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
|
||||
msgTx->slot = slot;
|
||||
msgTx->frame = frame;
|
||||
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = pullTpool(gNB->L1_tx_free, gNB->threadPool);
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
|
||||
for (int i=0;i<number_dl_pdu;i++) {
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
|
||||
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
|
||||
switch (dl_tti_pdu->PDUType) {
|
||||
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
|
||||
handle_nr_nfapi_ssb_pdu(msgTx,frame,slot,
|
||||
dl_tti_pdu);
|
||||
break;
|
||||
msgTx->num_pdsch_slot=0;
|
||||
msgTx->num_dl_pdcch=0;
|
||||
msgTx->num_ul_pdcch=number_ul_dci_pdu;
|
||||
msgTx->slot = slot;
|
||||
msgTx->frame = frame;
|
||||
|
||||
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
|
||||
AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n");
|
||||
msgTx->pdcch_pdu = dl_tti_pdu->pdcch_pdu;
|
||||
for (int i=0;i<number_dl_pdu;i++) {
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
|
||||
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
|
||||
switch (dl_tti_pdu->PDUType) {
|
||||
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
|
||||
handle_nr_nfapi_ssb_pdu(msgTx,frame,slot,
|
||||
dl_tti_pdu);
|
||||
break;
|
||||
|
||||
pdcch_received = 1;
|
||||
break;
|
||||
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
|
||||
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
|
||||
msgTx->pdcch_pdu[msgTx->num_dl_pdcch] = dl_tti_pdu->pdcch_pdu;
|
||||
msgTx->num_dl_pdcch++;
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
|
||||
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
|
||||
handle_nfapi_nr_csirs_pdu(msgTx,frame,slot,
|
||||
&dl_tti_pdu->csi_rs_pdu);
|
||||
break;
|
||||
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
|
||||
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
|
||||
handle_nfapi_nr_csirs_pdu(msgTx,frame,slot,&dl_tti_pdu->csi_rs_pdu);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
|
||||
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
|
||||
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
|
||||
pduIndex,TX_req->pdu_list[pduIndex].num_TLV);
|
||||
uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct;
|
||||
AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n",
|
||||
msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max);
|
||||
handle_nr_nfapi_pdsch_pdu(msgTx,&dl_tti_pdu->pdsch_pdu, sdu);
|
||||
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
|
||||
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
|
||||
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
|
||||
pduIndex,TX_req->pdu_list[pduIndex].num_TLV);
|
||||
uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct;
|
||||
AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n",
|
||||
msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max);
|
||||
handle_nr_nfapi_pdsch_pdu(msgTx,&dl_tti_pdu->pdsch_pdu, sdu);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<number_ul_dci_pdu; i++)
|
||||
msgTx->ul_pdcch_pdu[i] = UL_dci_req->ul_dci_pdu_list[i];
|
||||
|
||||
pushNotifiedFIFO(gNB->L1_tx_filled,res);
|
||||
}
|
||||
|
||||
if (number_ul_dci_pdu > 0)
|
||||
msgTx->ul_pdcch_pdu = UL_dci_req->ul_dci_pdu_list[number_ul_dci_pdu-1]; // copy the last pdu
|
||||
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,res);
|
||||
|
||||
for (int i = 0; i < number_ul_tti_pdu; i++) {
|
||||
switch (UL_tti_req->pdus_list[i].pdu_type) {
|
||||
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
|
||||
|
||||
@@ -128,6 +128,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
int frame,
|
||||
int slot,
|
||||
int do_meas) {
|
||||
|
||||
int aa;
|
||||
PHY_VARS_gNB *gNB = msgTx->gNB;
|
||||
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
@@ -158,18 +159,16 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
|
||||
|
||||
int num_dl_dci = msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci;
|
||||
int num_ul_dci = msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci;
|
||||
int num_pdcch_pdus = msgTx->num_ul_pdcch + msgTx->num_dl_pdcch;
|
||||
|
||||
if (num_dl_dci > 0 || num_ul_dci > 0) {
|
||||
LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n",
|
||||
gNB->Mod_id, frame, slot, num_ul_dci, num_dl_dci);
|
||||
if (num_pdcch_pdus > 0) {
|
||||
LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL PDCCH PDUs %d/%d)\n",
|
||||
gNB->Mod_id, frame, slot, msgTx->num_ul_pdcch, msgTx->num_dl_pdcch);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
|
||||
|
||||
nr_generate_dci_top(gNB,
|
||||
num_dl_dci > 0 ? &msgTx->pdcch_pdu : NULL,
|
||||
num_ul_dci > 0 ? &msgTx->ul_pdcch_pdu.pdcch_pdu : NULL,
|
||||
msgTx,
|
||||
gNB->nr_gold_pdcch_dmrs[slot],
|
||||
&gNB->common_vars.txdataF[0][txdataF_offset],
|
||||
AMP, fp);
|
||||
@@ -204,6 +203,8 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
|
||||
//pthread_mutex_unlock(&mutextest);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -421,6 +421,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Clear the fields when all the config pdu are done
|
||||
if (pdu_done == ul_config->number_pdus) {
|
||||
if (scheduled_response->tx_request)
|
||||
@@ -431,6 +432,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
LOG_D(PHY, "%d.%d clear ul_config %p\n", scheduled_response->frame, slot, ul_config);
|
||||
memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ul_config->mutex_ul_config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -980,18 +980,21 @@ int main(int argc, char **argv)
|
||||
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
initTpool(gNBthreads, gNB->threadPool, true);
|
||||
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->resp_L1_tx);
|
||||
gNB->L1_tx_free = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
gNB->L1_tx_filled = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
gNB->L1_tx_out = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->L1_tx_free);
|
||||
initNotifiedFIFO(gNB->L1_tx_filled);
|
||||
initNotifiedFIFO(gNB->L1_tx_out);
|
||||
// we create 2 threads for L1 tx processing
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,processSlotTX);
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_free,processSlotTX);
|
||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
init_DLSCH_struct(gNB, msgDataTx);
|
||||
msgDataTx->slot = slot;
|
||||
msgDataTx->frame = frame;
|
||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||
reset_meas(&msgDataTx->phy_proc_tx);
|
||||
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
|
||||
pushTpool(gNB->threadPool,msgL1Tx);
|
||||
gNB->phy_proc_tx[0] = &msgDataTx->phy_proc_tx;
|
||||
|
||||
for (SNR = snr0; SNR < snr1; SNR += .2) {
|
||||
|
||||
@@ -1046,8 +1049,6 @@ int main(int argc, char **argv)
|
||||
|
||||
while ((round<num_rounds) && (UE_harq_process->ack==0)) {
|
||||
|
||||
memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
|
||||
memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
|
||||
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
|
||||
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
@@ -1055,7 +1056,7 @@ int main(int argc, char **argv)
|
||||
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
gNB_mac->UE_info.num_pdcch_cand[0][i] = 0;
|
||||
gNB_mac->pdcch_cand[i] = 0;
|
||||
|
||||
if (css_flag == 0) {
|
||||
nr_schedule_ue_spec(0, frame, slot);
|
||||
@@ -1070,6 +1071,7 @@ int main(int argc, char **argv)
|
||||
Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[slot];
|
||||
Sched_INFO.UL_dci_req = NULL;
|
||||
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
|
||||
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx);
|
||||
nr_schedule_response(&Sched_INFO);
|
||||
|
||||
/* PTRS values for DLSIM calculations */
|
||||
@@ -1303,10 +1305,10 @@ int main(int argc, char **argv)
|
||||
printf("\n");
|
||||
|
||||
if (print_perf==1) {
|
||||
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d)\n",
|
||||
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, block %d)\n",
|
||||
1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex,
|
||||
msgDataTx->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3);
|
||||
printDistribution(gNB->phy_proc_tx_0,table_tx,"PHY proc tx");
|
||||
printDistribution(gNB->phy_proc_tx[0],table_tx,"PHY proc tx");
|
||||
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
|
||||
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
|
||||
printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
|
||||
|
||||
@@ -670,13 +670,16 @@ int main(int argc, char **argv)
|
||||
char tp_param[] = "n";
|
||||
initTpool(tp_param, gNB->threadPool, false);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->resp_L1_tx);
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,NULL);
|
||||
gNB->L1_tx_free = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
gNB->L1_tx_filled = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
gNB->L1_tx_out = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->L1_tx_free);
|
||||
initNotifiedFIFO(gNB->L1_tx_filled);
|
||||
initNotifiedFIFO(gNB->L1_tx_out);
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_free,NULL);
|
||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
msgDataTx->slot = -1;
|
||||
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
|
||||
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
|
||||
gNB->phy_proc_tx[0] = &msgDataTx->phy_proc_tx;
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
|
||||
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
@@ -1118,6 +1121,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// prepare ULSCH/PUSCH reception
|
||||
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
|
||||
nr_schedule_response(Sched_INFO);
|
||||
|
||||
// --------- setting parameters for UE --------
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:4, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_OFDM_OFFSET_DIVISOR, NULL, 0, uptr:NULL, defuintval:8, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \
|
||||
|
||||
@@ -73,6 +73,8 @@ void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, in
|
||||
memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list));
|
||||
}
|
||||
ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type;
|
||||
//ul_config->slot = slot_tx;
|
||||
//ul_config->sfn = frame_tx;
|
||||
ul_config->slot = slot_tx;
|
||||
ul_config->sfn = frame_tx;
|
||||
ul_config->number_pdus++;
|
||||
@@ -971,6 +973,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES];
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
fapi_nr_tx_request_t tx_req;
|
||||
//tx_req.slot = slot_tx;
|
||||
//tx_req.sfn = frame_tx;
|
||||
tx_req.slot = slot_tx;
|
||||
tx_req.sfn = frame_tx;
|
||||
tx_req.number_of_pdus = 0;
|
||||
|
||||
@@ -536,7 +536,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
if (CellGroup) {
|
||||
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
|
||||
|
||||
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
|
||||
if(bwpList) {
|
||||
AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
|
||||
@@ -607,6 +606,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
ra->msg3_dcch_dtch = false;
|
||||
LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti);
|
||||
} else { // CellGroup has been updated
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon;
|
||||
const int UE_id = find_nr_UE_id(Mod_idP,rnti);
|
||||
int target_ss;
|
||||
UE_info->CellGroup[UE_id] = CellGroup;
|
||||
@@ -627,19 +627,30 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
}
|
||||
// update coreset/searchspace
|
||||
void *bwpd = NULL;
|
||||
NR_BWP_t *genericParameters = NULL;
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
||||
if ((sched_ctrl->active_bwp)) {
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
bwpd = (void*)sched_ctrl->active_bwp->bwp_Dedicated;
|
||||
genericParameters = &sched_ctrl->active_bwp->bwp_Common->genericParameters;
|
||||
}
|
||||
else if (CellGroup->spCellConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
(CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) {
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
bwpd = (void*)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP;
|
||||
genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Either initial BWP or active BWP should always be present\n");
|
||||
sched_ctrl->search_space = get_searchspace(scc, bwpd, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(Mod_idP, scc, bwpd, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP],
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
sched_ctrl->maxL = 2;
|
||||
if (CellGroup->spCellConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
|
||||
@@ -67,7 +67,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***)gNB->pdcch_pdu_idx[CC_idP];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP];
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
|
||||
&gNB->UL_tti_req_ahead[CC_idP][(slotP + num_slots - 1) % num_slots];
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0];
|
||||
@@ -80,7 +80,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
DL_req[CC_idP].dl_tti_request_body.nPDUs = 0;
|
||||
DL_req[CC_idP].dl_tti_request_body.nGroup = 0;
|
||||
//DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich = 6000;
|
||||
memset(pdcch, 0, sizeof(**pdcch) * MAX_NUM_BWP * MAX_NUM_CORESET);
|
||||
memset(pdcch, 0, sizeof(*pdcch) * MAX_NUM_CORESET);
|
||||
|
||||
UL_dci_req[CC_idP].SFN = frameP;
|
||||
UL_dci_req[CC_idP].Slot = slotP;
|
||||
@@ -272,11 +272,11 @@ bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot){
|
||||
//pthread_mutex_lock(&mutextest);
|
||||
|
||||
protocol_ctxt_t ctxt={0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
|
||||
|
||||
const int bwp_id = 1;
|
||||
char stats_output[16384];
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
@@ -307,13 +307,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||
}
|
||||
|
||||
memset(RC.nrmac[module_idP]->cce_list[0][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
|
||||
memset(RC.nrmac[module_idP]->cce_list[0][1],0,MAX_NUM_CCE*sizeof(int)); // coreset1 on initialBWP
|
||||
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id])
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
UE_info->num_pdcch_cand[UE_id][i] = 0;
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
RC.nrmac[module_idP]->pdcch_cand[i] = 0;
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
//mbsfn_status[CC_id] = 0;
|
||||
|
||||
|
||||
@@ -587,12 +587,15 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
|
||||
NR_SearchSpaceId_t ra_SearchSpace = 0;
|
||||
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL;
|
||||
NR_BWP_t *genericParameters = NULL;
|
||||
if(bwp) {
|
||||
commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
|
||||
ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
|
||||
genericParameters = &bwp->bwp_Common->genericParameters;
|
||||
} else {
|
||||
commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
|
||||
ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
|
||||
genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
}
|
||||
AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n");
|
||||
|
||||
@@ -605,6 +608,14 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
|
||||
AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n");
|
||||
|
||||
ra->coreset = get_coreset(module_idP, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
ra->sched_pdcch = set_pdcch_structure(nr_mac,
|
||||
ra->ra_ss,
|
||||
ra->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
|
||||
// retrieving ra pdcch monitoring period and offset
|
||||
find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
|
||||
|
||||
@@ -781,13 +792,13 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
|
||||
// generation of DCI 0_0 to schedule msg3 retransmission
|
||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(module_idP, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
NR_ControlResourceSet_t *coreset = ra->coreset;
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n");
|
||||
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id];
|
||||
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu_rel15) {
|
||||
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
|
||||
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
|
||||
@@ -795,8 +806,8 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
uint8_t aggregation_level;
|
||||
@@ -807,7 +818,13 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
int CCEIndex = allocate_nr_CCEs(nr_mac, NULL, coreset, aggregation_level, 0, 0, nr_of_candidates);
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
CC_id,
|
||||
aggregation_level,
|
||||
nr_of_candidates,
|
||||
&ra->sched_pdcch,
|
||||
coreset,
|
||||
0);
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti);
|
||||
return;
|
||||
@@ -848,6 +865,13 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
ra->bwp_id);
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
CC_id,
|
||||
&ra->sched_pdcch,
|
||||
CCEIndex,
|
||||
aggregation_level);
|
||||
|
||||
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
|
||||
vrb_map_UL[rbStart + BWPStart + rb] = 1;
|
||||
}
|
||||
@@ -1165,13 +1189,19 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
BWPSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
}
|
||||
|
||||
coreset = get_coreset(module_idP, scc, bwp, ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
// Calculate number of symbols
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
|
||||
|
||||
coreset = ra->coreset;
|
||||
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg2\n");
|
||||
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
|
||||
if (vrb_map[BWPStart + rbStart + i]) {
|
||||
if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(startSymbolIndex, nrOfSymbols)) {
|
||||
rbStart += i;
|
||||
i = 0;
|
||||
}
|
||||
@@ -1197,18 +1227,20 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
CC_id,
|
||||
aggregation_level,
|
||||
nr_of_candidates,
|
||||
&ra->sched_pdcch,
|
||||
coreset,
|
||||
0);
|
||||
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate number of symbols
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
|
||||
|
||||
LOG_D(NR_MAC,"Msg2 startSymbolIndex.nrOfSymbols %d.%d\n",startSymbolIndex,nrOfSymbols);
|
||||
|
||||
int mappingtype = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
|
||||
@@ -1217,7 +1249,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
// important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
|
||||
const int bwpid = bwp ? bwp->bwp_Id : 0;
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu_rel15) {
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
@@ -1225,8 +1257,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
@@ -1385,9 +1417,14 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
nr_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
// Mark the corresponding symbols RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
CC_id,
|
||||
&ra->sched_pdcch,
|
||||
CCEIndex,
|
||||
aggregation_level);
|
||||
for (int rb = 0; rb < rbSize; rb++) {
|
||||
vrb_map[BWPStart + rb + rbStart] = 1;
|
||||
vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
}
|
||||
|
||||
ra->state = WAIT_Msg3;
|
||||
@@ -1424,7 +1461,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
}
|
||||
|
||||
coreset = get_coreset(module_idP, scc, bwp, ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
coreset = ra->coreset;
|
||||
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n");
|
||||
|
||||
@@ -1481,7 +1518,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
CC_id,
|
||||
aggregation_level,
|
||||
nr_of_candidates,
|
||||
&ra->sched_pdcch,
|
||||
coreset,
|
||||
0);
|
||||
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti);
|
||||
return;
|
||||
@@ -1596,7 +1641,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
AssertFatal(mcsIndex<10,"Cannot fit Msg4 in %d PRBs with QPSK\n",(int)BWPSize);
|
||||
int i = 0;
|
||||
while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) {
|
||||
if (vrb_map[BWPStart + rbStart + i]) {
|
||||
if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(startSymbolIndex, nrOfSymbols)) {
|
||||
rbStart += i+1;
|
||||
i = 0;
|
||||
} else {
|
||||
@@ -1621,7 +1666,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
// important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
|
||||
const int bwpid = bwp ? bwp->bwp_Id : 0;
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu_rel15) {
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
@@ -1629,8 +1674,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
@@ -1770,9 +1815,14 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
nr_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
// Mark the corresponding symbols and RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
CC_id,
|
||||
&ra->sched_pdcch,
|
||||
CCEIndex,
|
||||
aggregation_level);
|
||||
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
|
||||
vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] |= SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
|
||||
|
||||
@@ -314,7 +314,7 @@ void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
|
||||
for (int rb = 0; rb < 20; rb++)
|
||||
vrb_map[rbStart + rb] = 15<<symStart;
|
||||
vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4);
|
||||
|
||||
}
|
||||
|
||||
@@ -329,7 +329,9 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
int num_total_bytes) {
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
uint16_t *vrb_map = cc->vrb_map;
|
||||
|
||||
if (gNB_mac->sched_ctrlCommon == NULL){
|
||||
LOG_D(NR_MAC,"schedule_control_common: Filling nr_mac->sched_ctrlCommon\n");
|
||||
@@ -340,6 +342,12 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset,type0_PDCCH_CSS_config);
|
||||
gNB_mac->cset0_bwp_start = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
gNB_mac->cset0_bwp_size = type0_PDCCH_CSS_config->num_rbs;
|
||||
gNB_mac->sched_ctrlCommon->sched_pdcch = set_pdcch_structure(NULL,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
scc,
|
||||
NULL,
|
||||
type0_PDCCH_CSS_config);
|
||||
}
|
||||
|
||||
gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation;
|
||||
@@ -354,13 +362,13 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
if (nr_of_candidates>0) break; // choosing the lower value of aggregation level available
|
||||
}
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
gNB_mac->sched_ctrlCommon->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
NULL,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
0,
|
||||
candidate_idx,
|
||||
nr_of_candidates);
|
||||
gNB_mac->sched_ctrlCommon->cce_index = find_pdcch_candidate(gNB_mac,
|
||||
CC_id,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdcch,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
0);
|
||||
|
||||
AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
|
||||
|
||||
@@ -383,7 +391,7 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
int rbSize = 0;
|
||||
uint32_t TBS = 0;
|
||||
do {
|
||||
if(rbSize < bwpSize && !vrb_map[rbStart + rbSize])
|
||||
if(rbSize < bwpSize && !(vrb_map[rbStart + rbSize]&SL_to_bitmap(startSymbolIndex, nrOfSymbols)))
|
||||
rbSize++;
|
||||
else{
|
||||
if (gNB_mac->sched_ctrlCommon->sched_pdsch.mcs<10)
|
||||
@@ -410,16 +418,21 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
LOG_D(NR_MAC,"dmrs_length %d\n",dmrs_length);
|
||||
LOG_D(NR_MAC,"N_PRB_DMRS = %d\n",N_PRB_DMRS);
|
||||
LOG_D(NR_MAC,"mappingtype = %d\n", mappingtype);
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
fill_pdcch_vrb_map(gNB_mac,
|
||||
CC_id,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdcch,
|
||||
gNB_mac->sched_ctrlCommon->cce_index,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level);
|
||||
for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; rb++) {
|
||||
vrb_map[rb + rbStart] = 1;
|
||||
vrb_map[rb + rbStart] = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
}
|
||||
return TBS;
|
||||
}
|
||||
|
||||
void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
int pdu_index,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
uint32_t TBS,
|
||||
int StartSymbolIndex,
|
||||
@@ -436,13 +449,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(NULL,
|
||||
pdcch_pdu_rel15,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
nr_configure_pdcch(pdcch_pdu_rel15,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
scc,
|
||||
NULL,
|
||||
type0_PDCCH_CSS_config);
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdcch);
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
@@ -455,7 +465,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
pdsch_pdu_rel15->rnti = SI_RNTI;
|
||||
pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
|
||||
pdsch_pdu_rel15->pduIndex = pdu_index;
|
||||
|
||||
pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
@@ -623,7 +633,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
candidate_idx, sib1_sdu_length);
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols, dlDmrsSymbPos);
|
||||
int pdu_index = gNB_mac->pdu_index[0]++;
|
||||
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols, dlDmrsSymbPos);
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
@@ -633,7 +644,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
|
||||
|
||||
tx_req->PDU_length = TBS;
|
||||
tx_req->PDU_index = gNB_mac->pdu_index[0]++;
|
||||
tx_req->PDU_index = pdu_index;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
|
||||
@@ -531,7 +531,7 @@ void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
bool allocate_dl_retransmission(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
uint8_t *rballoc_mask,
|
||||
uint16_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
int UE_id,
|
||||
int current_harq_pid) {
|
||||
@@ -561,13 +561,16 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
while (rbSize < retInfo->rbSize) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart])
|
||||
while (rbStart < bwpSize &&
|
||||
!(rballoc_mask[rbStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)))
|
||||
rbStart++;
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
|
||||
return false;
|
||||
}
|
||||
while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && rbSize < retInfo->rbSize)
|
||||
while (rbStart + rbSize < bwpSize &&
|
||||
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) &&
|
||||
rbSize < retInfo->rbSize)
|
||||
rbSize++;
|
||||
}
|
||||
/* check whether we need to switch the TDA allocation since the last
|
||||
@@ -577,12 +580,14 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart])
|
||||
rbStart++;
|
||||
while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize])
|
||||
rbSize++;
|
||||
NR_pdsch_semi_static_t temp_ps = *ps;
|
||||
nr_set_pdsch_semi_static(scc, cg, sched_ctrl->active_bwp, bwpd,tda, ps->nrOfLayers, sched_ctrl, &temp_ps);
|
||||
while (rbStart < bwpSize &&
|
||||
!(rballoc_mask[rbStart]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
||||
rbStart++;
|
||||
while (rbStart + rbSize < bwpSize &&
|
||||
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
||||
rbSize++;
|
||||
uint32_t new_tbs;
|
||||
uint16_t new_rbSize;
|
||||
bool success = nr_find_nb_rb(retInfo->Qm,
|
||||
@@ -607,8 +612,27 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
}
|
||||
|
||||
/* Find a free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
/* CC_id = */ 0,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n",
|
||||
frame, slot, UE_id, UE_info->rnti[UE_id]);
|
||||
return false;
|
||||
@@ -625,14 +649,18 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
UE_info->rnti[UE_id],
|
||||
frame,
|
||||
slot);
|
||||
int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
UE_info->num_pdcch_cand[UE_id][cid]--;
|
||||
int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp?sched_ctrl->active_bwp->bwp_Id:0][cid];
|
||||
for (int i = 0; i < sched_ctrl->aggregation_level; i++)
|
||||
cce_list[sched_ctrl->cce_index + i] = 0;
|
||||
RC.nrmac[module_id]->pdcch_cand[cid]--;
|
||||
return false;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* just reuse from previous scheduling opportunity, set new start RB */
|
||||
sched_ctrl->sched_pdsch = *retInfo;
|
||||
sched_ctrl->sched_pdsch.rbStart = rbStart;
|
||||
@@ -642,7 +670,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
/* retransmissions: directly allocate */
|
||||
*n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] = 0;
|
||||
rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] -= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -655,7 +683,7 @@ void pf_dl(module_id_t module_id,
|
||||
NR_list_t *UE_list,
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint8_t *rballoc_mask) {
|
||||
uint16_t *rballoc_mask) {
|
||||
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
NR_UE_info_t *UE_info = &mac->UE_info;
|
||||
@@ -745,7 +773,6 @@ void pf_dl(module_id_t module_id,
|
||||
NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
int bwp_Id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
@@ -760,8 +787,27 @@ void pf_dl(module_id_t module_id,
|
||||
}
|
||||
|
||||
/* Find a free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(mac,
|
||||
/* CC_id = */ 0,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
|
||||
continue;
|
||||
}
|
||||
@@ -780,20 +826,17 @@ void pf_dl(module_id_t module_id,
|
||||
rnti,
|
||||
frame,
|
||||
slot);
|
||||
int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
UE_info->num_pdcch_cand[UE_id][cid]--;
|
||||
int *cce_list = mac->cce_list[bwp_Id][cid];
|
||||
for (int i = 0; i < sched_ctrl->aggregation_level; i++)
|
||||
cce_list[sched_ctrl->cce_index + i] = 0;
|
||||
mac->pdcch_cand[cid]--;
|
||||
return;
|
||||
}
|
||||
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
uint16_t max_rbSize = 1;
|
||||
while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
|
||||
max_rbSize++;
|
||||
fill_pdcch_vrb_map(mac,
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* MCS has been set above */
|
||||
|
||||
@@ -804,6 +847,18 @@ void pf_dl(module_id_t module_id,
|
||||
if (ps->nrOfLayers != layers[UE_id] ||
|
||||
ps->time_domain_allocation != tda)
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, layers[UE_id], sched_ctrl, ps);
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize &&
|
||||
!(rballoc_mask[rbStart]&slbitmap))
|
||||
rbStart++;
|
||||
|
||||
uint16_t max_rbSize = 1;
|
||||
while (rbStart + max_rbSize < bwpSize &&
|
||||
(rballoc_mask[rbStart + max_rbSize]&slbitmap))
|
||||
max_rbSize++;
|
||||
|
||||
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
@@ -826,7 +881,7 @@ void pf_dl(module_id_t module_id,
|
||||
/* transmissions: directly allocate */
|
||||
n_rb_sched -= sched_pdsch->rbSize;
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] = 0;
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] -= slbitmap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -839,9 +894,18 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
const int CC_id = 0;
|
||||
|
||||
/* Get bwpSize from the first UE */
|
||||
/* Get bwpSize and TDAfrom the first UE */
|
||||
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
||||
int UE_id = UE_info->list.head;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
@@ -852,14 +916,18 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
uint8_t rballoc_mask[bwpSize];
|
||||
uint16_t rballoc_mask[bwpSize];
|
||||
int n_rb_sched = 0;
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
// calculate mask: init with "NOT" vrb_map:
|
||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||
rballoc_mask[i] = !vrb_map[i+BWPStart];
|
||||
n_rb_sched += rballoc_mask[i];
|
||||
rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols
|
||||
// if all the pdsch symbols are free
|
||||
if((rballoc_mask[i]&slbitmap) ==
|
||||
slbitmap)
|
||||
n_rb_sched++;
|
||||
}
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
@@ -1014,7 +1082,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
const int bwpid = bwp ? bwp->bwp_Id : 0;
|
||||
const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu) {
|
||||
LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
@@ -1024,10 +1092,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %d, bwp %d, cs %d\n",UE_id,bwpid,coresetid);
|
||||
NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space:gNB_mac->sched_ctrlCommon->search_space;
|
||||
NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset;
|
||||
nr_configure_pdcch(gNB_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu;
|
||||
nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch);
|
||||
gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
|
||||
@@ -278,6 +278,12 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
__func__,
|
||||
UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
ps->nrOfLayers = target_dl_Nl;
|
||||
if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
|
||||
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
@@ -289,11 +295,14 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
/* loop ensures that we allocate exactly target_dl_bw, or return */
|
||||
while (true) {
|
||||
/* advance to first free RB */
|
||||
while (rbStart < bwpSize && vrb_map[rbStart + BWPStart])
|
||||
while (rbStart < bwpSize &&
|
||||
(vrb_map[rbStart + BWPStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)))
|
||||
rbStart++;
|
||||
rbSize = 1;
|
||||
/* iterate until we are at target_dl_bw or no available RBs */
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize + BWPStart] && rbSize < target_dl_bw)
|
||||
while (rbStart + rbSize < bwpSize &&
|
||||
!(vrb_map[rbStart + rbSize + BWPStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) &&
|
||||
rbSize < target_dl_bw)
|
||||
rbSize++;
|
||||
/* found target_dl_bw? */
|
||||
if (rbSize == target_dl_bw)
|
||||
@@ -334,16 +343,17 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
AssertFatal(sched_ctrl->cce_index >= 0,
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
AssertFatal(CCEIndex >= 0,
|
||||
"%s(): could not find CCE for UE %d\n",
|
||||
__func__,
|
||||
UE_id);
|
||||
@@ -357,24 +367,26 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
rnti,
|
||||
frame,
|
||||
slot);
|
||||
UE_info->num_pdcch_cand[UE_id][cid]--;
|
||||
int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid];
|
||||
for (int i = 0; i < sched_ctrl->aggregation_level; i++)
|
||||
cce_list[sched_ctrl->cce_index + i] = 0;
|
||||
RC.nrmac[module_id]->pdcch_cand[cid]--;
|
||||
return;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
//AssertFatal(alloc,
|
||||
// "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
|
||||
// rnti, frame, slot);
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
sched_pdsch->rbStart = rbStart;
|
||||
sched_pdsch->rbSize = rbSize;
|
||||
const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
|
||||
|
||||
if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
|
||||
|
||||
@@ -396,7 +408,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
vrb_map[rb + sched_pdsch->rbStart + BWPStart] = 1;
|
||||
vrb_map[rb + sched_pdsch->rbStart + BWPStart] = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
|
||||
if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
|
||||
}
|
||||
@@ -499,20 +511,21 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
nr_mac->pdcch_cand[cid]--;
|
||||
return false;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
const int mcs = target_ul_mcs;
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
@@ -541,6 +554,12 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
>> 3;
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
|
||||
vrb_map_UL[rb+BWPStart] = 1;
|
||||
return true;
|
||||
|
||||
@@ -232,6 +232,7 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_SearchSpace__searchSpaceType_PR ss_type) {
|
||||
NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId;
|
||||
|
||||
if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
if(coreset_id == 0) {
|
||||
@@ -281,53 +282,181 @@ NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
|
||||
AssertFatal(0, "Couldn't find an adequate searchspace bwp_Dedicated %p\n",bwp_Dedicated);
|
||||
}
|
||||
|
||||
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
int aggregation,
|
||||
uint16_t Y,
|
||||
int m,
|
||||
int nr_of_candidates) {
|
||||
NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_t *bwp,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) {
|
||||
|
||||
int coreset_id = coreset->controlResourceSetId;
|
||||
int sps;
|
||||
NR_sched_pdcch_t pdcch;
|
||||
|
||||
int *cce_list;
|
||||
if(bwp == NULL) {
|
||||
cce_list = nr_mac->cce_list[0][coreset_id];
|
||||
} else {
|
||||
cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
|
||||
AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId,
|
||||
"coreset id in SS %ld does not correspond to the one in coreset %ld",
|
||||
*ss->controlResourceSetId, coreset->controlResourceSetId);
|
||||
|
||||
if (bwp) { // This is not for SIB1
|
||||
if(coreset->controlResourceSetId == 0){
|
||||
pdcch.BWPSize = gNB_mac->cset0_bwp_size;
|
||||
pdcch.BWPStart = gNB_mac->cset0_bwp_start;
|
||||
}
|
||||
else {
|
||||
pdcch.BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdcch.BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
}
|
||||
pdcch.SubcarrierSpacing = bwp->subcarrierSpacing;
|
||||
pdcch.CyclicPrefix = (bwp->cyclicPrefix==NULL) ? 0 : *bwp->cyclicPrefix;
|
||||
|
||||
//AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
|
||||
sps = bwp->cyclicPrefix == NULL ? 14 : 12;
|
||||
}
|
||||
else {
|
||||
AssertFatal(type0_PDCCH_CSS_config!=NULL,"type0_PDCCH_CSS_config is null,bwp %p\n",bwp);
|
||||
pdcch.BWPSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
pdcch.BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
pdcch.SubcarrierSpacing = type0_PDCCH_CSS_config->scs_pdcch;
|
||||
pdcch.CyclicPrefix = 0;
|
||||
sps = 14;
|
||||
}
|
||||
|
||||
int n_rb=0;
|
||||
for (int i=0;i<6;i++)
|
||||
for (int j=0;j<8;j++) {
|
||||
n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1);
|
||||
AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
|
||||
AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
|
||||
|
||||
// for SPS=14 8 MSBs in positions 13 downto 6
|
||||
uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
|
||||
(ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
|
||||
|
||||
for (int i=0; i<sps; i++) {
|
||||
if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
|
||||
pdcch.StartSymbolIndex=i;
|
||||
break;
|
||||
}
|
||||
n_rb*=6;
|
||||
}
|
||||
|
||||
uint16_t N_reg = n_rb * coreset->duration;
|
||||
uint16_t n_CI = 0;
|
||||
pdcch.DurationSymbols = coreset->duration;
|
||||
|
||||
const uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE;
|
||||
const uint16_t M_s_max = nr_of_candidates;
|
||||
//cce-REG-MappingType
|
||||
pdcch.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
|
||||
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED;
|
||||
|
||||
LOG_D(PHY,"allocate_NR_CCes : bwp_id %d, coreset_id %d : N_cce %d, m %d, nr_of_candidates %d, Y %d\n",
|
||||
(int)(bwp ? bwp->bwp_Id : 0),coreset_id,N_cce,m,nr_of_candidates, Y);
|
||||
//PDCCH candidate index m in CORESET exceeds the maximum number of PDCCH candidates
|
||||
if(m >= nr_of_candidates)
|
||||
return -1;
|
||||
if (pdcch.CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
pdcch.RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize ==
|
||||
NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
|
||||
pdcch.InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize ==
|
||||
NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize);
|
||||
AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n");
|
||||
pdcch.ShiftIndex = coreset->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
|
||||
}
|
||||
else {
|
||||
pdcch.RegBundleSize = 6;
|
||||
pdcch.InterleaverSize = 0;
|
||||
pdcch.ShiftIndex = 0;
|
||||
}
|
||||
|
||||
int first_cce = aggregation * (( Y + CEILIDIV((m*N_cce),(aggregation*M_s_max)) + n_CI ) % CEILIDIV(N_cce,aggregation));
|
||||
|
||||
for (int i=0;i<aggregation;i++)
|
||||
if (cce_list[first_cce+i] != 0) return(-1);
|
||||
|
||||
for (int i=0;i<aggregation;i++) cce_list[first_cce+i] = 1;
|
||||
|
||||
return(first_cce);
|
||||
int N_rb = 0; // nb of rbs of coreset per symbol
|
||||
for (int i=0;i<6;i++) {
|
||||
for (int t=0;t<8;t++) {
|
||||
N_rb+=((coreset->frequencyDomainResources.buf[i]>>t)&1);
|
||||
}
|
||||
}
|
||||
pdcch.n_rb = N_rb*=6; // each bit of frequencyDomainResources represents 6 PRBs
|
||||
|
||||
return pdcch;
|
||||
}
|
||||
|
||||
|
||||
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs) {
|
||||
|
||||
int f; // interleaving function
|
||||
if(R==0)
|
||||
f = k;
|
||||
else {
|
||||
int c = k/R;
|
||||
int r = k%R;
|
||||
f = (r*C + c + n_shift)%(N_regs/L);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
uint8_t find_pdcch_candidate(gNB_MAC_INST *mac,
|
||||
int cc_id,
|
||||
int aggregation,
|
||||
int nr_of_candidates,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
uint16_t Y){
|
||||
|
||||
uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map;
|
||||
const int next_cand = mac->pdcch_cand[coreset->controlResourceSetId];
|
||||
const int N_ci = 0;
|
||||
|
||||
if(next_cand>=nr_of_candidates) {
|
||||
LOG_D(NR_MAC,"No more available candidates for this coreset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol
|
||||
const int N_symb = coreset->duration; // nb of coreset symbols
|
||||
const int N_regs = N_rb*N_symb; // nb of REGs per coreset
|
||||
const int N_cces = N_regs / NR_NB_REG_PER_CCE; // nb of cces in coreset
|
||||
const int R = pdcch->InterleaverSize;
|
||||
const int L = pdcch->RegBundleSize;
|
||||
const int C = R>0 ? N_regs/(L*R) : 0;
|
||||
const int B_rb = L/N_symb; // nb of RBs occupied by each REG bundle
|
||||
|
||||
int first_cce;
|
||||
bool taken = false; // flag if the resource for a given candidate are taken
|
||||
// loop over all the available candidates
|
||||
// this implements TS 38.211 Sec. 7.3.2.2
|
||||
for(int m=next_cand; m<nr_of_candidates; m++) { // loop over candidates
|
||||
first_cce = aggregation * (( Y + CEILIDIV((m*N_cces),(aggregation*nr_of_candidates)) + N_ci ) % CEILIDIV(N_cces,aggregation));
|
||||
for (int j=first_cce; (j<first_cce+aggregation) && !taken; j++) { // loop over CCEs
|
||||
for (int k=6*j/L; (k<(6*j/L+6/L)) && !taken; k++) { // loop over REG bundles
|
||||
int f = cce_to_reg_interleaving(R, k, pdcch->ShiftIndex, C, L, N_regs);
|
||||
for(int rb=0; rb<B_rb; rb++) { // loop over the RBs of the bundle
|
||||
if(vrb_map[pdcch->BWPStart + f*B_rb + rb]&SL_to_bitmap(pdcch->StartSymbolIndex,N_symb)) {
|
||||
taken = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!taken){
|
||||
mac->pdcch_cand[coreset->controlResourceSetId] = m++; // using candidate m, next available is m+1
|
||||
return first_cce;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fill_pdcch_vrb_map(gNB_MAC_INST *mac,
|
||||
int CC_id,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
int first_cce,
|
||||
int aggregation){
|
||||
|
||||
uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map;
|
||||
|
||||
int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol
|
||||
int L = pdcch->RegBundleSize;
|
||||
int R = pdcch->InterleaverSize;
|
||||
int n_shift = pdcch->ShiftIndex;
|
||||
int N_symb = pdcch->DurationSymbols;
|
||||
int N_regs = N_rb*N_symb; // nb of REGs per coreset
|
||||
int B_rb = L/N_symb; // nb of RBs occupied by each REG bundle
|
||||
int C = R>0 ? N_regs/(L*R) : 0;
|
||||
|
||||
for (int j=first_cce; j<first_cce+aggregation; j++) { // loop over CCEs
|
||||
for (int k=6*j/L; k<(6*j/L+6/L); k++) { // loop over REG bundles
|
||||
int f = cce_to_reg_interleaving(R, k, n_shift, C, L, N_regs);
|
||||
for(int rb=0; rb<B_rb; rb++) // loop over the RBs of the bundle
|
||||
vrb_map[pdcch->BWPStart + f*B_rb + rb] |= SL_to_bitmap(pdcch->StartSymbolIndex, N_symb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool nr_find_nb_rb(uint16_t Qm,
|
||||
uint16_t R,
|
||||
uint8_t nrOfLayers,
|
||||
@@ -836,81 +965,32 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
|
||||
return(default_pucch_csset[pucch_ResourceCommon]);
|
||||
}
|
||||
|
||||
void nr_configure_pdcch(gNB_MAC_INST *gNB_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_SearchSpace_t *ss,
|
||||
|
||||
|
||||
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_t *bwp,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) {
|
||||
NR_sched_pdcch_t *pdcch) {
|
||||
|
||||
int sps;
|
||||
AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId,
|
||||
"coreset id in SS %ld does not correspond to the one in coreset %ld",
|
||||
*ss->controlResourceSetId, coreset->controlResourceSetId);
|
||||
|
||||
if (bwp) { // This is not for SIB1
|
||||
if(coreset->controlResourceSetId == 0){
|
||||
pdcch_pdu->BWPSize = gNB_mac->cset0_bwp_size;
|
||||
pdcch_pdu->BWPStart = gNB_mac->cset0_bwp_start;
|
||||
}
|
||||
else {
|
||||
pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
}
|
||||
pdcch_pdu->SubcarrierSpacing = bwp->subcarrierSpacing;
|
||||
pdcch_pdu->CyclicPrefix = (bwp->cyclicPrefix==NULL) ? 0 : *bwp->cyclicPrefix;
|
||||
|
||||
//AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
|
||||
sps = bwp->cyclicPrefix == NULL ? 14 : 12;
|
||||
}
|
||||
else {
|
||||
AssertFatal(type0_PDCCH_CSS_config!=NULL,"type0_PDCCH_CSS_config is null,bwp %p\n",bwp);
|
||||
pdcch_pdu->BWPSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
pdcch_pdu->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
pdcch_pdu->SubcarrierSpacing = type0_PDCCH_CSS_config->scs_pdcch;
|
||||
pdcch_pdu->CyclicPrefix = 0;
|
||||
sps = 14;
|
||||
}
|
||||
|
||||
AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
|
||||
AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
|
||||
|
||||
// for SPS=14 8 MSBs in positions 13 downto 6
|
||||
uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
|
||||
(ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
|
||||
|
||||
for (int i=0; i<sps; i++) {
|
||||
if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
|
||||
pdcch_pdu->StartSymbolIndex=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pdcch_pdu->BWPSize = pdcch->BWPSize;
|
||||
pdcch_pdu->BWPStart = pdcch->BWPStart;
|
||||
pdcch_pdu->SubcarrierSpacing = pdcch->SubcarrierSpacing;
|
||||
pdcch_pdu->CyclicPrefix = pdcch->CyclicPrefix;
|
||||
pdcch_pdu->StartSymbolIndex = pdcch->StartSymbolIndex;
|
||||
|
||||
pdcch_pdu->DurationSymbols = coreset->duration;
|
||||
|
||||
for (int i=0;i<6;i++)
|
||||
pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i];
|
||||
|
||||
LOG_D(MAC,"Coreset : BWPstart %d, BWPsize %d, SCS %d, freq %x, , duration %d, \n",pdcch_pdu->BWPStart,pdcch_pdu->BWPSize,(int)pdcch_pdu->SubcarrierSpacing,(int)coreset->frequencyDomainResources.buf[0],(int)coreset->duration);
|
||||
LOG_D(MAC,"Coreset : BWPstart %d, BWPsize %d, SCS %d, freq %x, , duration %d, \n",
|
||||
pdcch_pdu->BWPStart,pdcch_pdu->BWPSize,(int)pdcch_pdu->SubcarrierSpacing,(int)coreset->frequencyDomainResources.buf[0],(int)coreset->duration);
|
||||
|
||||
//cce-REG-MappingType
|
||||
pdcch_pdu->CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
|
||||
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED;
|
||||
|
||||
if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
pdcch_pdu->RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize ==
|
||||
NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
|
||||
pdcch_pdu->InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize ==
|
||||
NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize);
|
||||
AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n");
|
||||
pdcch_pdu->ShiftIndex = coreset->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
|
||||
}
|
||||
else {
|
||||
pdcch_pdu->RegBundleSize = 0;
|
||||
pdcch_pdu->InterleaverSize = 0;
|
||||
pdcch_pdu->ShiftIndex = 0;
|
||||
}
|
||||
pdcch_pdu->CceRegMappingType = pdcch->CceRegMappingType;
|
||||
pdcch_pdu->RegBundleSize = pdcch->RegBundleSize;
|
||||
pdcch_pdu->InterleaverSize = pdcch->InterleaverSize;
|
||||
pdcch_pdu->ShiftIndex = pdcch->ShiftIndex;
|
||||
|
||||
if(coreset->controlResourceSetId == 0) {
|
||||
if(bwp == NULL)
|
||||
@@ -1962,19 +2042,18 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_Y(int Y[3][160], rnti_t rnti) {
|
||||
uint16_t get_Y(int cid, int slot, rnti_t rnti) {
|
||||
|
||||
const int A[3] = {39827, 39829, 39839};
|
||||
const int D = 65537;
|
||||
int Y;
|
||||
|
||||
Y[0][0] = (A[0] * rnti) % D;
|
||||
Y[1][0] = (A[1] * rnti) % D;
|
||||
Y[2][0] = (A[2] * rnti) % D;
|
||||
Y = (A[cid] * rnti) % D;
|
||||
|
||||
for (int s = 1; s < 160; s++) {
|
||||
Y[0][s] = (A[0] * Y[0][s - 1]) % D;
|
||||
Y[1][s] = (A[1] * Y[1][s - 1]) % D;
|
||||
Y[2][s] = (A[2] * Y[2][s - 1]) % D;
|
||||
}
|
||||
for (int s = 0; s < slot; s++)
|
||||
Y = (A[cid] * Y) % D;
|
||||
|
||||
return Y;
|
||||
}
|
||||
|
||||
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) {
|
||||
@@ -2058,7 +2137,6 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
UE_info->CellGroup[UE_id] = CellGroup;
|
||||
add_nr_list(&UE_info->list, UE_id);
|
||||
memset(&UE_info->mac_stats[UE_id], 0, sizeof(NR_mac_stats_t));
|
||||
set_Y(UE_info->Y[UE_id], rntiP);
|
||||
if (CellGroup &&
|
||||
CellGroup->spCellConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
@@ -2090,8 +2168,12 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
if (bwpList) AssertFatal(bwpList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
|
||||
const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0;
|
||||
sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
|
||||
sched_ctrl->search_space = get_searchspace(scc,
|
||||
sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
@@ -2099,6 +2181,12 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
sched_ctrl->coreset = get_coreset(mod_idP, scc,
|
||||
sched_ctrl->active_bwp ? (void*)sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[mod_idP],
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
|
||||
if (ubwpList) AssertFatal(ubwpList->list.count == 1,
|
||||
"uplinkBWP_ToAddModList has %d BWP!\n",
|
||||
@@ -2350,7 +2438,6 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
int period, offset;
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
NR_BWP_Downlink_t *bwp=sched_ctrl->active_bwp;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&gNB_mac->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
@@ -2400,20 +2487,20 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
csirs_pdu_rel15->row = 1;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
|
||||
csirs_pdu_rel15->row = 2;
|
||||
csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
|
||||
((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<8)&0xff0));
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
|
||||
csirs_pdu_rel15->row = 4;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
|
||||
@@ -2424,18 +2511,18 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
|
||||
csirs_pdu_rel15->row = 3;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
|
||||
csirs_pdu_rel15->row = 5;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 8;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
}
|
||||
else{
|
||||
int num_k = 0;
|
||||
@@ -2444,12 +2531,12 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if(num_k==4) {
|
||||
csirs_pdu_rel15->row = 6;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 7;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2457,12 +2544,12 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 10;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 9;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
}
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
|
||||
@@ -2471,24 +2558,24 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
else
|
||||
csirs_pdu_rel15->row = 11;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 14;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
}
|
||||
else{
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 15;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 13;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2496,18 +2583,18 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 17;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
}
|
||||
else{
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 18;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 16;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2525,38 +2612,6 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
bool find_free_CCE(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
int UE_id){
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id];
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = RC.nrmac[module_id]->UE_info.Y[UE_id][cid][slot];
|
||||
const int m = RC.nrmac[module_id]->UE_info.num_pdcch_cand[UE_id][cid];
|
||||
if (UE_id >= 0) LOG_D(NR_MAC,"calling allocate_nr_CCEs with L %d, nr_of_candidates %d, Y %x\n",sched_ctrl->aggregation_level,nr_of_candidates,Y);
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (sched_ctrl->cce_index < 0)
|
||||
return false;
|
||||
|
||||
RC.nrmac[module_id]->UE_info.num_pdcch_cand[UE_id][cid]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg,
|
||||
nfapi_nr_coreset_t *coreset,
|
||||
|
||||
@@ -701,7 +701,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
const NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
|
||||
AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0,
|
||||
"NO CSI report configuration available");
|
||||
NR_PUCCH_Config_t *pucch_Config;
|
||||
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||
if (sched_ctrl->active_ubwp) {
|
||||
pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
} else if (RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id] &&
|
||||
@@ -736,7 +736,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource)
|
||||
break;
|
||||
AssertFatal(res_index < n,
|
||||
"CSI pucch resource %d not found among PUCCH resources\n",pucchcsires->pucch_Resource);
|
||||
"CSI pucch resource %ld not found among PUCCH resources\n",pucchcsires->pucch_Resource);
|
||||
|
||||
// find free PUCCH that is in order with possibly existing PUCCH
|
||||
// schedulings (other CSI, SR)
|
||||
|
||||
@@ -1014,13 +1014,38 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
sched_ctrl->sched_pusch = *retInfo;
|
||||
}
|
||||
|
||||
/* Find free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
return false;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* frame/slot in sched_pusch has been set previously. In the following, we
|
||||
* overwrite the information in the retransmission information before storing
|
||||
* as the new scheduling instruction */
|
||||
@@ -1135,8 +1160,27 @@ void pf_ul(module_id_t module_id,
|
||||
* based on data to transmit) */
|
||||
if (B == 0 && do_sched) {
|
||||
/* if no data, pre-allocate 5RB */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
continue;
|
||||
}
|
||||
@@ -1153,6 +1197,13 @@ void pf_ul(module_id_t module_id,
|
||||
return;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* Save PUSCH field */
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
* every TTI if we can save it, so check whether dci_format, TDA, or
|
||||
@@ -1218,8 +1269,27 @@ void pf_ul(module_id_t module_id,
|
||||
*max = UE_sched.next[*max];
|
||||
*p = -1;
|
||||
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
continue;
|
||||
}
|
||||
@@ -1230,7 +1300,6 @@ void pf_ul(module_id_t module_id,
|
||||
if (max_num_ue < 0)
|
||||
return;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
@@ -1285,6 +1354,14 @@ void pf_ul(module_id_t module_id,
|
||||
rbSize, max_rbSize,sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B,sched_ctrl->cce_index,ps->num_dmrs_symb,ps->N_PRB_DMRS);
|
||||
|
||||
/* Mark the corresponding RBs as used */
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
n_rb_sched -= sched_pusch->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
|
||||
@@ -1441,10 +1518,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req = &RC.nrmac[module_id]->UL_dci_req[CC_id];
|
||||
ul_dci_req->SFN = frame;
|
||||
ul_dci_req->Slot = slot;
|
||||
/* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each
|
||||
* allocated PDCCH so we can easily allocate UE's DCIs independent of any
|
||||
* CORESET order */
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {{0}};
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
@@ -1683,7 +1756,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
NR_SearchSpace_t *ss = (sched_ctrl->active_bwp || ubwpd) ? sched_ctrl->search_space: RC.nrmac[module_id]->sched_ctrlCommon->search_space;
|
||||
NR_ControlResourceSet_t *coreset = (sched_ctrl->active_bwp || ubwpd) ? sched_ctrl->coreset: RC.nrmac[module_id]->sched_ctrlCommon->coreset;
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = pdcch_pdu_bwp_coreset[bwpid][coresetid];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu) {
|
||||
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
|
||||
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
|
||||
@@ -1691,8 +1764,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
pdcch_pdu_bwp_coreset[bwpid][coresetid] = pdcch_pdu;
|
||||
nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,"Configuring ULDCI/PDCCH in %d.%d at CCE %d, rnti %x\n", frame,slot,sched_ctrl->cce_index,rnti);
|
||||
|
||||
@@ -248,13 +248,31 @@ void find_search_space(int ss_type,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
void nr_configure_pdcch(gNB_MAC_INST *gNB_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_SearchSpace_t *ss,
|
||||
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_t *bwp,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config);
|
||||
NR_sched_pdcch_t *pdcch);
|
||||
|
||||
NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_t *bwp,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config);
|
||||
|
||||
uint8_t find_pdcch_candidate(gNB_MAC_INST *mac,
|
||||
int cc_id,
|
||||
int aggregation,
|
||||
int nr_of_candidates,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
uint16_t Y);
|
||||
|
||||
void fill_pdcch_vrb_map(gNB_MAC_INST *mac,
|
||||
int CC_id,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
int first_cce,
|
||||
int aggregation);
|
||||
|
||||
void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_CellGroupConfig_t *CellGroup,
|
||||
@@ -301,6 +319,8 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
uint8_t num_dmrs_cdm_grps_no_data,
|
||||
NR_pusch_semi_static_t *ps);
|
||||
|
||||
uint16_t get_Y(int cid, int slot, rnti_t rnti);
|
||||
|
||||
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
|
||||
|
||||
int get_spf(nfapi_nr_config_request_scf_t *cfg);
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
/* Defs */
|
||||
#define MAX_NUM_BWP 2
|
||||
#define MAX_NUM_CORESET 2
|
||||
#define MAX_NUM_CORESET 12
|
||||
#define MAX_NUM_CCE 90
|
||||
#define MAX_HARQ_ROUNDS 4
|
||||
/*!\brief Maximum number of random access process */
|
||||
@@ -103,6 +103,20 @@ typedef struct NR_preamble_ue {
|
||||
uint8_t *preamble_list;
|
||||
} NR_preamble_ue_t;
|
||||
|
||||
typedef struct NR_sched_pdcch {
|
||||
uint16_t BWPSize;
|
||||
uint16_t BWPStart;
|
||||
uint8_t CyclicPrefix;
|
||||
uint8_t SubcarrierSpacing;
|
||||
uint8_t StartSymbolIndex;
|
||||
uint8_t CceRegMappingType;
|
||||
uint8_t RegBundleSize;
|
||||
uint8_t InterleaverSize;
|
||||
uint16_t ShiftIndex;
|
||||
uint8_t DurationSymbols;
|
||||
int n_rb;
|
||||
} NR_sched_pdcch_t;
|
||||
|
||||
/*! \brief gNB template for the Random access information */
|
||||
typedef struct {
|
||||
/// Flag to indicate this process is active
|
||||
@@ -165,6 +179,9 @@ typedef struct {
|
||||
int mac_pdu_length;
|
||||
/// RA search space
|
||||
NR_SearchSpace_t *ra_ss;
|
||||
/// RA Coreset
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
NR_sched_pdcch_t sched_pdcch;
|
||||
// Beam index
|
||||
uint8_t beam_id;
|
||||
/// CellGroup for UE that is to come (NSA is non-null, null for SA)
|
||||
@@ -300,7 +317,6 @@ typedef struct UE_info {
|
||||
pdschTciStatesActDeact_t pdsch_TCI_States_ActDeact;
|
||||
} NR_UE_mac_ce_ctrl_t;
|
||||
|
||||
|
||||
typedef struct NR_sched_pucch {
|
||||
int frame;
|
||||
int ul_slot;
|
||||
@@ -535,6 +551,7 @@ typedef struct {
|
||||
/// CCE index and aggregation, should be coherent with cce_list
|
||||
NR_SearchSpace_t *search_space;
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
NR_sched_pdcch_t sched_pdcch;
|
||||
|
||||
/// CCE index and Aggr. Level are shared for PUSCH/PDSCH allocation decisions
|
||||
/// corresponding to the sched_pusch/sched_pdsch structures below
|
||||
@@ -651,12 +668,11 @@ typedef struct {
|
||||
rnti_t rnti[MAX_MOBILES_PER_GNB];
|
||||
NR_CellGroupConfig_t *CellGroup[MAX_MOBILES_PER_GNB];
|
||||
/// CCE indexing
|
||||
int Y[MAX_MOBILES_PER_GNB][3][160];
|
||||
int m[MAX_MOBILES_PER_GNB];
|
||||
int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET];
|
||||
// UE selected beam index
|
||||
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
|
||||
bool Msg4_ACKed[MAX_MOBILES_PER_GNB];
|
||||
|
||||
} NR_UE_info_t;
|
||||
|
||||
typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
|
||||
@@ -704,7 +720,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
/// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure
|
||||
/// keeps pointers to PDCCH PDUs within DL_req so that we can easily track
|
||||
/// PDCCH PDUs per CC/BWP/CORESET
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_BWP][MAX_NUM_CORESET];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_CORESET];
|
||||
/// NFAPI UL TTI Request Structure, simple pointer into structure
|
||||
/// UL_tti_req_ahead for current frame/slot
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX];
|
||||
@@ -715,7 +731,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX];
|
||||
/// NFAPI DL PDU structure
|
||||
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
|
||||
|
||||
int pdcch_cand[MAX_NUM_CORESET];
|
||||
NR_UE_info_t UE_info;
|
||||
|
||||
/// UL handle
|
||||
@@ -743,8 +759,6 @@ typedef struct gNB_MAC_INST_s {
|
||||
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
|
||||
/// processing time of eNB PCH scheduler
|
||||
time_stats_t schedule_pch;
|
||||
/// CCE lists
|
||||
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
|
||||
/// list of allocated beams per period
|
||||
int16_t *tdd_beam_association;
|
||||
|
||||
|
||||
@@ -4293,7 +4293,7 @@ ssize_t do_nrMeasurementReport(uint8_t *buffer,
|
||||
LTE_MeasResultListEUTRA_t *measResultListEUTRA2=&measResultNeighCells->choice.measResultListEUTRA;
|
||||
asn1cSequenceAdd(measResultListEUTRA2->list, struct LTE_MeasResultEUTRA, measresulteutra_list);
|
||||
measresulteutra_list->physCellId = phy_id;
|
||||
asn1cCalloc(measresulteutra_list->cgi_Info, measresult_cgi2);
|
||||
//asn1cCalloc(measresulteutra_list->cgi_Info, measresult_cgi2);
|
||||
//measresult_cgi2->cellGlobalId= {0};
|
||||
//measresult_cgi2->trackingAreaCode= {0};
|
||||
struct LTE_MeasResultEUTRA__measResult* measResult= &measresulteutra_list->measResult;
|
||||
|
||||
@@ -213,7 +213,7 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
pusch_proc_threads = 2;
|
||||
pusch_proc_threads = 8;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user