diff --git a/CMakeLists.txt b/CMakeLists.txt index 57d165ea05..8f8a6006bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -652,7 +652,6 @@ add_library(SCHED_LIB ${SCHED_SRC}) target_link_libraries(SCHED_LIB PRIVATE asn1_lte_rrc_hdrs) set(SCHED_NR_SRC - ${OPENAIR1_DIR}/SCHED_NR/fapi_nr_l1.c ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_gNB.c ${OPENAIR1_DIR}/SCHED_NR/nr_prach_procedures.c ${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c @@ -939,7 +938,6 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c - ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c @@ -1215,7 +1213,6 @@ set (MAC_SRC set (MAC_NR_SRC ${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c - ${NR_PHY_INTERFACE_DIR}/nr_sched_response.c ${NR_GNB_MAC_DIR}/main.c ${NR_GNB_MAC_DIR}/config.c ${NR_GNB_MAC_DIR}/gNB_scheduler.c @@ -1283,12 +1280,6 @@ set (MISC_NFAPI_LTE add_library(MISC_NFAPI_LTE_LIB ${MISC_NFAPI_LTE}) -set (MISC_NFAPI_NR - ${OPENAIR1_DIR}/SCHED/nfapi_nr_dummy.c - ) - -add_library(MISC_NFAPI_NR_LIB ${MISC_NFAPI_NR}) - add_library(L2 ${L2_SRC} ${MAC_SRC} @@ -2091,7 +2082,7 @@ if (${T_TRACER}) oai_eth_transpro HASHTABLE UTIL SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB - MISC_NFAPI_LTE_LIB MISC_NFAPI_NR_LIB + MISC_NFAPI_LTE_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_UE_NR ngap GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE SIMU diff --git a/ci-scripts/datalog_rt_stats.100.2x2.yaml b/ci-scripts/datalog_rt_stats.100.2x2.yaml index 7c5cb48add..360ba57402 100644 --- a/ci-scripts/datalog_rt_stats.100.2x2.yaml +++ b/ci-scripts/datalog_rt_stats.100.2x2.yaml @@ -15,7 +15,6 @@ Ref : DLSCH encoding : 200.0 L1 Rx processing : 530.0 PUSCH inner-receiver : 360.0 - Schedule Response : 1.0 DL & UL scheduling timing : 17.0 UL Indication : 1.0 Slot Indication : 13.0 @@ -31,7 +30,6 @@ DeviationThreshold : DLSCH encoding : 0.25 L1 Rx processing : 0.25 PUSCH inner-receiver : 0.25 - Schedule Response : 1.00 DL & UL scheduling timing : 0.25 UL Indication : 1.00 Slot Indication : 0.50 diff --git a/ci-scripts/datalog_rt_stats.1x1.60.yaml b/ci-scripts/datalog_rt_stats.1x1.60.yaml index 5e0564977b..b418b74940 100644 --- a/ci-scripts/datalog_rt_stats.1x1.60.yaml +++ b/ci-scripts/datalog_rt_stats.1x1.60.yaml @@ -15,7 +15,6 @@ Ref : DLSCH encoding : 110.0 L1 Rx processing : 345.0 PUSCH inner-receiver : 150.0 - Schedule Response : 1.0 DL & UL scheduling timing : 5.0 UL Indication : 1.0 Slot Indication : 6.0 @@ -31,7 +30,6 @@ DeviationThreshold : DLSCH encoding : 0.25 L1 Rx processing : 0.25 PUSCH inner-receiver : 0.25 - Schedule Response : 1.00 DL & UL scheduling timing : 0.50 UL Indication : 1.00 Slot Indication : 0.50 diff --git a/ci-scripts/datalog_rt_stats.2x2.yaml b/ci-scripts/datalog_rt_stats.2x2.yaml index 7d489c171e..25009bad10 100644 --- a/ci-scripts/datalog_rt_stats.2x2.yaml +++ b/ci-scripts/datalog_rt_stats.2x2.yaml @@ -15,7 +15,6 @@ Ref : DLSCH encoding : 230.0 L1 Rx processing : 175.0 PUSCH inner-receiver : 100.0 - Schedule Response : 3.0 DL & UL scheduling timing : 11.0 UL Indication : 3.0 Slot Indication : 14.0 @@ -28,7 +27,6 @@ DeviationThreshold : DLSCH encoding : 0.25 L1 Rx processing : 0.25 PUSCH inner-receiver : 0.25 - Schedule Response : 1.00 DL & UL scheduling timing : 0.50 UL Indication : 1.00 Slot Indication : 0.25 diff --git a/ci-scripts/datalog_rt_stats.60.2x2.yaml b/ci-scripts/datalog_rt_stats.60.2x2.yaml index 7352136764..6df6fded54 100644 --- a/ci-scripts/datalog_rt_stats.60.2x2.yaml +++ b/ci-scripts/datalog_rt_stats.60.2x2.yaml @@ -15,7 +15,6 @@ Ref : DLSCH encoding : 140.0 L1 Rx processing : 345.0 PUSCH inner-receiver : 155.0 - Schedule Response : 1.0 DL & UL scheduling timing : 8.0 UL Indication : 3.0 Slot Indication : 9.0 @@ -31,7 +30,6 @@ DeviationThreshold : DLSCH encoding : 0.25 L1 Rx processing : 0.25 PUSCH inner-receiver : 0.25 - Schedule Response : 1.00 DL & UL scheduling timing : 0.35 UL Indication : 1.00 Slot Indication : 0.35 diff --git a/ci-scripts/datalog_rt_stats.default.yaml b/ci-scripts/datalog_rt_stats.default.yaml index be3f8b277e..65fd678b0f 100644 --- a/ci-scripts/datalog_rt_stats.default.yaml +++ b/ci-scripts/datalog_rt_stats.default.yaml @@ -15,7 +15,6 @@ Ref : DLSCH encoding : 90.0 L1 Rx processing : 290.0 PUSCH inner-receiver : 115.0 - Schedule Response : 1.0 DL & UL scheduling timing : 4.0 UL Indication : 2.0 Slot Indication : 5.0 @@ -31,7 +30,6 @@ DeviationThreshold : DLSCH encoding : 0.25 L1 Rx processing : 0.25 PUSCH inner-receiver : 0.25 - Schedule Response : 1.00 DL & UL scheduling timing : 0.50 UL Indication : 1.00 Slot Indication : 0.50 diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 53fc42837b..a842f66443 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -575,8 +575,8 @@ int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, return f; } -void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { - +void get_coreset_rballoc(const uint8_t *FreqDomainResource, int *n_rb, int *rb_offset) +{ uint8_t count=0, start=0, start_set=0; uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)| @@ -599,7 +599,7 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { } // According to 38.211 7.3.2.2 -int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration) +int get_coreset_num_cces(const uint8_t *FreqDomainResource, int duration) { int num_rbs; int rb_offset; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 2e796bac23..52eb305824 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -280,8 +280,8 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, ui int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); -void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); -int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration); +void get_coreset_rballoc(const uint8_t *FreqDomainResource, int *n_rb, int *rb_offset); +int get_coreset_num_cces(const uint8_t *FreqDomainResource, int duration); int get_nr_table_idx(int nr_bandP, uint8_t scs_index); int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); diff --git a/doc/Doxyfile b/doc/Doxyfile index 5f96bc2e4a..85cb5776c0 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1916,8 +1916,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/E1AP/e1ap_api.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/E1AP/e1ap_setup.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/E1AP/e1ap_asnc.h \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/nr_sched_response.h \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/nr_sched_response.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/NR_IF_Module.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/NR_IF_Module.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/SDAP/nr_sdap/nr_sdap.h \ @@ -2012,7 +2010,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_sss.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_prach.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_scrambling.c \ @@ -2294,10 +2291,8 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/phy_frame_config_nr.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/phy_frame_config_nr.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/nr_prach_procedures.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/fapi_nr_l1.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/phy_procedures_nr_gNB.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/sched_nr.h \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/fapi_nr_l1.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/nr_ru_procedures.c \ @CMAKE_CURRENT_SOURCE_DIR@/../radio/ETHERNET/if_defs.h \ @CMAKE_CURRENT_SOURCE_DIR@/../radio/ETHERNET/ethernet_lib.h \ diff --git a/doc/NR_NFAPI_archi.md b/doc/NR_NFAPI_archi.md index 8065ddb4fc..8e6647f73c 100644 --- a/doc/NR_NFAPI_archi.md +++ b/doc/NR_NFAPI_archi.md @@ -161,9 +161,9 @@ unpack function is called. ## P7 DL Transmission by VNF DL messages are scheduled at the VNF, through gNB_dlsch_ulsch_scheduler(). gNB_dlsch_ulsch_scheduler() is called when -handling a SLOT.indication message in trigger_scheduler(). +handling a SLOT.indication message in phy_nr_slot_indication(). -The function trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind) calls the functions oai_nfapi_[DL P7 msg]_ +The function phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *slot_ind) calls the functions oai_nfapi_[DL P7 msg]_ req(), calling in turn call the send_p7_msg function pointer, which contain the logic to pack the message into a buffer and send it to the PNF. Finally, NR_UL_indication is called to process the other P7 messages received from the PNF that were put in theire @@ -215,7 +215,7 @@ bool nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_re graph TD softmodem_start[nr-softmodem init] --> P5_configuration[configure_nr_nfapi_vnf] --> transport_init[Transport mechanism init] --> send_first_msg[Send first P5 message to PNF] transport_init[Transport mechanism init] --> P5_recv_loop[P5 receive loop] -- P5 Message processing --> P5_recv_loop[P5 receive loop] - P5_recv_loop[P5 receive loop] -- Start.response callback called --> P7_config[P7 Configuration] --> P7_loop[P7 Loop] --> P7_msg_recv[P7 message received] --> call_vnf_handle_p7[Call vnf_nr_handle_p7_msg] --> hdr_unpack[Unpack header] --> call_specific_p7_handler[Call specific P7 message handler] --> slot_ind[Is a SLOT.indication?] -- Yes --> trig_scheduler[Call trigger_scheduler] --> gNB_ulsch_dlsch_sched[Call gNB_dlsch_ulsch_scheduler] --> send_p7_dl[Process and send P7 messages to PNF] --> call_ul_ind[Call NR_UL_indication] --> proc_p7[Process P7 messages in queue] --> P7_loop[P7 Loop] + P5_recv_loop[P5 receive loop] -- Start.response callback called --> P7_config[P7 Configuration] --> P7_loop[P7 Loop] --> P7_msg_recv[P7 message received] --> call_vnf_handle_p7[Call vnf_nr_handle_p7_msg] --> hdr_unpack[Unpack header] --> call_specific_p7_handler[Call specific P7 message handler] --> slot_ind[Is a SLOT.indication?] -- Yes --> trig_scheduler[Call phy_nr_slot_indication] --> gNB_ulsch_dlsch_sched[Call gNB_dlsch_ulsch_scheduler] --> send_p7_dl[Process and send P7 messages to PNF] --> call_ul_ind[Call NR_UL_indication] --> proc_p7[Process P7 messages in queue] --> P7_loop[P7 Loop] slot_ind[Is a SLOT.indication?] -- No --> put_queue[Put message in queue] --> P7_loop[P7 Loop]; diff --git a/doc/SW-archi-graph.md b/doc/SW-archi-graph.md index cf826e6e43..467ce5cd04 100644 --- a/doc/SW-archi-graph.md +++ b/doc/SW-archi-graph.md @@ -1,74 +1,97 @@ +This document is a high-level overview over the L1 threading mechanism. + ```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_RX - 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 - --> 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_schedule_rx_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_TX - -- 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 - + ru_thread --> RFin[block rx_rf] --> UL{is UL slot?} + UL -- yes --> wait_free_rx_tti --> fep_rx --> rx_nr_prach_ru --> msg:L1_tx_out + UL -- no --> msg:L1_tx_out + msg:L1_tx_out -- asnyc launch --> L1_tx_thread + msg:L1_tx_out --> RFin ``` + +The main thread is `ru_thread()`. It blocks on reception of radio samples +(either time domain or frequency domain). In the case of an UL slot, it waits +that no more than N UL jobs are scheduled (via `wait_free_rx_tti()`, which +waits on queue `L1_rx_out`, cf. the RX L1 processing further below). Then: + +- if the radio is time domain-based, it performs RX front-end processing (RX + FEP -> `fep_rx()`, i.e. DFT) to reach a frequency domain representation of + the RX signal, as well as does DFT for PRACH. +- if the radio is frequency domain-based, nothing is done. + +Afterwards, it triggers TX processing by pushing a message into the FIFO queue +`L1_tx_out`, which asynchronously starts a TX job in `L1_tx_thread()` (see +below). After that, it blocks again on reception on the radio. + + +```mermaid +flowchart TB + L1_tx_thread --> TX_in[block L1_tx_out] --> NR_slot_indication + + subgraph tx_func + + NR_slot_indication --> msg:resp_L1 --> phy_procedures_gNB_tx --> ru_tx_func + NR_slot_indication["run the scheduler: + - monolithic: run_scheduler_monolithic() + - nFAPI: send indication via pnf_send_slot_ind()"] + msg:resp_L1 -- async launch --> L1_RX_thread + end + ru_tx_func --> TX_in +``` + +The `L1_tx_thread()` processes individual TX jobs sequentially, by waiting for +new messages on queue `L1_tx_out`, signalling individual TX jobs. For each +message, it calls `tx_func()` which does in order: + +- run the scheduler through `NR_slot_indication`, which corresponds to a + "Slot.indication" in FAPI parlance. This runs the scheduler, and schedules a + given slot (either downlink, uplink, or both). +- trigger RX processing by pushing a message into the FIFO queue `resp_L1`, + asynchronously starting an RX job in `L1_rx_thread()` (see below). +- process the current L1 TX job through `phy_procedures_gNB_tx()` +- write to the radio board via `ru_tx_func()`. + +After these steps, `tx_func()` return to `L1_tx_thread()`, which will wait for +the next TX job. + +```mermaid +flowchart TB + L1_rx_thread --> RX_in[block resp_L1] --> L1_nr_prach_proc + + subgraph rx_func + + L1_nr_prach_proc --> phase_comp{apply phase comp.?} + phase_comp -- yes --> apply_nr_rotation --> phy_procedures_gNB_uespec_RX + phase_comp -- no --> phy_procedures_gNB_uespec_RX + phy_procedures_gNB_uespec_RX --> NR_ul_indication --> msg:L1_rx_out + NR_ul_indication["run the scheduler: NR_UL_indication()"] + msg:L1_rx_out -- async signal free --> ru_thread + end + msg:L1_rx_out --> RX_in +``` + +The `L1_rx_thread()` processes individual RX jobs sequentially. It waits for a +new RX job through the queue `resp_L1`, and then calls `rx_func()`, which does +in order: + +- run PRACH processing via `L1_nr_prach_proc()` +- optionally apply rotation to the RX signal if phase compensation is to be + applied +- run the current L1 RX job through (`phy_procedures_gNB_uespec_RX()`), which + notably includes PUCCH, PUSCH, SRS processing +- call the scheduler through `NR_ul_indication()`, which corresponds to FAPI + uplink messages (e.g., `RX_data.indication`, `CRC.indication`, + `UCI.indication` etc.) +- signal completion via FIFO queue `L1_rx_out()`, which tells `ru_thread()` + that RX processing finished. + +The signalling of scheduler data is done through a variable `UL_INFO`, which is +filled by `L1_nr_prach_proc()` (for PRACH) and `phy_procedures_gNB_uespec_RX()` +(for PUCCH, PUSCH, SRS). + +After these steps, `rx_func()` returns to `L1_rx_thread()`, which will wait the +next RX job. + +Note that while individual TX (RX) jobs are run sequentially through +`L1_tx_thread()` (`L1_rx_thread()`), both TX and RX processing run in +parallel. diff --git a/doc/SW_archi.md b/doc/SW_archi.md index c47a3cbc91..78004a5a74 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -177,7 +177,7 @@ it would be better to call **NR_UL_indication()** now instead of before (on prev * nr_common_signal_procedures() generate common signals {: .func4} -* nr_generate_dci_top() +* nr_generate_dci() generate DCI: the scheduling informtion for each UE in both DL and UL {: .func4} * nr_generate_pdsch() diff --git a/doc/nfapi.md b/doc/nfapi.md index 214aa2799f..8b9197b056 100644 --- a/doc/nfapi.md +++ b/doc/nfapi.md @@ -242,10 +242,10 @@ To see the (any) periodical output at the PNF, define `NFAPI_TRACE_LEVEL=info`. This output shows: ``` -41056.739654 [I] 3556767424: pnf_p7_slot_ind: [P7:1] msgs ontime 489 thr DL 0.06 UL 0.01 msg late 0 (vtime) +41056.739654 [I] 3556767424: nr_pnf_p7_get_msgs: [P7:1] msgs ontime 489 thr DL 0.06 UL 0.01 msg late 0 (vtime) ``` -The first numbers are timestamps. `pnf_p7_slot_ind` is the name of the +The first numbers are timestamps. `nr_pnf_p7_get_msgs` is the name of the functions that prints the output. `[P7:1]` refers to the fact that these are information on P7, of PHY ID 1. Finally, `msgs ontime 489` means that in the last window (since the last print), 489 messages arrived at the PNF in total. diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 80b532607e..6ff535fb5b 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -194,13 +194,7 @@ void handle_nr_srs_measurements(const module_id_t module_id, void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); /* TODO these declarations are to be removed */ -void nr_schedule_dl_tti_req(void) {}; -void nr_schedule_ul_dci_req() {}; -void nr_schedule_tx_req() {}; -void nr_schedule_ul_tti_req() {}; void nr_slot_select() {}; -void NR_UL_indication(NR_UL_IND_t *UL_INFO) {}; -void gNB_dlsch_ulsch_scheduler() {}; /*------------------------------------------------------------------------*/ diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index b212ceb3f1..f36bdde2b5 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -156,10 +156,6 @@ extern char uecap_xer[1024]; char uecap_xer_in=0; /* TODO these declarations are to be removed */ -void nr_schedule_dl_tti_req(void) {}; -void nr_schedule_ul_dci_req() {}; -void nr_schedule_tx_req() {}; -void nr_schedule_ul_tti_req() {}; void nr_slot_select() {}; /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index b866a83222..94fc22cf46 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -55,7 +55,6 @@ #include "PHY/defs_gNB.h" #include "PHY/defs_nr_common.h" #include "PHY/impl_defs_nr.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "SCHED_NR/phy_frame_config_nr.h" #include "SCHED_NR/sched_nr.h" #include "assertions.h" @@ -65,7 +64,6 @@ #include "nfapi/oai_integration/vendor_ext.h" #include "nfapi_nr_interface_scf.h" #include "notified_fifo.h" -#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" #include "thread-pool.h" #include "time_meas.h" #include "utils.h" @@ -82,8 +80,6 @@ static void tx_func(processingData_L1tx_t *info) int slot_rx = info->slot_rx; LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx); PHY_VARS_gNB *gNB = info->gNB; - module_id_t module_id = gNB->Mod_id; - uint8_t CC_id = gNB->CC_id; NR_IF_Module_t *ifi = gNB->if_inst; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; @@ -94,15 +90,22 @@ static void tx_func(processingData_L1tx_t *info) reset_active_ulsch(gNB, frame_rx); } + clear_slot_beamid(gNB, slot_tx); + + nfapi_nr_slot_indication_scf_t ind = {.sfn = frame_tx, .slot = slot_tx}; start_meas(&gNB->slot_indication_stats); - ifi->NR_slot_indication(module_id, CC_id, frame_tx, slot_tx); + // this variable is very big (multiple MB), so we put it into static storage + // to not overflow the stack while still having it in local (function) scope + // also, tx_func() is only executed by one thread, serially + static NR_Sched_Rsp_t sched_response; + ifi->NR_slot_indication(&ind, &sched_response); stop_meas(&gNB->slot_indication_stats); - gNB->msgDataTx->timestamp_tx = info->timestamp_tx; - info = gNB->msgDataTx; + info->gNB = gNB; // At this point, MAC scheduler just ran, including scheduling // PRACH/PUCCH/PUSCH, so trigger RX chain processing + nr_save_ul_tti_req(gNB, &sched_response.UL_tti_req); LOG_D(NR_PHY, "Trigger RX for %d.%d\n", frame_rx, slot_rx); notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, NULL); processingData_L1_t *syncMsg = NotifiedFifoData(res); @@ -119,7 +122,13 @@ static void tx_func(processingData_L1tx_t *info) if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM || cfg->analog_beamforming_ve.analog_beam_list) { start_meas(&info->gNB->phy_proc_tx); - phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1); + phy_procedures_gNB_TX(info->gNB, + &sched_response.DL_req, + &sched_response.TX_req, + &sched_response.UL_dci_req, + frame_tx, + slot_tx, + 1); PHY_VARS_gNB *gNB = info->gNB; processingData_RU_t syncMsgRU; @@ -131,14 +140,6 @@ static void tx_func(processingData_L1tx_t *info) ru_tx_func((void *)&syncMsgRU); stop_meas(&info->gNB->phy_proc_tx); } - - if (NFAPI_MODE == NFAPI_MONOLITHIC) { - /* this thread is done with the sched_info, decrease the reference counter. - * This only applies for monolithic; in the PNF, the memory is allocated in - * a ring buffer that should never be overwritten (one frame duration). */ - LOG_D(NR_PHY, "Calling deref_sched_response for id %d (tx_func) in %d.%d\n", info->sched_response_id, frame_tx, slot_tx); - deref_sched_response(info->sched_response_id); - } } void *L1_rx_thread(void *arg) @@ -248,7 +249,6 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size output += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output, end - output); output += print_meas_log(&gNB->slot_indication_stats, "Slot Indication", NULL, NULL, output, end - output); output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output); - output += print_meas_log(&gNB->schedule_response_stats, "Schedule Response", NULL, NULL, output, end - output); output += print_meas_log(&gNB->rx_prach, "PRACH RX", NULL, NULL, output, end - output); if (ru->feprx) output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output); @@ -310,7 +310,6 @@ void *nrL1_stats_thread(void *param) { reset_meas(&gNB->ul_indication_stats); reset_meas(&gNB->slot_indication_stats); reset_meas(&gNB->rx_pusch_stats); - reset_meas(&gNB->schedule_response_stats); reset_meas(&gNB->dlsch_scrambling_stats); reset_meas(&gNB->dlsch_modulation_stats); reset_meas(&gNB->dlsch_resource_mapping_stats); @@ -358,14 +357,6 @@ void init_gNB_Tpool(int inst) // create the TX thread responsible for TX processing start event (L1_tx_out msg queue), then launch tx_func() threadCreate(&gNB->L1_tx_thread, L1_tx_thread, (void *)gNB, "L1_tx_thread", gNB->L1_tx_thread_core, OAI_PRIORITY_RT_MAX); - notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL); - processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx); - memset(msgDataTx, 0, sizeof(processingData_L1tx_t)); - init_DLSCH_struct(gNB, msgDataTx); - memset(msgDataTx->ssb, 0, 64 * sizeof(NR_gNB_SSB_t)); - // this will be removed when the msgDataTx is not necessary anymore - gNB->msgDataTx = msgDataTx; - if (!IS_SOFTMODEM_NOSTATS) threadCreate(&proc->L1_stats_thread, nrL1_stats_thread, (void *)gNB, "L1_stats", -1, OAI_PRIORITY_RT_LOW); } @@ -442,7 +433,6 @@ void init_gNB() AssertFatal((gNB->if_inst = NR_IF_Module_init(inst)) != NULL, "Cannot register interface"); LOG_I(NR_PHY, "Registered with MAC interface module (%p)\n", gNB->if_inst); - gNB->if_inst->NR_Schedule_response = nr_schedule_response; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; gNB->prach_energy_counter = 0; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 945e7e4cae..125bfbd898 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -423,8 +423,6 @@ int start_L1L2(module_id_t gnb_id) /* block threads */ oai_exit = 0; sync_var = -1; - extern void init_sched_response(void); - init_sched_response(); /* update config */ gNB_MAC_INST *mac = RC.nrmac[0]; diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 3de11d8003..bb3ac8555b 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -55,7 +55,6 @@ #include "PHY/INIT/phy_init.h" #include "PHY/INIT/nr_phy_init.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" -#include "openair1/SCHED_NR/fapi_nr_l1.h" #include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" #include "openair1/PHY/defs_gNB.h" #include @@ -1108,17 +1107,6 @@ void pnf_nr_phy_deallocate_p7_vendor_ext(void *header) free(header); } -extern void nr_schedule_ul_dci_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_dci_request_t *UL_dci_req); -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) -{ - DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL); - PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst? - - nr_schedule_ul_dci_req(gNB, req); - - return 0; -} - int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) { if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0) @@ -1149,21 +1137,6 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa } -// from dl_tti_req_fn fptr -extern void nr_schedule_dl_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_request_t *DL_req); -int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_dl_tti_request_t *DL_req) -{ - DevAssert(proc == NULL); - DevAssert(sync_var == 0); - DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL); - PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst? - - nr_schedule_dl_tti_req(gNB, DL_req); - - return 0; -} - - int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) { if (RC.eNB == 0) { @@ -1256,18 +1229,6 @@ int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n } -extern void nr_schedule_tx_req(PHY_VARS_gNB *gNB, nfapi_nr_tx_data_request_t *TX_req); -int pnf_phy_tx_data_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_tx_data_request_t *req) -{ - DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL); - PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst? - - nr_schedule_tx_req(gNB, req); - - return 0; -} - - int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf); uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf); @@ -1293,16 +1254,6 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { return 0; } -extern void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req); -int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_tti_request_t *req) -{ - DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL); - PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst? - - nr_schedule_ul_tti_req(gNB, req); - return 0; -} - int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) { if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", __FUNCTION__, @@ -1711,10 +1662,10 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf } // NR - p7_config->dl_tti_req_fn = &pnf_phy_dl_tti_req; - p7_config->ul_tti_req_fn = &pnf_phy_ul_tti_req; - p7_config->ul_dci_req_fn = &pnf_phy_ul_dci_req; - p7_config->tx_data_req_fn = &pnf_phy_tx_data_req; + p7_config->dl_tti_req_fn = NULL; + p7_config->ul_tti_req_fn = NULL; + p7_config->ul_dci_req_fn = NULL; + p7_config->tx_data_req_fn = NULL; // LTE p7_config->dl_config_req = &pnf_phy_dl_config_req; @@ -1825,13 +1776,6 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf nfapi_nr_send_pnf_start_resp(config, p7_config->phy_id); printf("[PNF] Sending first P7 slot indication\n"); #endif -#if 1 - nfapi_pnf_p7_slot_ind(p7_config, p7_config->phy_id, 0, 0); - printf("[PNF] Sent first P7 slot ind\n"); -#else - nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // SFN_SF set to zero - correct??? - printf("[PNF] Sent first P7 subframe ind\n"); -#endif return 0; } @@ -2321,7 +2265,7 @@ static void maybe_slow_down_pnf(int mu) last_execution = current_execution; } -void handle_nr_slot_ind(uint16_t sfn, uint16_t slot) +void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_resp) { nfapi_pnf_p7_config_t *config = p7_config_g; pnf_p7_t *_this = (pnf_p7_t *)(config); @@ -2352,7 +2296,14 @@ void handle_nr_slot_ind(uint16_t sfn, uint16_t slot) oai_nfapi_nr_slot_indication(&ind); // copy data from appropriate p7 slot buffers into channel structures for PHY processing - nfapi_pnf_p7_slot_ind(config, config->phy_id, sfn, slot); + nfapi_pnf_p7_get_msgs(config, + config->phy_id, + sfn, + slot, + &sched_resp->DL_req, + &sched_resp->UL_tti_req, + &sched_resp->UL_dci_req, + &sched_resp->TX_req); return; } diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index 0ba0676f10..ad2df72ad3 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -28,7 +28,8 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); void oai_subframe_ind(uint16_t sfn, uint16_t sf); -void handle_nr_slot_ind(uint16_t sfn, uint16_t slot); +struct NR_Sched_Rsp; +void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, struct NR_Sched_Rsp *resp); void sfnslot_add_slot(int mu, uint16_t *sfn, uint16_t *slot, int offset); int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind); diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 5ea99de7ea..b251d9d762 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -124,7 +124,6 @@ int vnf_nr_unpack_vendor_extension_tlv(nfapi_tl_t *tl, { return -1; } -void install_nr_schedule_handlers(NR_IF_Module_t *if_inst); void install_schedule_handlers(IF_Module_t *if_inst); extern int sf_ahead; @@ -326,71 +325,6 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_ return 0; } -int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) { - struct timespec curr_t; - clock_gettime(CLOCK_MONOTONIC,&curr_t); - //NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec); - gNB_L1_proc_t *proc=&gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc= (slot&1)? &proc->L1_proc : &proc->L1_proc_tx; - - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); - //int i; - struct timespec wait; - clock_gettime(CLOCK_REALTIME, &wait); - wait.tv_sec = 0; - wait.tv_nsec +=5000L; - //wait.tv_nsec = 0; - // wake up TX for subframe n+sf_ahead - // lock the TX mutex and make sure the thread is ready - AssertFatal(gNB->if_inst->sl_ahead==6,"gNB->if_inst->sl_ahead %d : This is hard-coded to 6 in nfapi P7!!!\n",gNB->if_inst->sl_ahead); - if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt ); - exit_fun( "error locking mutex_rxtx" ); - return(-1); - } - - { - static uint16_t old_slot = 0; - static uint16_t old_sfn = 0; - proc->slot_rx = old_slot; - proc->frame_rx = old_sfn; - // Try to be 1 frame back - old_slot = slot; - old_sfn = sfn; - //NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx); - if (old_slot == 0 && old_sfn % 100 == 0) LOG_W( PHY,"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", sfn, slot, old_sfn, old_slot, proc->frame_rx, proc->slot_rx); - } - - ++L1_proc->instance_cnt; - //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx); - // We have just received and processed the common part of a subframe, say n. - // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired - // transmitted timestamp of the next TX slot (first). - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti, - // and proc->subframe_tx = proc->subframe_rx+sf_ahead - L1_proc->timestamp_tx = proc->timestamp_rx + (gNB->if_inst->sl_ahead *fp->samples_per_subframe); - L1_proc->frame_rx = proc->frame_rx; - L1_proc->slot_rx = proc->slot_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (19-gNB->if_inst->sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + gNB->if_inst->sl_ahead)%20; - - //LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx); - //NFAPI_TRACE(NFAPI_TRACE_INFO, "\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx); - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); - exit_fun( "ERROR pthread_clond_signal" ); - return(-1); - } - - //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__); - pthread_mutex_unlock( &L1_proc->mutex ); - //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__); - return(0); -} - int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { L1_proc_t *proc=&eNB->proc; L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx; @@ -498,28 +432,6 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) { } -int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) { - static uint8_t first_time = 1; - - if (first_time) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d.%d\n", sfn, slot); - first_time = 0; - } - - if (RC.gNB && RC.gNB[0]->configured) { - // uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); - // uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); - LOG_D(PHY,"[VNF] slot indication sfn:%d slot:%d\n", sfn, slot); - wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent - } else { - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB); - - if (RC.gNB) NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured); - } - - return 0; -} - int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) { static uint8_t first_time = 1; @@ -971,65 +883,63 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_ //NR phy indication -NR_Sched_Rsp_t g_sched_resp; -void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slot, NR_Sched_Rsp_t* sched_info); int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req); int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t* tx_data_req); int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t* ul_dci_req); -int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind) -{ - // Call into the scheduler (this is hardcoded and should be init properly!) - // memset(sched_resp, 0, sizeof(*sched_resp)); - gNB_dlsch_ulsch_scheduler(0, slot_ind->sfn, slot_ind->slot, &g_sched_resp); - -#ifdef ENABLE_AERIAL - bool send_slt_resp = false; - if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) { - oai_fapi_dl_tti_req(&g_sched_resp.DL_req); - send_slt_resp = true; - } - if (g_sched_resp.UL_tti_req.n_pdus > 0) { - oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req); - send_slt_resp = true; - } - if (g_sched_resp.TX_req.Number_of_PDUs > 0) { - oai_fapi_tx_data_req(&g_sched_resp.TX_req); - send_slt_resp = true; - } - if (g_sched_resp.UL_dci_req.numPdus > 0) { - oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req); - send_slt_resp = true; - } - if (send_slt_resp) { - oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot); - } -#else - if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs > 0) - oai_nfapi_dl_tti_req(&g_sched_resp.DL_req); - - if (g_sched_resp.UL_tti_req.n_pdus > 0) - oai_nfapi_ul_tti_req(&g_sched_resp.UL_tti_req); - - if (g_sched_resp.TX_req.Number_of_PDUs > 0) - oai_nfapi_tx_data_req(&g_sched_resp.TX_req); - - if (g_sched_resp.UL_dci_req.numPdus > 0) - oai_nfapi_ul_dci_req(&g_sched_resp.UL_dci_req); -#endif - - NR_UL_IND_t ind = {.frame = slot_ind->sfn, .slot = slot_ind->slot, }; - NR_UL_indication(&ind); - - return 1; -} - int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) { LOG_D(MAC, "VNF SFN/Slot %d.%d \n", ind->sfn, ind->slot); - trigger_scheduler(ind); + // this variable is very big (multiple MB), so we put it into static storage + // to not overflow the stack while still having it in local (function) scope + // also, phy_nr_slot_indication() is only executed by one thread, serially + static NR_Sched_Rsp_t sched_response; + NR_IF_Module_t *ifi = RC.nrmac[0]->if_inst; + ifi->NR_slot_indication(ind, &sched_response); + +#ifdef ENABLE_AERIAL + bool send_slt_resp = false; + if (sched_response.DL_req.dl_tti_request_body.nPDUs> 0) { + oai_fapi_dl_tti_req(&sched_response.DL_req); + send_slt_resp = true; + } + if (sched_response.UL_tti_req.n_pdus > 0) { + oai_fapi_ul_tti_req(&sched_response.UL_tti_req); + send_slt_resp = true; + } + if (sched_response.TX_req.Number_of_PDUs > 0) { + oai_fapi_tx_data_req(&sched_response.TX_req); + send_slt_resp = true; + } + if (sched_response.UL_dci_req.numPdus > 0) { + oai_fapi_ul_dci_req(&sched_response.UL_dci_req); + send_slt_resp = true; + } + if (send_slt_resp) { + oai_fapi_send_end_request(0, ind->sfn, ind->slot); + } +#else + if (sched_response.DL_req.dl_tti_request_body.nPDUs > 0) + oai_nfapi_dl_tti_req(&sched_response.DL_req); + + if (sched_response.UL_tti_req.n_pdus > 0) + oai_nfapi_ul_tti_req(&sched_response.UL_tti_req); + + if (sched_response.TX_req.Number_of_PDUs > 0) + oai_nfapi_tx_data_req(&sched_response.TX_req); + + if (sched_response.UL_dci_req.numPdus > 0) + oai_nfapi_ul_dci_req(&sched_response.UL_dci_req); +#endif + + /* the below works because the function behind the callback collects + * messages from queue into which messages have been copied. + * TODO we should have different callbacks for received messages and call + * into the scheduler separately for each message instead of one big one. */ + NR_UL_IND_t ul_ind = {.frame = ind->sfn, .slot = ind->slot, }; + ifi->NR_UL_indication(&ul_ind); return 1; } @@ -1305,7 +1215,7 @@ void *configure_nr_p7_vnf(void *ptr) p7_vnf->config->port = p7_vnf->local_port; #ifndef ENABLE_AERIAL p7_vnf->config->sync_indication = &phy_sync_indication; - p7_vnf->config->slot_indication = &phy_slot_indication; + p7_vnf->config->slot_indication = NULL; p7_vnf->config->harq_indication = &phy_harq_indication; #endif p7_vnf->config->nr_crc_indication = &phy_nr_crc_indication; @@ -1367,7 +1277,7 @@ void *vnf_p7_thread_start(void *ptr) { p7_vnf->config->port = p7_vnf->local_port; p7_vnf->config->sync_indication = &phy_sync_indication; p7_vnf->config->subframe_indication = &phy_subframe_indication; - p7_vnf->config->slot_indication = &phy_slot_indication; + p7_vnf->config->slot_indication = NULL; p7_vnf->config->harq_indication = &phy_harq_indication; p7_vnf->config->crc_indication = &phy_crc_indication; diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 5805e07445..3040d9de09 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -145,8 +145,14 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7); int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len); int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len); - -int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot); +int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7, + uint16_t phy_id, + uint16_t sfn, + uint16_t slot, + nfapi_nr_dl_tti_request_t* ret_dl_tti, + nfapi_nr_ul_tti_request_t* ret_ul_tti, + nfapi_nr_ul_dci_request_t* ret_ul_dci, + nfapi_nr_tx_data_request_t* ret_tx_data); int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf); int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind); int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind); diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index 957e032f69..6576f6406e 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -856,7 +856,7 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config); */ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config); -/*! NR Slot indication +/*! NR get stuff * message copied from nfapi_pnf_p7_subframe_ind * \param config A pointer to a PNF P7 config * \param phy_id The phy_id for the phy instance @@ -868,8 +868,14 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config); * * If messages are not in the subframe buffer, they dummy subframe messages will be sent */ -int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot); - +int nfapi_pnf_p7_get_msgs(nfapi_pnf_p7_config_t* config, + uint16_t phy_id, + uint16_t sfn, + uint16_t slot, + nfapi_nr_dl_tti_request_t* ret_dl_tti, + nfapi_nr_ul_tti_request_t* ret_ul_tti, + nfapi_nr_ul_dci_request_t* ret_ul_dci, + nfapi_nr_tx_data_request_t* ret_tx_data); /*! Subframe indication * \param config A pointer to a PNF P7 config diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index e2b6d253d2..197bac22b7 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -672,145 +672,157 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf) } } +int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7, + uint16_t phy_id, + uint16_t sfn, + uint16_t slot, + nfapi_nr_dl_tti_request_t* ret_dl_tti, + nfapi_nr_ul_tti_request_t* ret_ul_tti, + nfapi_nr_ul_dci_request_t* ret_ul_dci, + nfapi_nr_tx_data_request_t* ret_tx_data) +{ + if (pthread_mutex_lock(&(pnf_p7->mutex)) != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } -int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot) -{ - //This function is aligned with rx sfn/slot + // save the curren time, sfn and slot + // TODO useful? + pnf_p7->slot_start_time_hr = pnf_get_current_time_hr(); - // We could either send an event to the p7 thread have have it run the - // subframe or we could handle it here and lock access to the subframe - // buffers. If we do it on the p7 thread then we run the risk of blocking - // on the udp send. - - // todo : consider a more efficent lock mechasium - //uint16_t NUM_SLOTS = 20;//10* 2^mu - - if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) - { - NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); - return -1; - } + // We align the pnf_p7 sfn/slot with tx sfn/slot, and vnf is synced with pnf_p7 sfn/slot. This is so that the scheduler runs + // slot_ahead from rx thread. + pnf_p7->sfn = sfn; + pnf_p7->slot = slot; - // save the curren time, sfn and slot - pnf_p7->slot_start_time_hr = pnf_get_current_time_hr(); + uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn, slot); + uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu); - //We align the pnf_p7 sfn/slot with tx sfn/slot, and vnf is synced with pnf_p7 sfn/slot. This is so that the scheduler runs slot_ahead from rx thread. + // If the subframe_buffer has been configured + if (pnf_p7->_public.slot_buffer_size != 0) // for now value is same as sf_buffer_size + { + // apply the shift to the incoming sfn_sf + if (pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync + { + uint16_t shifted_slot = slot + pnf_p7->slot_shift; - pnf_p7->sfn = sfn; - pnf_p7->slot = slot; + // adjust for wrap-around + if (shifted_slot < 0) + shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu); + else if (shifted_slot > NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu)) + shifted_slot -= NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu); - uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn,slot); - uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift, + //NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot); + slot = shifted_slot; - // If the subframe_buffer has been configured - if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size - { + // + // why does the shift not apply to pnf_p7->sfn_sf??? + // - // apply the shift to the incoming sfn_sf - if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync - { - uint16_t shifted_slot = slot + pnf_p7->slot_shift; + pnf_p7->slot_shift = 0; + } - // adjust for wrap-around - if(shifted_slot < 0) - shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu); - else if(shifted_slot > NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu)) - shifted_slot -= NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu); - - // NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift, NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot); - slot = shifted_slot; - - // - // why does the shift not apply to pnf_p7->sfn_sf??? - // - - pnf_p7->slot_shift = 0; - } - - nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]); + nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]); + ret_dl_tti->SFN = sfn; + ret_dl_tti->Slot = slot; + ret_dl_tti->dl_tti_request_body.nPDUs = 0; + ret_tx_data->SFN = sfn; + ret_tx_data->Slot = slot; + ret_tx_data->Number_of_PDUs = 0; nfapi_nr_dl_tti_request_t* dl_tti_req = &tx_slot_buffer->dl_tti_req; - nfapi_nr_tx_data_request_t* tx_data_req = &tx_slot_buffer->tx_data_req; - if (dl_tti_req->dl_tti_request_body.nPDUs > 0 && dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot) { - DevAssert(pnf_p7->_public.dl_tti_req_fn != NULL); - DevAssert(pnf_p7->_public.tx_data_req_fn != NULL); - if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) { - (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), dl_tti_req); - (pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_data_req); - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding tx_data.request for dl_tti.request, dropping\n", sfn, slot); + nfapi_nr_tx_data_request_t* txd = &tx_slot_buffer->tx_data_req; + if (dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot && txd->SFN == sfn && txd->Slot == slot) { + nfapi_nr_dl_tti_request_body_t* p_tti = &dl_tti_req->dl_tti_request_body; + int ret_idx = 0; + for (int i = 0; i < p_tti->nPDUs; ++i) { + int tx_index = p_tti->dl_tti_pdu_list[i].pdsch_pdu.pdsch_pdu_rel15.pduIndex - 1; + if (tx_index >= txd->Number_of_PDUs) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, + "%4d.%2d no corresponding tx_data.request for dl_tti.request index %d, dropping\n", + sfn, + slot, + tx_index); + continue; + } + ret_dl_tti->dl_tti_request_body.dl_tti_pdu_list[ret_idx] = p_tti->dl_tti_pdu_list[i]; + // TODO avoid huge copy + ret_tx_data->pdu_list[ret_idx] = txd->pdu_list[i]; + ret_idx++; } + ret_dl_tti->dl_tti_request_body.nPDUs = ret_idx; + ret_tx_data->Number_of_PDUs = ret_idx; + tx_slot_buffer->dl_tti_req.SFN = -1; tx_slot_buffer->dl_tti_req.Slot = -1; tx_slot_buffer->tx_data_req.SFN = -1; tx_slot_buffer->tx_data_req.Slot = -1; } - if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) { - // there is a tx_data.request in this slot, but no corresponding - // dl_tti.request (when they need to come pairwise) - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding dl_tti.request for tx_data.request, dropping\n", sfn, slot); - tx_slot_buffer->tx_data_req.SFN = -1; - tx_slot_buffer->tx_data_req.Slot = -1; - } - if(tx_slot_buffer->ul_tti_req.n_pdus > 0 && tx_slot_buffer->ul_tti_req.SFN == sfn && tx_slot_buffer->ul_tti_req.Slot == slot) - { - DevAssert(pnf_p7->_public.ul_tti_req_fn != NULL); - (pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_tti_req); + ret_ul_tti->SFN = sfn; + ret_ul_tti->Slot = slot; + ret_ul_tti->n_pdus = 0; + if (tx_slot_buffer->ul_tti_req.SFN == sfn && tx_slot_buffer->ul_tti_req.Slot == slot) { + nfapi_nr_ul_tti_request_t* p = &tx_slot_buffer->ul_tti_req; + ret_ul_tti->n_pdus = p->n_pdus; + for (int i = 0; i < p->n_pdus; ++i) + ret_ul_tti->pdus_list[i] = p->pdus_list[i]; tx_slot_buffer->ul_tti_req.SFN = -1; tx_slot_buffer->ul_tti_req.Slot = -1; - } + } - if(tx_slot_buffer->ul_dci_req.numPdus > 0 && tx_slot_buffer->ul_dci_req.SFN == sfn && tx_slot_buffer->ul_dci_req.Slot == slot) - { - DevAssert(pnf_p7->_public.ul_dci_req_fn != NULL); - (pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_dci_req); + ret_ul_dci->SFN = sfn; + ret_ul_dci->Slot = slot; + ret_ul_dci->numPdus = 0; + if (tx_slot_buffer->ul_dci_req.SFN == sfn && tx_slot_buffer->ul_dci_req.Slot == slot) { + nfapi_nr_ul_dci_request_t* p = &tx_slot_buffer->ul_dci_req; + ret_ul_dci->numPdus = p->numPdus; + for (int i = 0; i < p->numPdus; ++i) + ret_ul_dci->ul_dci_pdu_list[i] = p->ul_dci_pdu_list[i]; tx_slot_buffer->ul_dci_req.SFN = -1; tx_slot_buffer->ul_dci_req.Slot = -1; - } + } - //send the periodic timing info if configured - if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) - { - pnf_nr_pack_and_send_timing_info(pnf_p7); + // send the periodic timing info if configured + if (pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) { + pnf_nr_pack_and_send_timing_info(pnf_p7); - pnf_p7->timing_info_period_counter = 0; - } - else if(pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) - { - pnf_nr_pack_and_send_timing_info(pnf_p7); + pnf_p7->timing_info_period_counter = 0; + } else if (pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) { + pnf_nr_pack_and_send_timing_info(pnf_p7); - pnf_p7->timing_info_aperiodic_send = 0; - } - else - { - pnf_p7->timing_info_ms_counter++; - } - - } + pnf_p7->timing_info_aperiodic_send = 0; + } else { + pnf_p7->timing_info_ms_counter++; + } + } if (sfn % 128 == 0 && slot == 0) { pnf_p7_nr_stats_t* s = &pnf_p7->nr_stats; int ontime = s->dl_tti.ontime + s->ul_tti.ontime + s->ul_dci.ontime + s->tx_data.ontime; int late = s->dl_tti.late + s->ul_tti.late + s->ul_dci.late + s->tx_data.late; - float dl_thr = (float) s->dl.bytes * 8 / 1000 / 1000 / 1.28f; // every 128 frames = 1.28 s - float ul_thr = (float) s->ul.bytes * 8 / 1000 / 1000 / 1.28f; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[P7:%d] msgs ontime %d thr DL %.2f UL %.2f msg late %d (vtime)\n", pnf_p7->_public.phy_id, ontime, dl_thr, ul_thr, late); + float dl_thr = (float)s->dl.bytes * 8 / 1000 / 1000 / 1.28f; // every 128 frames = 1.28 s + float ul_thr = (float)s->ul.bytes * 8 / 1000 / 1000 / 1.28f; + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[P7:%d] msgs ontime %d thr DL %.2f UL %.2f msg late %d (vtime)\n", + pnf_p7->_public.phy_id, + ontime, + dl_thr, + ul_thr, + late); memset(s, 0, sizeof(*s)); } - if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) - { - NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); - return -1; - } + if (pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } - return 0; + return 0; } - - int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) { // We could either send an event to the p7 thread have have it run the diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index b021e67fc9..af02ef7a4e 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -89,15 +89,22 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config) return 0; } -int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot) +int nfapi_pnf_p7_get_msgs(nfapi_pnf_p7_config_t* config, + uint16_t phy_id, + uint16_t sfn, + uint16_t slot, + nfapi_nr_dl_tti_request_t* ret_dl_tti, + nfapi_nr_ul_tti_request_t* ret_ul_tti, + nfapi_nr_ul_dci_request_t* ret_ul_dci, + nfapi_nr_tx_data_request_t* ret_tx_data) { - // Verify that config is not null - if(config == 0) - return -1; - - pnf_p7_t* _this = (pnf_p7_t*)(config); + // Verify that config is not null + if (config == 0) + return -1; - return pnf_p7_slot_ind(_this, phy_id, sfn, slot); + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return nr_pnf_p7_get_msgs(_this, phy_id, sfn, slot, ret_dl_tti, ret_ul_tti, ret_ul_dci, ret_tx_data); } int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf) diff --git a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c index bd6bedbea5..3460d4d9d7 100644 --- a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c +++ b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c @@ -1210,12 +1210,6 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i //free(req.tx_request_body.tx_pdu_list); } -void send_slot_indication(phy_info_t* phy_info) -{ - // DONE: add sfn and slot as members in the phy_info - nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot); -} - void send_subframe_indication(phy_info_t* phy_info) { nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf); diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c index 3fece46ac8..374ecb4b19 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c @@ -36,7 +36,6 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "SCHED_NR/sched_nr.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/log.h" diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c index b23db3781d..1d9aa53d25 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c @@ -38,7 +38,6 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/defs_gNB.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "SCHED_NR/sched_nr.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 913ffbb8d5..58ad0f2449 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -39,11 +39,13 @@ #include #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_REFSIG/nr_refsig.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" #include #include "nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h" +static void init_DLSCH_struct(PHY_VARS_gNB *gNB); +static void destroy_DLSCH_struct(const PHY_VARS_gNB *gNB); + int l1_north_init_gNB() { AssertFatal(RC.nb_nr_L1_inst > 0, "Failed to init PHY callbacks: nb_nr_L1_inst = %d\n", RC.nb_nr_L1_inst); @@ -58,7 +60,6 @@ int l1_north_init_gNB() LOG_D(NR_PHY, "RC.gNB[%d]: installing callbacks\n", i); RC.gNB[i]->if_inst->NR_PHY_config_req = nr_phy_config_request; - RC.gNB[i]->if_inst->NR_Schedule_response = nr_schedule_response; } return 0; @@ -155,6 +156,8 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) /// Transport init necessary for NR synchro init_nr_transport(gNB); + init_DLSCH_struct(gNB); + gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*)); for (int id = 0; id < gNB->max_nb_srs; id++) { gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); @@ -241,6 +244,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) reset_nr_transport(gNB); + destroy_DLSCH_struct(gNB); + NR_gNB_COMMON * common_vars = &gNB->common_vars; for (int j = 0; j < common_vars->num_beams_period; j++) { if (common_vars->beam_id) @@ -281,13 +286,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) } -//Adding nr_schedule_handler -void install_nr_schedule_handlers(NR_IF_Module_t *if_inst) -{ - if_inst->NR_PHY_config_req = nr_phy_config_request; - if_inst->NR_Schedule_response = nr_schedule_response; -} - void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, int N_RB_DL, int N_RB_UL, @@ -401,37 +399,27 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) init_timeshift_rotation(fp); } -void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) +static void init_DLSCH_struct(PHY_VARS_gNB *gNB) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value; - msg->num_pdsch_slot = 0; - - msg->dlsch = malloc16(gNB->max_nb_pdsch * sizeof(NR_gNB_DLSCH_t *)); - int num_cw = NR_MAX_NB_LAYERS > 4? 2:1; + gNB->dlsch = calloc(gNB->max_nb_pdsch, sizeof(*gNB->dlsch)); for (int i = 0; i < gNB->max_nb_pdsch; i++) { LOG_D(PHY, "Allocating Transport Channel Buffers for DLSCH %d/%d\n", i, gNB->max_nb_pdsch); - msg->dlsch[i] = (NR_gNB_DLSCH_t *)malloc16(num_cw * sizeof(NR_gNB_DLSCH_t)); - for (int j = 0; j < num_cw; j++) { - msg->dlsch[i][j] = new_gNB_dlsch(fp, grid_size); - } + gNB->dlsch[i] = new_gNB_dlsch(fp, grid_size); } } -void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) +static void destroy_DLSCH_struct(const PHY_VARS_gNB *gNB) { const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; const nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value; - int num_cw = NR_MAX_NB_LAYERS > 4? 2:1; for (int i = 0; i < gNB->max_nb_pdsch; i++) { - for (int j = 0; j < num_cw; j++) { - free_gNB_dlsch(&msg->dlsch[i][j], grid_size, fp); - } - free(msg->dlsch[i]); + free_gNB_dlsch(&gNB->dlsch[i], grid_size, fp); } - free(msg->dlsch); + free(gNB->dlsch); } void init_nr_transport(PHY_VARS_gNB *gNB) diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index 1b1a0fa1b0..f556498f0f 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -46,9 +46,6 @@ int l1_north_init_gNB(void); void init_nr_transport(PHY_VARS_gNB *gNB); void reset_nr_transport(PHY_VARS_gNB *gNB); -void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg); -void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg); - void RCconfig_nrUE_prs(void *cfg); void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue); void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 0548c8fc10..2df2df8eb0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -51,11 +51,11 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3 out[i] = in[i] ^ seq[i]; } -static void nr_generate_dci(PHY_VARS_gNB *gNB, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, - int txdataF_offset, - NR_DL_FRAME_PARMS *frame_parms, - int slot) +void nr_generate_dci(PHY_VARS_gNB *gNB, + const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + int txdataF_offset, + NR_DL_FRAME_PARMS *frame_parms, + int slot) { // fill reg list per symbol int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE]; @@ -237,16 +237,3 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, *(unsigned long long *)dci_pdu->Payload); } // for (int d=0;dnumDlDci;d++) } - -void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset) -{ - PHY_VARS_gNB *gNB = msgTx->gNB; - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - start_meas(&gNB->dci_generation_stats); - for (int i = 0; i < msgTx->num_ul_pdcch; i++) - nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot); - for (int i = 0; i < msgTx->num_dl_pdcch; i++) - nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot); - stop_meas(&gNB->dci_generation_stats); -} - diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index e735069975..57651f03a2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -26,7 +26,11 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" -void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset); +void nr_generate_dci(PHY_VARS_gNB *gNB, + const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + int txdataF_offset, + NR_DL_FRAME_PARMS *frame_parms, + int slot); int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type); @@ -42,6 +46,6 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB, int slot, nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu); -void nr_fill_reg_list(int cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15); +void nr_fill_reg_list(int cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15); #endif //__PHY_NR_TRANSPORT_DCI__H diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 538b54ac0b..c2d2ab7a24 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -42,7 +42,7 @@ int compfunc(const void *a, const void *b) return (*(int *)a - *(int *)b); } -void nr_fill_reg_list(int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) +void nr_fill_reg_list(int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) { int bsize = pdcch_pdu_rel15->RegBundleSize; int R = pdcch_pdu_rel15->InterleaverSize; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 535c68f419..8df7b4814c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -51,7 +51,7 @@ static void nr_pdsch_codeword_scrambling(uint8_t *in, uint32_t size, uint8_t q, nr_codeword_scrambling(in, size, q, Nid, n_RNTI, out); } -static int do_ptrs_symbol(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, +static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, int start_sc, int symbol_sz, c16_t *txF, @@ -339,7 +339,7 @@ static inline void neg_dmrs(c16_t *in, c16_t *out, int sz) static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, int slot, - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, + const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, int layer, c16_t *output, c16_t *txl_start, @@ -457,7 +457,7 @@ static inline void do_txdataF(c16_t **txdataF, int symbol_sz, c16_t txdataF_precoding[][symbol_sz], PHY_VARS_gNB *gNB, - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, + const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, int ant, int start_sc, int txdataF_offset_per_symbol) @@ -465,7 +465,7 @@ static inline void do_txdataF(c16_t **txdataF, NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; int rb = 0; uint16_t subCarrier = start_sc; - nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; + const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; while (rb < rel15->rbSize) { // get pmi info const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0; @@ -555,8 +555,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats; time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15; const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB; const int symbol_sz=frame_parms->ofdm_symbol_size; const int dmrs_Type = rel15->dmrsConfigType; @@ -580,7 +579,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC /* PTRS */ uint16_t dlPtrsSymPos = 0; int n_ptrs = 0; - uint32_t ptrsSymbPerSlot = 0; if (rel15->pduBitmap & 0x1) { set_ptrs_symb_idx(&dlPtrsSymPos, rel15->NrOfSymbols, @@ -588,15 +586,13 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC 1 << rel15->PTRSTimeDensity, rel15->dlDmrsSymbPos); n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; - ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); } - harq->unav_res = ptrsSymbPerSlot * n_ptrs; #ifdef DEBUG_DLSCH printf("PDSCH encoding:\nPayload:\n"); - for (int i = 0; i < (harq->B >> 3); i += 16) { + for (int i = 0; i < (dlsch->B >> 3); i += 16) { for (int j = 0; j < 16; j++) - printf("0x%02x\t", harq->pdu[i + j]); + printf("0x%02x\t", dlsch->pdu[i + j]); printf("\n"); } printf("\nEncoded payload:\n"); @@ -609,7 +605,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC #endif if (IS_SOFTMODEM_DLSIM) - memcpy(harq->f, input_ptr, (encoded_length + 7) >> 3); + memcpy(dlsch->f, input_ptr, (encoded_length + 7) >> 3); c16_t mod_symbs[rel15->NrOfCodewords][encoded_length] __attribute__((aligned(64))); for (int codeWord = 0; codeWord < rel15->NrOfCodewords; codeWord++) { @@ -680,7 +676,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC // pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1 // The Precoding matrix: // The Codebook Type I - nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; + const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; // beam number in multi-beam scenario (concurrent beams) int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols); int beam_nb = beam_index_allocation(gNB->enable_analog_das, @@ -777,9 +773,8 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC return ((size_output_tb + 511) >> 9) << 6; } -void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) +void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_array, int frame, int slot) { - PHY_VARS_gNB *gNB = msgTx->gNB; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats; time_stats_t *tinput = &gNB->tinput; @@ -792,10 +787,9 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) size_t size_output = 0; - for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { - NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + for (int i = 0; i < n_dlsch; i++) { + NR_gNB_DLSCH_t *dlsch = &dlsch_array[i]; + const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15; LOG_D(PHY, "pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n", @@ -819,10 +813,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); } - harq->unav_res = ptrsSymbPerSlot * n_ptrs; + dlsch->unav_res = ptrsSymbPerSlot * n_ptrs; /// CRC, coding, interleaving and rate matching - AssertFatal(harq->pdu != NULL, "%4d.%2d no HARQ PDU for PDSCH generation\n", msgTx->frame, msgTx->slot); + AssertFatal(dlsch->pdu != NULL, "%4d.%2d no PDU for PDSCH generation\n", frame, slot); /* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits) * => size_output is a sum of parts sizes rounded up to a multiple of 8 * 64 @@ -836,7 +830,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) start_meas(dlsch_encoding_stats); if (nr_dlsch_encoding(gNB, - msgTx, + n_dlsch, + dlsch_array, frame, slot, frame_parms, @@ -854,8 +849,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) stop_meas(dlsch_encoding_stats); unsigned char *output_ptr = output; - for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { - output_ptr += do_one_dlsch(output_ptr, gNB, msgTx->dlsch[dlsch_id], slot); + for (int i = 0; i < n_dlsch; i++) { + output_ptr += do_one_dlsch(output_ptr, gNB, &dlsch_array[i], slot); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index 15f48825f5..0a82b2c47f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -35,15 +35,11 @@ #include "PHY/defs_gNB.h" -void nr_fill_dlsch_dl_tti_req(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu); -void nr_fill_dlsch_tx_req(processingData_L1tx_t *msgTx, int idx, uint8_t *sdu); - -void nr_generate_pdsch(processingData_L1tx_t *msgTx, - int frame, - int slot); +void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_array, int frame, int slot); int nr_dlsch_encoding(PHY_VARS_gNB *gNB, - processingData_L1tx_t *msgTx, + int n_dlsch, + NR_gNB_DLSCH_t *dlsch_array, int frame, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 56a849a4af..f74685ed71 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -52,20 +52,19 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM a_segments = a_segments / 273 + 1; } - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - if (harq->b) { - free16(harq->b, a_segments * 1056); - harq->b = NULL; + if (dlsch->b) { + free16(dlsch->b, a_segments * 1056); + dlsch->b = NULL; } - if (harq->f) { - free16(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); - harq->f = NULL; + if (dlsch->f) { + free16(dlsch->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + dlsch->f = NULL; } for (int r = 0; r < a_segments; r++) { - free(harq->c[r]); - harq->c[r] = NULL; + free(dlsch->c[r]); + dlsch->c[r] = NULL; } - free(harq->c); + free(dlsch->c); } NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB) @@ -80,34 +79,33 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB) LOG_D(PHY, "Allocating %d segments (MAX %d, N_PRB %d)\n", a_segments, MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER, N_RB); uint32_t dlsch_bytes = a_segments * 1056; // allocated bytes per segment - NR_gNB_DLSCH_t dlsch; + NR_gNB_DLSCH_t dlsch = {0}; - NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process; - bzero(harq, sizeof(NR_DL_gNB_HARQ_t)); - harq->b = malloc16(dlsch_bytes); - AssertFatal(harq->b, "cannot allocate memory for harq->b\n"); - bzero(harq->b, dlsch_bytes); + dlsch.b = malloc16(dlsch_bytes); + AssertFatal(dlsch.b, "cannot allocate memory for dlsch.b\n"); + bzero(dlsch.b, dlsch_bytes); - harq->c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *)); + dlsch.c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *)); for (int r = 0; r < a_segments; r++) { // account for filler in first segment and CRCs for multiple segment case // [hna] 8448 is the maximum CB size in NR // 68*348 = 68*(maximum size of Zc) // In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc) - harq->c[r] = malloc16(8448); - AssertFatal(harq->c[r], "cannot allocate harq->c[%d]\n", r); - bzero(harq->c[r], 8448); + dlsch.c[r] = malloc16(8448); + AssertFatal(dlsch.c[r], "cannot allocate dlsch.c[%d]\n", r); + bzero(dlsch.c[r], 8448); } - harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); - AssertFatal(harq->f, "cannot allocate harq->f\n"); - bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + dlsch.f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + AssertFatal(dlsch.f, "cannot allocate dlsch->f\n"); + bzero(dlsch.f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); return (dlsch); } int nr_dlsch_encoding(PHY_VARS_gNB *gNB, - processingData_L1tx_t *msgTx, + int n_dlsch, + NR_gNB_DLSCH_t *dlsch_array, int frame, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, @@ -122,28 +120,18 @@ 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); - nrLDPC_TB_encoding_parameters_t TBs[msgTx->num_pdsch_slot]; + nrLDPC_TB_encoding_parameters_t TBs[n_dlsch]; memset(TBs, 0, sizeof(TBs)); - nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame, - .slot = slot, - .nb_TBs = msgTx->num_pdsch_slot, - .threadPool = &gNB->threadPool, - .tinput = tinput, - .tprep = tprep, - .tparity = tparity, - .toutput = toutput, - .TBs = TBs}; int num_segments = 0; - for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { - NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; + for (int i = 0; i < n_dlsch; i++) { + NR_gNB_DLSCH_t *dlsch = &dlsch_array[i]; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; unsigned int crc = 1; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15; uint32_t A = rel15->TBSize[0] << 3; - unsigned char *a = harq->pdu; + unsigned char *a = dlsch->pdu; if (rel15->rnti != SI_RNTI) { ws_trace_t tmp = {.nr = true, .direction = DIRECTION_DOWNLINK, @@ -182,9 +170,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, // printf("CRC %x (A %d)\n",crc,A); // printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); B = A + 24; - // harq->b = a; AssertFatal((A / 8) + 4 <= max_bytes, "A %d is too big (A/8+4 = %d > %d)\n", A, (A / 8) + 4, max_bytes); - memcpy(harq->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes? + memcpy(dlsch->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes? } else { // Add 16-bit crc (polynomial A) to payload crc = crc16(a, A) >> 16; @@ -193,21 +180,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, // printf("CRC %x (A %d)\n",crc,A); // printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); B = A + 16; - // harq->b = a; AssertFatal((A / 8) + 3 <= max_bytes, "A %d is too big (A/8+3 = %d > %d)\n", A, (A / 8) + 3, max_bytes); - memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc + memcpy(dlsch->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc } - nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id]; + nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i]; - // The harq_pid is not unique among the active HARQ processes in the instance so we use dlsch_id instead - TB_parameters->harq_unique_pid = dlsch_id; + // The harq_pid is not unique among the active HARQ processes in the instance so we use i instead + TB_parameters->harq_unique_pid = i; TB_parameters->BG = rel15->maintenance_parms_v3.ldpcBaseGraph; - TB_parameters->Z = harq->Z; TB_parameters->A = A; start_meas(dlsch_segmentation_stats); - TB_parameters->Kb = nr_segmentation(harq->b, - harq->c, + TB_parameters->Kb = nr_segmentation(dlsch->b, + dlsch->c, B, &TB_parameters->C, &TB_parameters->K, @@ -228,20 +213,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, size_t segments_offset = 0; size_t dlsch_offset = 0; - for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { - NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + for (int i = 0; i < n_dlsch; i++) { + NR_gNB_DLSCH_t *dlsch = &dlsch_array[i]; + const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15; - nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id]; + nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i]; #ifdef DEBUG_DLSCH_CODING for (int r = 0; r < TB_parameters->C; r++) { - LOG_D(PHY, "Encoder: B %d F %d \n", harq->B, TB_parameters->F); + LOG_D(PHY, "Encoder: B %d F %d \n", dlsch->B, TB_parameters->F); LOG_D(PHY, "start ldpc encoder segment %d/%d\n", r, TB_parameters->C); - LOG_D(PHY, "input %d %d %d %d %d \n", harq->c[r][0], harq->c[r][1], harq->c[r][2], harq->c[r][3], harq->c[r][4]); + LOG_D(PHY, "input %d %d %d %d %d \n", dlsch->c[r][0], dlsch->c[r][1], dlsch->c[r][2], dlsch->c[r][3], dlsch->c[r][4]); for (int cnt = 0; cnt < 22 * (TB_parameters->Z) / 8; cnt++) { - LOG_D(PHY, "%d ", harq->c[r][cnt]); + LOG_D(PHY, "%d ", dlsch->c[r][cnt]); } LOG_D(PHY, "\n"); } @@ -259,7 +243,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, rel15->NrOfSymbols, nb_re_dmrs, get_num_dmrs(rel15->dlDmrsSymbPos), - harq->unav_res, + dlsch->unav_res, rel15->qamModOrder[0], rel15->nrOfLayers); @@ -270,7 +254,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, for (int r = 0; r < TB_parameters->C; r++) { nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r]; - segment_parameters->c = harq->c[r]; + segment_parameters->c = dlsch->c[r]; segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, rel15->nrOfLayers, r); reset_meas(&segment_parameters->ts_interleave); @@ -287,10 +271,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, dlsch_offset += ceil_mod(dlsch_size, 8 * 64); } + nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame, + .slot = slot, + .nb_TBs = n_dlsch, + .threadPool = &gNB->threadPool, + .tinput = tinput, + .tprep = tprep, + .tparity = tparity, + .toutput = toutput, + .TBs = TBs}; gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters); - for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { - nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id]; + for (int i = 0; i < n_dlsch; i++) { + nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i]; for (int r = 0; r < TB_parameters->C; r++) { nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r]; merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c deleted file mode 100644 index 3f1d988c53..0000000000 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ /dev/null @@ -1,62 +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 - */ - -/*! \file PHY/NR_TRANSPORT/nr_dlsch_tools.c -* \brief Top-level routines for decoding DLSCH transport channel from 38-214, V15.2.0 2018-06 -* \author Guy De Souza -* \date 2018 -* \version 0.1 -* \company Eurecom -* \email: desouza@eurecom.fr -* \note - -* \warning -*/ - -#include "nr_dlsch.h" -#include "../../../nfapi/oai_integration/vendor_ext.h" - -void nr_fill_dlsch_dl_tti_req(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu) -{ - NR_gNB_DLSCH_t *dlsch = &msgTx->dlsch[msgTx->num_pdsch_slot][0]; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - /// DLSCH struct - memcpy((void*)&harq->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - AssertFatal(msgTx->num_pdsch_slot == pdsch_pdu->pdsch_pdu_rel15.pduIndex, - "PDSCH PDU index %d does not match msgTx index %d\n", - pdsch_pdu->pdsch_pdu_rel15.pduIndex, - msgTx->num_pdsch_slot); - msgTx->num_pdsch_slot++; - harq->pdu = NULL; -} - -void nr_fill_dlsch_tx_req(processingData_L1tx_t *msgTx, int idx, uint8_t *sdu) -{ - AssertFatal(sdu != NULL, "sdu is null\n"); - - /* not sure if FAPI could transmit DL_TTI_req and TX_req in different orders. - * for the moment, assume they are in the same order (and check!) */ - NR_gNB_DLSCH_t *dlsch = &msgTx->dlsch[idx][0]; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - nfapi_nr_dl_tti_pdsch_pdu *pdsch = &harq->pdsch_pdu; - AssertFatal(pdsch->pdsch_pdu_rel15.pduIndex == idx, "PDSCH PDU index %d does not match %d\n", pdsch->pdsch_pdu_rel15.pduIndex, idx); - harq->pdu = sdu; -} diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 239b6f2f29..24d4950dfa 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -35,7 +35,6 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "SCHED_NR/sched_nr.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/log.h" diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index ef12f20ce5..abc700f9d2 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -53,30 +53,6 @@ typedef struct { int lut[MAX_PUCCH0_NID][160][14]; } NR_gNB_PUCCH0_LUT_t; -typedef struct { - /// Nfapi DLSCH PDU - nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu; - /// pointer to pdu from MAC interface (this is "a" in 36.212) - uint8_t *pdu; - /// Pointer to the payload - uint8_t *b; - /// Pointers to transport block segments - uint8_t **c; - /// Frame where current HARQ round was sent - uint32_t frame; - /// Interleaver outputs - uint8_t *f; - /// LDPC lifting size - uint32_t Z; - /// REs unavailable for DLSCH (overlapping with PTRS, CSIRS etc.) - uint32_t unav_res; -} NR_DL_gNB_HARQ_t; - -typedef struct { - uint8_t active; - nfapi_nr_dl_tti_csi_rs_pdu csirs_pdu; -} NR_gNB_CSIRS_t; - typedef struct { int dump_frame; int round_trials[8]; @@ -121,19 +97,20 @@ typedef struct { } NR_gNB_PHY_STATS_t; typedef struct { - /// Pointers to variables related to DLSCH harq process - NR_DL_gNB_HARQ_t harq_process; - /// Active flag for baseband transmitter processing - uint8_t active; - /// Number of soft channel bits - uint32_t G; + /// Nfapi DLSCH PDU + const nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu; + /// pointer to pdu from MAC interface (this is "a" in 36.212) + uint8_t *pdu; + /// Pointer to the payload + uint8_t *b; + /// Pointers to transport block segments + uint8_t **c; + /// Interleaver outputs + uint8_t *f; + /// REs unavailable for DLSCH (overlapping with PTRS, CSIRS etc.) + uint32_t unav_res; } NR_gNB_DLSCH_t; -typedef struct { - bool active; - nfapi_nr_dl_tti_ssb_pdu ssb_pdu; -} NR_gNB_SSB_t; - typedef struct { uint8_t NumPRSResources; prs_config_t prs_cfg[NR_MAX_PRS_RESOURCES_PER_SET]; @@ -409,6 +386,8 @@ typedef struct PHY_VARS_gNB_s { NR_gNB_COMMON common_vars; prach_list_t prach_list; + // TODO: can we remove c from NR_gNB_DLSCH_t and put it on the stack? + NR_gNB_DLSCH_t *dlsch; NR_gNB_PRS prs_vars; NR_gNB_PUSCH *pusch_vars; NR_gNB_PUCCH_t *pucch; @@ -494,7 +473,6 @@ typedef struct PHY_VARS_gNB_s { time_stats_t rx_pusch_symbol_processing_stats; time_stats_t ul_indication_stats; time_stats_t slot_indication_stats; - time_stats_t schedule_response_stats; time_stats_t ulsch_decoding_stats; time_stats_t ts_deinterleave; time_stats_t ts_rate_unmatch; @@ -522,7 +500,6 @@ typedef struct PHY_VARS_gNB_s { int L1_rx_thread_core; pthread_t L1_tx_thread; int L1_tx_thread_core; - struct processingData_L1tx *msgDataTx; void *scopeData; } PHY_VARS_gNB; @@ -599,16 +576,6 @@ typedef struct processingData_L1tx { int slot_rx; openair0_timestamp timestamp_tx; PHY_VARS_gNB *gNB; - 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[NR_SYMBOLS_PER_SLOT]; - NR_gNB_DLSCH_t **dlsch; - NR_gNB_SSB_t ssb[64]; - uint16_t num_pdsch_slot; - int num_dl_pdcch; - int num_ul_pdcch; - /* a reference to the sched_response, to release it when not needed anymore */ - int sched_response_id; } processingData_L1tx_t; typedef struct processingData_L1rx { diff --git a/openair1/SCHED/nfapi_lte_dummy.c b/openair1/SCHED/nfapi_lte_dummy.c index be532a0c54..fa59cbdb71 100644 --- a/openair1/SCHED/nfapi_lte_dummy.c +++ b/openair1/SCHED/nfapi_lte_dummy.c @@ -9,30 +9,12 @@ typedef struct pnf_p7_t pnf_p7_t; typedef struct vnf_t vnf_t; typedef struct vnf_p7_t vnf_p7_t; -void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, - int frame, int slot, - nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){} - -void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){} - -void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx, - nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, - uint8_t *sdu){ -} -void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, - int frame, int slot, - nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){ - } int l1_north_init_gNB(void){return 0;} int slot_ahead = 6; //uint8_t nfapi_mode=0; NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;} -void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, - int frame, int slot, - nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){} void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, @@ -47,8 +29,6 @@ void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_p void nr_phy_config_request(NR_PHY_Config_t *gNB){} -void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){} - void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){} bool vnf_nr_send_p5_msg(vnf_t *vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t *msg, uint32_t msg_len) diff --git a/openair1/SCHED/nfapi_nr_dummy.c b/openair1/SCHED/nfapi_nr_dummy.c deleted file mode 100644 index 7377a455dd..0000000000 --- a/openair1/SCHED/nfapi_nr_dummy.c +++ /dev/null @@ -1,49 +0,0 @@ -//Dummy NR defs to avoid linking errors - -#include "PHY/defs_gNB.h" -#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" -#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" -#include "openair1/PHY/LTE_TRANSPORT/transport_common.h" - -void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, - int frame, int slot, - nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){} - -void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){} - -void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx, - nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, - uint8_t *sdu){ -} -void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, - int frame, int slot, - nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){ - } -int l1_north_init_gNB(void){return 0;} - -int slot_ahead = 6; -//uint8_t nfapi_mode=0; -NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;} - -void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, - int frame, int slot, - nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){} -void nr_fill_ulsch(PHY_VARS_gNB *gNB, - int frame, - int slot, - nfapi_nr_pusch_pdu_t *ulsch_pdu){} -void nr_fill_pucch(PHY_VARS_gNB *gNB, - int frame, - int slot, - nfapi_nr_pucch_pdu_t *pucch_pdu){} -void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) -{ -} - -void nr_phy_config_request(NR_PHY_Config_t *gNB){} - -void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){} - -//void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){} - diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c deleted file mode 100644 index 9e4ab67efc..0000000000 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ /dev/null @@ -1,232 +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 - */ - -/*! \file fapi_nr_l1.c - * \brief functions for FAPI L1 interface - * \author R. Knopp, WEI-TAI CHEN - * \date 2017, 2018 - * \version 0.1 - * \company Eurecom, NTUST - * \email: knopp@eurecom.fr, kroempa@gmail.com - * \note - * \warning - */ -#include "fapi_nr_l1.h" -#include "common/ran_context.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" -#include "PHY/NR_TRANSPORT/nr_dlsch.h" -#include "PHY/NR_TRANSPORT/nr_dci.h" -#include "nfapi/oai_integration/vendor_ext.h" -#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" -#include "nfapi/oai_integration/nfapi_vnf.h" - -void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,int frame,int slot, - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu) -{ - - AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n", - dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag); - - uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex; - - LOG_D(NR_PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); - if (msgTx->ssb[i_ssb].active) - AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb); - else { - msgTx->ssb[i_ssb].active = true; - memcpy((void*)&msgTx->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu)); - } -} - -void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, int frame, int slot, nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu) -{ - int found = 0; - - for (int id = 0; id < NR_NUMBER_OF_SYMBOLS_PER_SLOT; id++) { - NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[id]; - if (csirs->active == 0) { - LOG_D(NR_PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id); - csirs->active = 1; - memcpy((void*)&csirs->csirs_pdu, (void*)csirs_pdu, sizeof(nfapi_nr_dl_tti_csi_rs_pdu)); - found = 1; - break; - } - } - if (found == 0) - LOG_E(MAC,"CSI-RS list is full\n"); -} - -void nr_schedule_dl_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_request_t *DL_req) -{ - DevAssert(gNB != NULL); - DevAssert(DL_req != NULL); - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - - int frame = DL_req->SFN; - int slot = DL_req->Slot; - - int slot_type = nr_slot_select(cfg, frame, slot); - DevAssert(slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT); - - processingData_L1tx_t *msgTx = gNB->msgDataTx; - msgTx->slot = slot; - msgTx->frame = frame; - - uint8_t number_dl_pdu = DL_req->dl_tti_request_body.nPDUs; - - 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(NR_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; - - case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: - LOG_D(NR_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(NR_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(NR_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); - nr_fill_dlsch_dl_tti_req(msgTx, &dl_tti_pdu->pdsch_pdu); - } - } -} - -void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req) -{ - DevAssert(gNB != NULL); - DevAssert(UL_tti_req != NULL); - - int frame = UL_tti_req->SFN; - int slot = UL_tti_req->Slot; - - for (int i = 0; i < UL_tti_req->n_pdus; i++) { - int type = UL_tti_req->pdus_list[i].pdu_type; - LOG_D(NR_PHY, - "frame %d, slot %d got %s for %d.%d\n", - frame, - slot, - txt_nfapi_nr_ul_config_pdu_type[type], - UL_tti_req->SFN, - UL_tti_req->Slot); - switch (type) { - case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: - nr_fill_ulsch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu); - break; - case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: - nr_fill_pucch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu); - break; - case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: { - nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; - prach_item_t *prach = nr_schedule_rx_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); - if (!prach) - LOG_W(NR_PHY_RACH, "Error in scheduling rach\n"); - } break; - case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: - nr_fill_srs(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].srs_pdu); - break; - } - } -} - -void nr_schedule_tx_req(PHY_VARS_gNB *gNB, nfapi_nr_tx_data_request_t *TX_req) -{ - DevAssert(gNB != NULL); - DevAssert(TX_req != NULL); - processingData_L1tx_t *msgTx = gNB->msgDataTx; - - for (int idx = 0; idx < TX_req->Number_of_PDUs; ++idx) { - uint8_t *sdu = (uint8_t *)TX_req->pdu_list[idx].TLVs[0].value.direct; - nr_fill_dlsch_tx_req(msgTx, idx, sdu); - } -} - -void nr_schedule_ul_dci_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_dci_request_t *UL_dci_req) -{ - DevAssert(gNB != NULL); - DevAssert(UL_dci_req != NULL); - processingData_L1tx_t *msgTx = gNB->msgDataTx; - - msgTx->num_ul_pdcch = UL_dci_req->numPdus; - for (int i = 0; i < UL_dci_req->numPdus; i++) - msgTx->ul_pdcch_pdu[i] = UL_dci_req->ul_dci_pdu_list[i]; -} - -void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) -{ - // copy data from L2 interface into L1 structures - module_id_t Mod_id = Sched_INFO->module_id; - frame_t frame = Sched_INFO->frame; - slot_t slot = Sched_INFO->slot; - - AssertFatal(RC.gNB != NULL, "RC.gNB is null\n"); - AssertFatal(RC.gNB[Mod_id] != NULL, "RC.gNB[%d] is null\n", Mod_id); - - PHY_VARS_gNB *gNB = RC.gNB[Mod_id]; - start_meas(&gNB->schedule_response_stats); - - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - - int slot_type = nr_slot_select(cfg, frame, slot); - - clear_slot_beamid(gNB, slot); // reset beam_id information for the slot to be processed - DevAssert(NFAPI_MODE == NFAPI_MONOLITHIC); - bool is_dl = slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT; - - processingData_L1tx_t *msgTx = gNB->msgDataTx; - /* store the sched_response_id for the TX thread to release it when done */ - msgTx->sched_response_id = Sched_INFO->sched_response_id; - - DevAssert(Sched_INFO->DL_req.SFN == frame); - DevAssert(Sched_INFO->DL_req.Slot == slot); - - if (is_dl) { - nr_schedule_dl_tti_req(gNB, &Sched_INFO->DL_req); - } - - nr_schedule_ul_tti_req(gNB, &Sched_INFO->UL_tti_req); - - if (is_dl) { - nr_schedule_tx_req(gNB, &Sched_INFO->TX_req); - - nr_schedule_ul_dci_req(gNB, &Sched_INFO->UL_dci_req); - /* Both the current thread and the TX thread will access the sched_info - * at the same time, so increase its reference counter, so that it is - * released only when both threads are done with it. - */ - inc_ref_sched_response(Sched_INFO->sched_response_id); - } - - /* this thread is done with the sched_info, decrease the reference counter */ - if ((slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) && NFAPI_MODE == NFAPI_MONOLITHIC) { - LOG_D(NR_PHY, "Calling dref_sched_response for id %d in %d.%d (sched_response)\n", Sched_INFO->sched_response_id, frame, slot); - deref_sched_response(Sched_INFO->sched_response_id); - } - stop_meas(&gNB->schedule_response_stats); -} diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h deleted file mode 100644 index 4d426d92ce..0000000000 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ /dev/null @@ -1,60 +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 - */ - -/*! \file fapi_nr_l1.h - * \brief function prototypes for FAPI L1 interface - * \author R. Knopp, WEI-TAI CHEN - * \date 2017, 2018 - * \version 0.1 - * \company Eurecom, NTUST - * \email: knopp@eurecom.fr, kroempa@gmail.com - * \note - * \warning - */ - -#include "PHY/defs_gNB.h" -#include "SCHED_NR/sched_nr.h" -#include "nfapi_nr_interface_scf.h" - -// added -void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx, - int frame,int slot, - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu); - -void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO); - -void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, - int frame, int slot, - nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu); - -void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, - int frame, int subframe, - nfapi_nr_dl_tti_pdcch_pdu *dcl_dl_pdu); - -void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx, - nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, - uint8_t *sdu); - -//added - -void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, - int frame, int slot, - nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu); diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index e6cd15b4a9..d5d6a8860e 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -33,7 +33,6 @@ #include "PHY/defs_gNB.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "nfapi_nr_interface_scf.h" -#include "fapi_nr_l1.h" #include "nfapi_pnf.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e28d22ede9..e9ff83cf40 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -27,7 +27,6 @@ #include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" -#include "fapi_nr_l1.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/INIT/nr_phy_init.h" @@ -55,9 +54,19 @@ static void nr_fill_indication(PHY_VARS_gNB *gNB, nfapi_nr_crc_t *crc, nfapi_nr_rx_data_pdu_t *pdu); +static void nr_fill_indication(PHY_VARS_gNB *gNB, + int frame, + int slot_rx, + int ULSCH_id, + uint8_t harq_pid, + uint8_t crc_flag, + int dtx_flag, + nfapi_nr_crc_t *crc, + nfapi_nr_rx_data_pdu_t *pdu); + int beam_index_allocation(bool das, int fapi_beam_index, - nfapi_nr_analog_beamforming_ve_t *analog_bf, + const nfapi_nr_analog_beamforming_ve_t *analog_bf, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, @@ -93,10 +102,10 @@ int beam_index_allocation(bool das, return idx; } -void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu) +void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const nfapi_nr_dl_tti_ssb_pdu *ssb_pdu) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &ssb_pdu.ssb_pdu_rel15; + const nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &ssb_pdu->ssb_pdu_rel15; uint8_t ssb_index = pdu->SsbBlockIndex; LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n", frame, slot, ssb_index); @@ -144,7 +153,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n fp->ssb_start_subcarrier); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); - nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; + const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; c16_t ***txdataF = gNB->common_vars.txdataF; int txdataF_offset = slot * fp->samples_per_slot_wCP; // beam number in a scenario with multiple concurrent beams @@ -182,7 +191,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n #endif nr_generate_pbch(gNB, - &ssb_pdu, + ssb_pdu, &txdataF[beam_nb][0][txdataF_offset], ssb_start_symbol, n_hf, @@ -202,12 +211,54 @@ void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot) } } -void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, +static void nr_generate_csi_rs_gNB(PHY_VARS_gNB *gNB, + int slot, + const nfapi_nr_config_request_scf_t *cfg, + const nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu) +{ + const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csi_rs_pdu->csi_rs_pdu_rel15; + if (csi_params->csi_type == 2) // ZP-CSI + return; + + csi_mapping_parms_t mapping_parms = + get_csi_mapping_parms(csi_params->row, csi_params->freq_domain, csi_params->symb_l0, csi_params->symb_l1); + const nfapi_nr_tx_precoding_and_beamforming_t *pb = &csi_params->precodingAndBeamforming; + int csi_bitmap = 0; + int lprime_num = mapping_parms.lprime + 1; + for (int j = 0; j < mapping_parms.size; j++) + csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j]; + int beam_nb = beam_index_allocation(gNB->enable_analog_das, + pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, + &cfg->analog_beamforming_ve, + &gNB->common_vars, + slot, + gNB->frame_parms.symbols_per_slot, + csi_bitmap); + + nr_generate_csi_rs(&gNB->frame_parms, + &mapping_parms, + gNB->TX_AMP, + slot, + csi_params->freq_density, + csi_params->start_rb, + csi_params->nr_of_rbs, + csi_params->symb_l0, + csi_params->symb_l1, + csi_params->row, + csi_params->scramb_id, + csi_params->power_control_offset_ss, + csi_params->cdm_type, + gNB->common_vars.txdataF[beam_nb]); +} + +void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, + const nfapi_nr_dl_tti_request_t *DL_req, + const nfapi_nr_tx_data_request_t *TX_req, + const nfapi_nr_ul_dci_request_t *UL_dci_req, int frame, int slot, int do_meas) { - PHY_VARS_gNB *gNB = msgTx->gNB; const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const int txdataF_offset = slot * fp->samples_per_slot_wCP; @@ -239,82 +290,41 @@ 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,1); - for (int i = 0; i < fp->Lmax; i++) { - if (msgTx->ssb[i].active) { - nr_common_signal_procedures(gNB, frame, slot, msgTx->ssb[i].ssb_pdu); - msgTx->ssb[i].active = false; + for (int i = 0; i < UL_dci_req->numPdus; ++i) + nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); + + int num_pdsch = 0; + for (int i = 0; i < DL_req->dl_tti_request_body.nPDUs; ++i) { + const nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i]; + switch (dl_tti_pdu->PDUType) { + case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: + nr_common_signal_procedures(gNB, frame, slot, &dl_tti_pdu->ssb_pdu); + break; + case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: + nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); + break; + case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: + nr_generate_csi_rs_gNB(gNB, slot, cfg, &dl_tti_pdu->csi_rs_pdu); + break; + case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { + int tx_data_idx = dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15.pduIndex; + DevAssert(tx_data_idx < TX_req->Number_of_PDUs); + // reuse dlsch variables, as there are multiple very large memory + // buffers + gNB->dlsch[num_pdsch].pdsch_pdu = &dl_tti_pdu->pdsch_pdu; + gNB->dlsch[num_pdsch].pdu = (uint8_t *)TX_req->pdu_list[tx_data_idx].TLVs[0].value.direct; + DevAssert(num_pdsch < gNB->max_nb_pdsch); + num_pdsch++; + } break; } } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0); - - int num_pdcch_pdus = msgTx->num_ul_pdcch + msgTx->num_dl_pdcch; - - 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(msgTx, slot, txdataF_offset); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0); - } - msgTx->num_dl_pdcch = 0; - msgTx->num_ul_pdcch = 0; - if (msgTx->num_pdsch_slot > 0) { + if (num_pdsch > 0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); - LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", msgTx->num_pdsch_slot,frame,slot); - nr_generate_pdsch(msgTx, frame, slot); + LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", num_pdsch, frame, slot); + nr_generate_pdsch(gNB, num_pdsch, gNB->dlsch, frame, slot); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } - msgTx->num_pdsch_slot = 0; - - for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){ - NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i]; - if (csirs->active == 1) { - LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; - if (csi_params->csi_type == 2) { // ZP-CSI - csirs->active = 0; - return; - } - csi_mapping_parms_t mapping_parms = get_csi_mapping_parms(csi_params->row, - csi_params->freq_domain, - csi_params->symb_l0, - csi_params->symb_l1); - nfapi_nr_tx_precoding_and_beamforming_t *pb = &csi_params->precodingAndBeamforming; - int csi_bitmap = 0; - int lprime_num = mapping_parms.lprime + 1; - for (int j = 0; j < mapping_parms.size; j++) - csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j]; - int beam_nb = beam_index_allocation(gNB->enable_analog_das, - pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, - &cfg->analog_beamforming_ve, - &gNB->common_vars, - slot, - fp->symbols_per_slot, - csi_bitmap); - - nr_generate_csi_rs(&gNB->frame_parms, - &mapping_parms, - gNB->TX_AMP, - slot, - csi_params->freq_density, - csi_params->start_rb, - csi_params->nr_of_rbs, - csi_params->symb_l0, - csi_params->symb_l1, - csi_params->row, - csi_params->scramb_id, - csi_params->power_control_offset_ss, - csi_params->cdm_type, - gNB->common_vars.txdataF[beam_nb]); - csirs->active = 0; - } - } //apply the OFDM symbol rotation here start_meas(&gNB->phase_comp_stats); @@ -1299,3 +1309,40 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); return pusch_DTX; } + +void nr_save_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req) +{ + DevAssert(gNB != NULL); + DevAssert(UL_tti_req != NULL); + + int frame = UL_tti_req->SFN; + int slot = UL_tti_req->Slot; + + for (int i = 0; i < UL_tti_req->n_pdus; i++) { + int type = UL_tti_req->pdus_list[i].pdu_type; + LOG_D(NR_PHY, + "frame %d, slot %d got %s for %d.%d\n", + frame, + slot, + txt_nfapi_nr_ul_config_pdu_type[type], + UL_tti_req->SFN, + UL_tti_req->Slot); + switch (type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + nr_fill_ulsch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + nr_fill_pucch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: { + nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; + prach_item_t *prach = nr_schedule_rx_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + if (!prach) + LOG_W(NR_PHY_RACH, "Error in scheduling rach\n"); + } break; + case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: + nr_fill_srs(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].srs_pdu); + break; + } + } +} diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 40c32c2199..da71809589 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -33,10 +33,17 @@ #include "phy_frame_config_nr.h" void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp); -void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame_tx, int slot_tx, int do_meas); +void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, + const nfapi_nr_dl_tti_request_t *DL_req, + const nfapi_nr_tx_data_request_t *TX_req, + const nfapi_nr_ul_dci_request_t *UL_dci_req, + int frame, + int slot, + int do_meas); +void nr_save_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req); int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, NR_UL_IND_t *UL_INFO); void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rach_indication_t *rach_ind); -void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu); +void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot, const nfapi_nr_dl_tti_ssb_pdu *ssb_pdu); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx); @@ -49,7 +56,7 @@ void nr_phy_free_RU(RU_t *ru); void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot); int beam_index_allocation(bool das, int fapi_beam_index, - nfapi_nr_analog_beamforming_ve_t *analog_bf, + const nfapi_nr_analog_beamforming_ve_t *analog_bf, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index c475bfc039..ea4a068b6e 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -439,10 +439,7 @@ int main(int argc, char **argv) nr_init_dl_harq_processes(UE->dl_harq_processes, 8, nb_rb); unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; - processingData_L1tx_t msgDataTx; - init_DLSCH_struct(gNB, &msgDataTx); - NR_gNB_DLSCH_t *dlsch = &msgDataTx.dlsch[0][0]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15; + NR_gNB_DLSCH_t *dlsch = &gNB->dlsch[0]; //time_stats_t *rm_stats, *te_stats, *i_stats; unsigned int TBS = 8424; uint8_t nb_re_dmrs = 6; // No data in dmrs symbol @@ -459,19 +456,24 @@ int main(int argc, char **argv) TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl); printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); //dlsch->harq_ids[subframe]= 0; - rel15->rbSize = nb_rb; - rel15->NrOfSymbols = nb_symb_sch; - rel15->qamModOrder[0] = mod_order; - rel15->nrOfLayers = Nl; - rel15->TBSize[0] = TBS>>3; - rel15->targetCodeRate[0] = rate; - rel15->NrOfCodewords = 1; - rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1; - rel15->dlDmrsSymbPos = 4; - rel15->mcsIndex[0] = Imcs; - rel15->numDmrsCdmGrpsNoData = 1; - rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm; - rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate); + nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu = { + .pdsch_pdu_rel15 = { + .rbSize = nb_rb, + .NrOfSymbols = nb_symb_sch, + .qamModOrder[0] = mod_order, + .nrOfLayers = Nl, + .TBSize[0] = TBS >> 3, + .targetCodeRate[0] = rate, + .NrOfCodewords = 1, + .dmrsConfigType = NFAPI_NR_DMRS_TYPE1, + .dlDmrsSymbPos = 4, + .mcsIndex[0] = Imcs, + .numDmrsCdmGrpsNoData = 1, + .maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm, + .maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate), + }, + }; + dlsch->pdsch_pdu = &pdsch_pdu; double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc short channel_output_fixed[16 * 68 * 384]; //unsigned char *estimated_output; @@ -498,7 +500,7 @@ int main(int argc, char **argv) printf("harq process ue mcs = %d Qm = %d, symb %d\n", dlsch0_ue->dlsch_config.mcs, dlsch0_ue->dlsch_config.qamModOrder, nb_symb_sch); uint8_t test_input[TBS / 8 + 4]; // + 3 for CRC + 1 additional byte, see nr_dlsch_encoding() - dlsch->harq_process.pdu = test_input; + dlsch->pdu = test_input; //unsigned char test_input[TBS / 8] __attribute__ ((aligned(16))); for (i = 0; i < TBS / 8; i++) test_input[i] = (unsigned char) rand(); @@ -512,11 +514,10 @@ int main(int argc, char **argv) //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); // generate signal - unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * NR_MAX_NB_LAYERS] __attribute__((aligned(64))); + unsigned char output[nb_rb * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * NR_MAX_NB_LAYERS] __attribute__((aligned(64))); bzero(output, sizeof(output)); if (input_fd == NULL) { - msgDataTx.num_pdsch_slot = 1; - nr_dlsch_encoding(gNB, &msgDataTx, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + nr_dlsch_encoding(gNB, 1, dlsch, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } for (SNR = snr0; SNR < snr1 && !stop; SNR += snr_step) { @@ -622,8 +623,6 @@ int main(int argc, char **argv) free_channel_desc_scm(gNB2UE); - reset_DLSCH_struct(gNB, &msgDataTx); - int nb_slots_to_set = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; for (int i = 0; i < nb_slots_to_set; ++i) free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index c03e3c0046..82984657d3 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -62,7 +62,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/impl_defs_nr.h" #include "PHY/phy_vars_nr_ue.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "SCHED_NR/sched_nr.h" #include "SCHED_NR_UE/defs.h" #include "SCHED_NR_UE/fapi_nr_ue_l1.h" @@ -286,7 +285,6 @@ nrUE_params_t *get_nrUE_params(void) { return &nrUE_params; } - void validate_input_pmi(nfapi_nr_config_request_scf_t *gNB_config, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts, int nrOfLayers, @@ -974,13 +972,6 @@ int main(int argc, char **argv) int ret = 1; initNamedTpool(gNBthreads, &gNB->threadPool, true, "gNB-tpool"); initNotifiedFIFO(&gNB->L1_tx_out); - // we create 2 threads for L1 tx processing - processingData_L1tx_t *msgDataTx = malloc(sizeof(processingData_L1tx_t)); - init_DLSCH_struct(gNB, msgDataTx); - msgDataTx->slot = slot; - msgDataTx->frame = frame; - memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t)); - gNB->msgDataTx = msgDataTx; // Buffers to store internal memory of slot process int rx_size = (((14 * UE->frame_parms.N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4; @@ -1059,8 +1050,13 @@ int main(int argc, char **argv) n_false_positive = 0; if (n_trials== 1) num_rounds = 1; - NR_gNB_DLSCH_t *gNB_dlsch = &msgDataTx->dlsch[0][0]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15; + NR_gNB_DLSCH_t *gNB_dlsch = &gNB->dlsch[0]; + memset(Sched_INFO, 0, sizeof(*Sched_INFO)); + Sched_INFO->sched_response_id = -1; + nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body; + // scheduler will place PDSCH second (after PDCCH), verification below + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; for (trial = 0; trial < n_trials && !stop; trial++) { @@ -1082,11 +1078,9 @@ int main(int argc, char **argv) UE_harq_process->DLround = round; UE_harq_process->first_rx = 1; - memset(Sched_INFO, 0, sizeof(*Sched_INFO)); - Sched_INFO->sched_response_id = -1; - while (round < num_rounds && !UE_harq_process->decodeResult && !stop) { - clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req); + reset_sched_response(Sched_INFO, frame, slot, 0, 0); + clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1); UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round; @@ -1094,18 +1088,13 @@ int main(int argc, char **argv) NR_SCHED_LOCK(&gNB_mac->sched_lock); nr_schedule_ue_spec(0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req); NR_SCHED_UNLOCK(&gNB_mac->sched_lock); - Sched_INFO->module_id = 0; - Sched_INFO->CC_id = 0; - Sched_INFO->frame = frame; - Sched_INFO->slot = slot; - Sched_INFO->UL_dci_req.numPdus = 0; - nr_schedule_response(Sched_INFO); + + /* check that second message is indeed PDSCH */ + DevAssert(dl_tti_pdsch_pdu->PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE); /* PTRS values for DLSIM calculations */ - nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body; - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; pdu_bit_map = pdsch_pdu_rel15->pduBitmap; + // This is already in DL procedures?? if(pdu_bit_map & 0x1) { set_ptrs_symb_idx(&dlPtrsSymPos, pdsch_pdu_rel15->NrOfSymbols, @@ -1113,16 +1102,12 @@ int main(int argc, char **argv) 1<PTRSTimeDensity, pdsch_pdu_rel15->dlDmrsSymbPos); ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, pdsch_pdu_rel15->StartSymbolIndex, pdsch_pdu_rel15->NrOfSymbols); - ptrsRePerSymb = ((rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity); + ptrsRePerSymb = ((pdsch_pdu_rel15->rbSize + pdsch_pdu_rel15->PTRSFreqDensity - 1) / pdsch_pdu_rel15->PTRSFreqDensity); LOG_D(PHY,"[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot, ptrsRePerSymb, ptrsSymbPerSlot * ptrsRePerSymb); } - msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; - msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0; - msgDataTx->gNB = gNB; - start_meas(&gNB->phy_proc_tx); - phy_procedures_gNB_TX(msgDataTx,frame,slot,1); + phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot, 1); stop_meas(&gNB->phy_proc_tx); int txdataF_offset = slot * frame_parms->samples_per_slot_wCP; @@ -1197,9 +1182,9 @@ int main(int argc, char **argv) double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); //Compute AWGN variance - sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; + sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize))) - SNR; sigma2 = pow(10, sigma2_dB/10); - if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize)); + if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize)); for (aa = 0; aa < n_rx; aa++) { bzero(r_re[aa], slot_length * sizeof(double)); @@ -1241,22 +1226,22 @@ int main(int argc, char **argv) int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr; - TBS = dlsch0->dlsch_config.TBS;//rel15->TBSize[0]; + TBS = dlsch0->dlsch_config.TBS; uint16_t length_dmrs = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos); uint16_t nb_rb = dlsch0->dlsch_config.number_rbs; uint8_t nb_re_dmrs = dlsch0->dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*dlsch0->dlsch_config.n_dmrs_cdm_groups : 4*dlsch0->dlsch_config.n_dmrs_cdm_groups; uint8_t mod_order = dlsch0->dlsch_config.qamModOrder; uint8_t nb_symb_sch = dlsch0->dlsch_config.number_symbols; uint32_t unav_res = ptrsSymbPerSlot * ptrsRePerSymb; - available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, unav_res, mod_order, rel15->nrOfLayers); + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, unav_res, mod_order, pdsch_pdu_rel15->nrOfLayers); if (pdu_bit_map & 0x1) { if (trial == 0 && round == 0) { - printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n", available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * rel15->nrOfLayers * mod_order)); + printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n", available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * pdsch_pdu_rel15->nrOfLayers * mod_order)); } } for (i = 0; i < available_bits; i++) { - const uint8_t current_bit = (gNB_dlsch->harq_process.f[i / 8] & (1 << (i & 7))) >> (i & 7); + const uint8_t current_bit = (gNB_dlsch->f[i / 8] & (1 << (i & 7))) >> (i & 7); if (((current_bit == 0) && (UE_llr[i] <= 0)) || ((current_bit == 1) && (UE_llr[i] >= 0))) { if (errors_scrambling[round] == 0) { LOG_D(PHY,"First bit in error in unscrambling = %d\n",i); @@ -1270,13 +1255,13 @@ int main(int argc, char **argv) } // round if (test_input_bit == NULL) { - test_input_bit = (unsigned char *)malloc16(8 * rel15->TBSize[0]); - estimated_output_bit = (unsigned char *)malloc16(8 * rel15->TBSize[0]); + test_input_bit = (unsigned char *)malloc16(8 * pdsch_pdu_rel15->TBSize[0]); + estimated_output_bit = (unsigned char *)malloc16(8 * pdsch_pdu_rel15->TBSize[0]); } for (i = 0; i < TBS; i++) { estimated_output_bit[i] = (UE->phy_sim_dlsch_b[i/8] & (1 << (i & 7))) >> (i & 7); - test_input_bit[i] = (gNB_dlsch->harq_process.b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments + test_input_bit[i] = (gNB_dlsch->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments if (estimated_output_bit[i] != test_input_bit[i]) { if(errors_bit == 0) @@ -1320,7 +1305,7 @@ int main(int argc, char **argv) printf("), Channel BER (%e", berStats[0]); for (int r = 1; r < num_rounds; r++) printf(",%e", berStats[r]); - printf(") Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", roundStats, effRate, effRate / (8 * rel15->TBSize[0]) * 100, 8 * rel15->TBSize[0]); + printf(") Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", roundStats, effRate, effRate / (8 * pdsch_pdu_rel15->TBSize[0]) * 100, 8 * pdsch_pdu_rel15->TBSize[0]); printf("*****************************************\n"); printf("\n"); // writing to csv file @@ -1328,7 +1313,7 @@ int main(int argc, char **argv) fprintf(csv_file,"%f,%d/%d,",SNR,n_false_positive,n_trials); for (int r = 0; r < num_rounds; r++) fprintf(csv_file,"%d/%d,%u/%u,%f,%e,",n_errors[r], round_trials[r], errors_scrambling[r], available_bits * round_trials[r],blerStats[r],berStats[r]); - fprintf(csv_file,"%.2f,%.4f,%.2f,%u\n", roundStats, effRate, effRate / (8 * rel15->TBSize[0]) * 100, 8 * rel15->TBSize[0]); + fprintf(csv_file,"%.2f,%.4f,%.2f,%u\n", roundStats, effRate, effRate / (8 * pdsch_pdu_rel15->TBSize[0]) * 100, 8 * pdsch_pdu_rel15->TBSize[0]); } if (print_perf==1) { printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, C %d, block %d)\n", @@ -1336,7 +1321,7 @@ int main(int argc, char **argv) g_rbSize, g_mcsIndex, UE->dl_harq_processes[0][slot].C, - 8 * rel15->TBSize[0]); + 8 * pdsch_pdu_rel15->TBSize[0]); printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx"); printStatIndent2(&gNB->dci_generation_stats, "DCI encoding time"); printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time"); @@ -1378,8 +1363,8 @@ int main(int argc, char **argv) const uint32_t numReSym = (g_rbSize * 12 + 15) & (~15); for (int l = 0; l < g_nrOfLayers; l++) { for (int r = 0; r < n_rx; r++) { - const int s = rel15->StartSymbolIndex; - const int n = rel15->NrOfSymbols; + const int s = pdsch_pdu_rel15->StartSymbolIndex; + const int n = pdsch_pdu_rel15->NrOfSymbols; for (int i = s; i < s + n; i++) { const uint32_t dmrsBitMap = phy_data.dlsch[0].dlsch_config.dlDmrsSymbPos; const uint32_t dmrsCfg = phy_data.dlsch[0].dlsch_config.dmrsConfigType; @@ -1415,7 +1400,7 @@ int main(int argc, char **argv) break; } - if (effRate >= (eff_tp_check * 8 * rel15->TBSize[0])) { + if (effRate >= (eff_tp_check * 8 * pdsch_pdu_rel15->TBSize[0])) { printf("PDSCH test OK\n"); ret = 0; break; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 4b44b34091..c86744afaa 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -519,10 +519,10 @@ int main(int argc, char **argv) exit(-1); } - processingData_L1tx_t msgDataTx; // generate signal const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP; __attribute__ ((aligned(32))) c16_t rxdataF[UE->frame_parms.nb_antennas_rx][rxdataF_sz]; + nfapi_nr_dl_tti_ssb_pdu ssb_pdu[64] = {0}; if (input_fd==NULL) { for (i=0; iLmax; i++) { @@ -530,10 +530,10 @@ int main(int argc, char **argv) const int sc_offset = frame_parms->freq_range == FR1 ? ssb_subcarrier_offset<freq_range == FR1 ? gNB->gNB_config.ssb_table.ssb_offset_point_a.value<gNB_config.ssb_table.ssb_offset_point_a.value << (mu - 2); - msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33; - msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i; - msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset; - msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = prb_offset; + ssb_pdu[i].ssb_pdu_rel15.bchPayload = 0x55dd33; + ssb_pdu[i].ssb_pdu_rel15.SsbBlockIndex = i; + ssb_pdu[i].ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset; + ssb_pdu[i].ssb_pdu_rel15.ssbOffsetPointA = prb_offset; start_symbol = nr_get_ssb_start_symbol(frame_parms,i); int slot = start_symbol/14; @@ -541,7 +541,7 @@ int main(int argc, char **argv) for (aa=0; aaframe_parms.nb_antennas_tx; aa++) memset(gNB->common_vars.txdataF[0][aa], 0, frame_parms->samples_per_slot_wCP * sizeof(int32_t)); - nr_common_signal_procedures (gNB,frame,slot,msgDataTx.ssb[i].ssb_pdu); + nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]); int samp = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { @@ -744,7 +744,7 @@ int main(int argc, char **argv) gNB->gNB_config.ssb_table.ssb_subcarrier_offset.value, frame_parms->Lmax); int payload_ret = (result.xtra_byte == xtra_byte); - nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15; + nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &ssb_pdu[ssb_index].ssb_pdu_rel15; for (int i = 0; i < 3; i++) payload_ret += (result.decoded_output[i] == ((pdu->bchPayload >> (8 * i)) & 0xff)); // printf("ret %d\n", payload_ret); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b7f93cdf3a..85c165b00d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -60,7 +60,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/impl_defs_nr.h" #include "PHY/phy_vars_nr_ue.h" -#include "SCHED_NR/fapi_nr_l1.h" #include "SCHED_NR/sched_nr.h" #include "SCHED_NR_UE/defs.h" #include "SCHED_NR_UE/fapi_nr_ue_l1.h" @@ -727,11 +726,6 @@ int main(int argc, char *argv[]) else initNamedTpool(gNBthreads, &gNB->threadPool, true, "gNB-tpool"); - processingData_L1tx_t *msgDataTx = malloc(sizeof(processingData_L1tx_t)); - msgDataTx->slot = -1; - gNB->msgDataTx = msgDataTx; - //gNB_config = &gNB->gNB_config; - NR_UL_IND_t UL_INFO = {0}; UL_INFO.crc_ind.crc_list = UL_INFO.crc_pdu_list; UL_INFO.rx_ind.pdu_list = UL_INFO.rx_pdu_list; @@ -1284,6 +1278,9 @@ int main(int argc, char *argv[]) srs_pdu->beamforming.prg_size = 1; } + /* load FAPI into RX of L1 */ + nr_save_ul_tti_req(gNB, &Sched_INFO->UL_tti_req); + /// UE UL PDUs UE->ul_harq_processes[harq_pid].round = round; @@ -1291,9 +1288,6 @@ int main(int argc, char *argv[]) UE_proc.frame_tx = frame; UE_proc.gNB_id = 0; - // prepare ULSCH/PUSCH reception - nr_schedule_response(Sched_INFO); - // --------- setting parameters for UE -------- nr_scheduled_response_t scheduled_response = {.ul_config = &ul_config, .phy_data = (void *)&phy_data}; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index a102411721..6a9cce656a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -59,13 +59,7 @@ uint8_t nr_get_rv(int rel_round) return nr_rv_round_map[rel_round]; } -void clear_nr_nfapi_information(gNB_MAC_INST *gNB, - int CC_idP, - frame_t frameP, - slot_t slotP, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req, - nfapi_nr_ul_dci_request_t *UL_dci_req) +void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, frame_t frameP, slot_t slotP) { /* called below and in simulators, so we assume a lock but don't require it */ const int num_slots = gNB->frame_structure.numb_slots_frame; @@ -75,16 +69,8 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, gNB->pdu_index[CC_idP] = 0; - DL_req[CC_idP].SFN = frameP; - DL_req[CC_idP].Slot = slotP; - DL_req[CC_idP].dl_tti_request_body.nPDUs = 0; - DL_req[CC_idP].dl_tti_request_body.nGroup = 0; memset(pdcch, 0, sizeof(*pdcch) * MAX_NUM_CORESET); - UL_dci_req[CC_idP].SFN = frameP; - UL_dci_req[CC_idP].Slot = slotP; - UL_dci_req[CC_idP].numPdus = 0; - /* advance last round's future UL_tti_req to be ahead of current frame/slot */ const int size = gNB->UL_tti_req_ahead_size; const int prev_slot = frameP * num_slots + slotP + size - 1; @@ -100,8 +86,6 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, future_ul_tti_req->n_ulsch = 0; future_ul_tti_req->n_ulcch = 0; future_ul_tti_req->n_group = 0; - - TX_req[CC_idP].Number_of_PDUs = 0; } static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame) @@ -191,7 +175,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL[i]; memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE); } - clear_nr_nfapi_information(gNB, CC_id, frame, slot, &sched_info->DL_req, &sched_info->TX_req, &sched_info->UL_dci_req); + clear_nr_nfapi_information(gNB, CC_id, frame, slot); } bool wait_prach_completed = gNB->num_scheduled_prach_rx >= NUM_PRACH_RX_FOR_NOISE_ESTIMATE; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 41f6fd5755..29398c9edf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -67,13 +67,7 @@ int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs); int nr_transmission_action_indicator_stop(gNB_MAC_INST *mac, NR_UE_info_t *UE_info); -void clear_nr_nfapi_information(gNB_MAC_INST *gNB, - int CC_idP, - frame_t frameP, - slot_t slotP, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req, - nfapi_nr_ul_dci_request_t *UL_dci_req); +void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, frame_t frameP, slot_t slotP); void nr_mac_update_timers(module_id_t module_id, frame_t frame, slot_t slot); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 2352870ace..18944a8099 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -41,7 +41,6 @@ #include "nfapi/oai_integration/gnb_ind_vars.h" #include "nfapi/oai_integration/vendor_ext.h" #include "nfapi_interface.h" -#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" #include "openair2/PHY_INTERFACE/queue_t.h" #include "utils.h" #include "nfapi/oai_integration/nfapi_pnf.h" @@ -379,52 +378,25 @@ static void match_crc_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, nfapi_nr_crc } } -extern void handle_nr_slot_ind(uint16_t sfn, uint16_t slot); -static void pnf_send_slot_ind(module_id_t module_id, int CC_id, int frame, int slot) +extern void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_response); +static void pnf_send_slot_ind(const nfapi_nr_slot_indication_scf_t *ind, NR_Sched_Rsp_t *rsp) { - (void)module_id; - (void)CC_id; - handle_nr_slot_ind(frame, slot); + module_id_t module_id = 0; + int CC_id = 0; + reset_sched_response(rsp, ind->sfn, ind->slot, module_id, CC_id); + handle_nr_slot_ind(ind->sfn, ind->slot, rsp); } -static void run_scheduler_monolithic(module_id_t module_id, int CC_id, int frame, int slot) +static void run_scheduler_monolithic(const nfapi_nr_slot_indication_scf_t *ind, NR_Sched_Rsp_t *rsp) { - NR_IF_Module_t *ifi = nr_if_inst[module_id]; - - LOG_D(NR_MAC, "Calling scheduler for %d.%d\n", frame, slot); - NR_Sched_Rsp_t *sched_info = allocate_sched_response(); - - // clear UL DCI prior to handling ULSCH - sched_info->UL_dci_req.numPdus = 0; - gNB_dlsch_ulsch_scheduler(module_id, frame, slot, sched_info); - ifi->CC_mask = 0; - sched_info->module_id = module_id; - sched_info->CC_id = CC_id; - sched_info->frame = frame; - sched_info->slot = slot; - /* - sched_info->DL_req = &mac->DL_req[CC_id]; - sched_info->UL_dci_req = &mac->UL_dci_req[CC_id]; - - sched_info->UL_tti_req = mac->UL_tti_req[CC_id]; - - sched_info->TX_req = &mac->TX_req[CC_id]; - */ -#ifdef DUMP_FAPI - dump_dl(sched_info); -#endif - - AssertFatal(ifi->NR_Schedule_response != NULL, "nr_schedule_response is null (mod %d, cc %d)\n", module_id, CC_id); - ifi->NR_Schedule_response(sched_info); - - LOG_D(NR_PHY, - "NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n", - sched_info->frame, - sched_info->slot, - sched_info->DL_req.dl_tti_request_body.nPDUs); + module_id_t module_id = 0; + int CC_id = 0; + reset_sched_response(rsp, ind->sfn, ind->slot, module_id, CC_id); + gNB_dlsch_ulsch_scheduler(rsp->module_id, ind->sfn, ind->slot, rsp); } -void NR_UL_indication(NR_UL_IND_t *UL_info) { +static void NR_UL_indication(NR_UL_IND_t *UL_info) +{ AssertFatal(UL_info!=NULL,"UL_info is null\n"); module_id_t module_id = UL_info->module_id; int CC_id = UL_info->CC_id; @@ -501,17 +473,47 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { nr_if_inst[Mod_id]->CC_mask=0; nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication; - if (NFAPI_MODE == NFAPI_MONOLITHIC) + if (NFAPI_MODE == NFAPI_MONOLITHIC) { nr_if_inst[Mod_id]->NR_slot_indication = run_scheduler_monolithic; - else if (NFAPI_MODE == NFAPI_MODE_PNF) + } else if (NFAPI_MODE == NFAPI_MODE_PNF) { nr_if_inst[Mod_id]->NR_slot_indication = pnf_send_slot_ind; - else // NFAPI_MODE_VNF - NULL; + } else { // NFAPI_MODE_VNF + DevAssert(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL); + nr_if_inst[Mod_id]->NR_slot_indication = run_scheduler_monolithic; + } AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0, "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id); } - init_sched_response(); - return nr_if_inst[Mod_id]; } + +void reset_sched_response(NR_Sched_Rsp_t *sched_response, int frame, int slot, int module_id, int CC_id) +{ + sched_response->module_id = module_id; + sched_response->CC_id = CC_id; + sched_response->frame = frame; + sched_response->slot = slot; + + + nfapi_nr_dl_tti_request_t *DL_req = &sched_response->DL_req; + DL_req->SFN = frame; + DL_req->Slot = slot; + DL_req->dl_tti_request_body.nPDUs = 0; + DL_req->dl_tti_request_body.nGroup = 0; + + nfapi_nr_ul_dci_request_t *UL_dci_req = &sched_response->UL_dci_req; + UL_dci_req->SFN = frame; + UL_dci_req->Slot = slot; + UL_dci_req->numPdus = 0; + + nfapi_nr_ul_tti_request_t *UL_tti_req = &sched_response->UL_tti_req; + UL_tti_req->SFN = frame; + UL_tti_req->Slot = slot; + UL_tti_req->n_pdus = 0; + + nfapi_nr_tx_data_request_t *TX_req = &sched_response->TX_req; + TX_req->SFN = frame; + TX_req->Slot = slot; + TX_req->Number_of_PDUs = 0; +} diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 52a0f28871..49219a0af1 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -91,7 +91,7 @@ typedef struct { // Downlink slot P7 -typedef struct { +typedef struct NR_Sched_Rsp { /// the ID of this sched_response - used by sched_reponse memory management int sched_response_id; /// Module ID @@ -111,6 +111,7 @@ typedef struct { /// Pointers to DL SDUs nfapi_nr_tx_data_request_t TX_req; } NR_Sched_Rsp_t; +void reset_sched_response(NR_Sched_Rsp_t *sched_response, int frame, int slot, int module_id, int CC_id); typedef struct { uint8_t Mod_id; @@ -121,8 +122,7 @@ typedef struct { typedef struct NR_IF_Module_s { //define the function pointer void (*NR_UL_indication)(NR_UL_IND_t *UL_INFO); - void (*NR_Schedule_response)(NR_Sched_Rsp_t *Sched_INFO); - void (*NR_slot_indication)(module_id_t module_idP, int CC_id, int frame, int slot); + void (*NR_slot_indication)(const nfapi_nr_slot_indication_scf_t *ind, NR_Sched_Rsp_t *rsp); void (*NR_PHY_config_req)(NR_PHY_Config_t *config_INFO); uint32_t CC_mask; uint16_t current_frame; @@ -136,9 +136,4 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id); void NR_IF_Module_kill(int Mod_id); -void NR_UL_indication(NR_UL_IND_t *UL_INFO); - -/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ -void NR_Schedule_Response(NR_Sched_Rsp_t *Sched_INFO); - #endif /*_NFAPI_INTERFACE_NR_H_*/ diff --git a/openair2/NR_PHY_INTERFACE/nr_sched_response.c b/openair2/NR_PHY_INTERFACE/nr_sched_response.c deleted file mode 100644 index 9c66b21536..0000000000 --- a/openair2/NR_PHY_INTERFACE/nr_sched_response.c +++ /dev/null @@ -1,157 +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 - */ - -/* sched response memory management */ - -/* A system with reference counting is implemented. - * It is needed because several threads will access the structure, - * which has to be released only when all the threads are done with it. - * So the main thread allocates a sched_response with allocate_sched_response() - * which allocates a sched_response with a reference counter == 1 - * and then for each other thread that will access sched_response, a - * call to inc_ref_sched_response() is done. When a thread has finished - * using the sched_response, it calls deref_sched_response() which will - * in turn call release_sched_response() when the reference counter becomes 0. - * - * The several threads in question are accessing the _same_ sched_response, - * it has not to be confused with the various TX processes that may run in - * parallel and which are accessing _different_ sched_response (the maximum - * number of parallel processes is N_RESP). - */ - -#include "nr_sched_response.h" -#include -#include -#include -#include "NR_PHY_INTERFACE/NR_IF_Module.h" -#include "common/utils/LOG/log.h" -#include "common/utils/assertions.h" - -#define N_RESP 3 -static NR_Sched_Rsp_t resp[N_RESP]; -static int resp_refcount[N_RESP]; -static int resp_freelist_next[N_RESP]; -static int resp_freelist_head; -static pthread_mutex_t resp_mutex = PTHREAD_MUTEX_INITIALIZER; -static bool resp_freelist_inited = false; - -void init_sched_response(void) -{ - /* init only once */ - if (pthread_mutex_lock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_lock failed\n"); - if (resp_freelist_inited) { - if (pthread_mutex_unlock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_unlock failed\n"); - return; - } - resp_freelist_inited = true; - if (pthread_mutex_unlock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_unlock failed\n"); - - int i; - for (i = 0; i < N_RESP - 1; i++) - resp_freelist_next[i] = i + 1; - resp_freelist_next[N_RESP - 1] = -1; - resp_freelist_head = 0; -} - -NR_Sched_Rsp_t *allocate_sched_response(void) -{ - NR_Sched_Rsp_t *ret; - int new_head; - - if (pthread_mutex_lock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_lock failed\n"); - - AssertFatal(resp_freelist_inited, "sched_response used before init\n"); - - if (resp_freelist_head == -1) { - LOG_E(PHY, "fatal: sched_response cannot be allocated, increase N_RESP\n"); - exit(1); - } - - ret = &resp[resp_freelist_head]; - ret->sched_response_id = resp_freelist_head; - resp_refcount[resp_freelist_head] = 1; - - new_head = resp_freelist_next[resp_freelist_head]; - resp_freelist_next[resp_freelist_head] = -1; - resp_freelist_head = new_head; - - if (pthread_mutex_unlock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_unlock failed\n"); - - return ret; -} - -static void release_sched_response(int sched_response_id) -{ - LOG_D(NR_MAC,"Releasing sched_response %d\n",sched_response_id); - resp_freelist_next[sched_response_id] = resp_freelist_head; - resp_freelist_head = sched_response_id; -} - -void deref_sched_response(int sched_response_id) -{ - /* simulators (ulsim/dlsim) deal with their own sched_response but call - * functions that call this one, let's handle this case with a special - * value -1 where we do nothing (yes it's a hack) - */ - if (sched_response_id == -1) - return; - - if (pthread_mutex_lock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_lock failed\n"); - - AssertFatal(resp_freelist_inited, "sched_response used before init\n"); - AssertFatal(resp_refcount[sched_response_id] > 0, "sched_reponse decreased too much\n"); - - LOG_D(NR_MAC,"resp_refcount[%d] %d\n",sched_response_id,resp_refcount[sched_response_id]); - resp_refcount[sched_response_id]--; - if (resp_refcount[sched_response_id] == 0) - release_sched_response(sched_response_id); - - if (pthread_mutex_unlock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_unlock failed\n"); -} - -void inc_ref_sched_response(int sched_response_id) -{ - /* simulators (ulsim/dlsim) deal with their own sched_response but call - * functions that call this one, let's handle this case with a special - * value -1 where we do nothing (yes it's a hack) - */ - if (sched_response_id == -1) - return; - - LOG_D(NR_MAC,"Incrementing sched_resp resp_refounct[%d] = %d\n", - sched_response_id,resp_refcount[sched_response_id]); - if (pthread_mutex_lock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_lock failed\n"); - - AssertFatal(resp_freelist_inited, "sched_response used before init\n"); - - resp_refcount[sched_response_id]++; - - if (pthread_mutex_unlock(&resp_mutex)) - AssertFatal(0, "pthread_mutex_unlock failed\n"); -} diff --git a/openair2/NR_PHY_INTERFACE/nr_sched_response.h b/openair2/NR_PHY_INTERFACE/nr_sched_response.h deleted file mode 100644 index 33a0af93d0..0000000000 --- a/openair2/NR_PHY_INTERFACE/nr_sched_response.h +++ /dev/null @@ -1,32 +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 - */ - -#ifndef OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H -#define OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H - -#include "NR_IF_Module.h" - -void init_sched_response(void); -NR_Sched_Rsp_t *allocate_sched_response(void); -void deref_sched_response(int sched_response_id); -void inc_ref_sched_response(int sched_response_id); - -#endif /* OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H */ diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-pnf.band78.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-pnf.band78.rfsim.conf index 887ff6eced..08691c3b62 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-pnf.band78.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-pnf.band78.rfsim.conf @@ -22,6 +22,7 @@ RUs = ({ att_tx = 0 att_rx = 0; bands = [78]; + sl_ahead = 2; max_pdschReferenceSignalPower = -27; max_rxgain = 125; });