├── LICENSE ├── Makefile ├── README.md ├── acc100 ├── acc100_cfg_app.c ├── acc100_cfg_app.h ├── acc100_cfg_parser.c ├── acc100_config.cfg ├── acc100_config_1vf_4g5g.cfg ├── acc100_config_1vf_5g.cfg ├── acc100_config_2vf_4g5g.cfg ├── acc100_config_4vf_4g5g.cfg ├── acc100_config_pf.cfg ├── acc100_config_pf_4g5g.cfg ├── acc100_config_vf.cfg ├── acc100_config_vf_4g.cfg ├── acc100_config_vf_5g.cfg └── acc100_pf_enum.h ├── agx100 ├── agx100_cfg_app.c ├── agx100_cfg_app.h ├── agx100_cfg_parser.c ├── agx100_config.cfg ├── agx100_config_1vf.cfg ├── agx100_config_2vf.cfg ├── agx100_config_4vf.cfg └── agx100_config_8vf.cfg ├── bb_acc.h ├── bb_acc_common.c ├── bb_acc_log.c ├── bb_acc_log.h ├── bb_acc_reg_dump.h ├── bb_acc_vfio.c ├── bsd-3-clause.txt ├── build.sh ├── cfg_reader ├── cfg_reader.c └── cfg_reader.h ├── config_app.c ├── daemon.c ├── fpga_5gnr ├── fpga_5gnr_cfg_app.c ├── fpga_5gnr_cfg_app.h ├── fpga_5gnr_cfg_parser.c ├── fpga_5gnr_config.cfg ├── fpga_5gnr_config_1vf.cfg └── fpga_5gnr_config_vf.cfg ├── fpga_lte ├── fpga_lte_cfg_app.c ├── fpga_lte_cfg_app.h ├── fpga_lte_cfg_parser.c ├── fpga_lte_config.cfg └── fpga_lte_config_vf.cfg ├── pf_bb_config_cli.h ├── rel_notes.txt ├── security.md ├── vrb1 ├── srs_fft_windows_coefficient.bin ├── srs_fft_windows_coefficient.txt ├── srs_fft_windows_coefficient_legacy.bin ├── srs_fft_windows_coefficient_wide.bin ├── vrb1_cfg_app.c ├── vrb1_cfg_app.h ├── vrb1_cfg_parser.c ├── vrb1_config.cfg ├── vrb1_config_16vf.cfg ├── vrb1_config_pf.cfg ├── vrb1_config_pf_4g.cfg ├── vrb1_config_pf_5g.cfg ├── vrb1_config_vf_4g.cfg ├── vrb1_config_vf_5g.cfg ├── vrb1_fft_lut.h └── vrb1_pf_enum.h └── vrb2 ├── srs_fft_windows_coefficient.bin ├── srs_fft_windows_coefficient.txt ├── srs_fft_windows_coefficient_legacy.bin ├── srs_fft_windows_coefficient_vrb2.bin ├── srs_fft_windows_coefficient_wide.bin ├── vrb2_cfg_app.c ├── vrb2_cfg_app.h ├── vrb2_cfg_parser.c ├── vrb2_config_pf.cfg ├── vrb2_config_vf.cfg ├── vrb2_config_vf_5g.cfg └── vrb2_pf_enum.h /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 © Intel Corporation 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #****************************************************************************** 2 | # 3 | # Copyright (c) 2020 Intel. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | #******************************************************************************/ 18 | 19 | CC=gcc 20 | CFLAGS=-Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE -z relro -z now -z noexecstack -s -O1 21 | ODIR=build 22 | DEPS= 23 | 24 | INCLUDE=-I. -I./acc100 -I./vrb1 -I./vrb2 -I./fpga_lte -I./fpga_5gnr -I./agx100 -I./cfg_reader 25 | LDFLAGS=-L. 26 | 27 | SRC = config_app.c acc100/acc100_cfg_app.c acc100/acc100_cfg_parser.c \ 28 | fpga_lte/fpga_lte_cfg_app.c fpga_lte/fpga_lte_cfg_parser.c \ 29 | fpga_5gnr/fpga_5gnr_cfg_app.c fpga_5gnr/fpga_5gnr_cfg_parser.c \ 30 | vrb1/vrb1_cfg_app.c vrb1/vrb1_cfg_parser.c cfg_reader/cfg_reader.c \ 31 | vrb2/vrb2_cfg_app.c vrb2/vrb2_cfg_parser.c \ 32 | agx100/agx100_cfg_app.c agx100/agx100_cfg_parser.c \ 33 | bb_acc_vfio.c daemon.c bb_acc_log.c bb_acc_common.c 34 | OBJ = $(patsubst %.c,$(ODIR)/%.o,$(SRC)) 35 | 36 | .PHONY: clean 37 | 38 | all: pf_bb_config 39 | 40 | $(ODIR): 41 | mkdir -p $(ODIR) 42 | 43 | $(OBJ): $(ODIR)/%.o: ./%.c | $(DEPS) $(ODIR) 44 | @mkdir -p $(@D) 45 | $(CC) -c -o $@ $< $(CFLAGS) $(INCLUDE) 46 | 47 | pf_bb_config: $(OBJ) 48 | $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) 49 | 50 | clean: 51 | rm -rf $(ODIR) 52 | rm -rf pf_bb_config 53 | -------------------------------------------------------------------------------- /acc100/acc100_cfg_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _ACC100_CFG_APP_H_ 20 | #define _ACC100_CFG_APP_H_ 21 | 22 | #define ACC100_DDR_ECC_ENABLE 23 | 24 | #define BYTES_IN_WORD 4 25 | #define WORDS_IN_ARAM_SIZE (128 * 1024 / 4) 26 | 27 | #define ACC100_NUM_QGRPS 8 28 | #define ACC100_NUM_TMPL 32 29 | #define ACC100_NUM_AQS 16 30 | #define ACC100_MAX_QDEPTH 12 31 | #define VF_OFFSET_QOS 16 /* offset in Memory Space specific to QoS Mon */ 32 | #define TMPL_PRI_0 0x03020100 33 | #define TMPL_PRI_1 0x07060504 34 | #define TMPL_PRI_2 0x0b0a0908 35 | #define TMPL_PRI_3 0x0f0e0d0c 36 | 37 | #define SIG_UL_5G 0 38 | #define SIG_UL_5G_LAST 7 39 | #define SIG_DL_5G 13 40 | #define SIG_DL_5G_LAST 15 41 | #define SIG_UL_4G 16 42 | #define SIG_UL_4G_LAST 21 43 | #define SIG_DL_4G 27 44 | #define SIG_DL_4G_LAST 31 45 | 46 | #define ACC100_NUM_VFS 16 /**< Number of Virtual Functions ACC100 supports */ 47 | #define ACC100_QMGR_BA_STRIDE 64 /**< Base address stride for Qmgr */ 48 | #define ACC100_INFO_RING_NUM_ENTRIES 1024 49 | 50 | /* ACC100 Configuration */ 51 | #define ACC100_CFG_DDR_ECC_EN 0x842304 52 | #define ACC100_CFG_DDR_ECC_DIS 0x842300 53 | #define ACC100_CFG_DMA_ERROR 0x3D7 54 | #define ACC100_CFG_AXI_CACHE 0x11 55 | #define ACC100_CFG_QMGR_HI_P 0x0F0F 56 | #define ACC100_CFG_PCI_AXI 0xC003 57 | #define ACC100_CFG_PCI_BRIDGE 0x40006033 58 | #define ACC100_QUAD_NUMS 4 59 | #define ACC100_LANES_PER_QUAD 4 60 | #define ACC100_PCIE_LANE_OFFSET 0x200 61 | #define ACC100_PCIE_QUAD_OFFSET 0x2000 62 | #define ACC100_PCS_EQ 0x6007 63 | #define ACC100_ADAPT 0x8400 64 | #define ACC100_CLOCK_GATING_EN 0x30000 65 | /* DDR Size to be split across VFs */ 66 | #define ACC100_HARQ_TOTAL_DDR (4096) 67 | #define ACC100_PRQ_DDR_VER 0x10092020 68 | #define ACC100_MS_IN_US (1000) 69 | #define ACC100_DDR_TRAINING_MAX (5000) 70 | #define ACC100_FABRIC_MODE 0xB 71 | #define ACC100_ROM_VER_SKU_A 0x5 72 | #define ACC100_ROM_VER_SKU_B 0x7 73 | 74 | 75 | #define ACC100_5GUL_ENGS 8 76 | #define ACC100_5GDL_ENGS 3 77 | #define ACC100_PMON_OFF_1 256 78 | #define ACC100_PMON_OFF_2 16 79 | /** 80 | * Definition of Queue Topology for ACC100 Configuration 81 | * Some level of details is abstracted out to expose a clean interface 82 | * given that comprehensive flexibility is not required 83 | */ 84 | struct q_topology_t { 85 | /** Number of QGroups for DL/UL in incremental order of priority */ 86 | uint16_t num_qgroups; 87 | /** 88 | * All QGroups have the same number of AQs here. 89 | * Note : Could be made a 16-array if more flexibility is really 90 | * required 91 | */ 92 | uint16_t num_aqs_per_groups; 93 | /** 94 | * Depth of the AQs is the same of all QGroups here. Log2 Enum : 2^N 95 | * Note : Could be made a 16-array if more flexibility is really 96 | * required 97 | */ 98 | uint16_t aq_depth_log2; 99 | }; 100 | 101 | /** 102 | * Definition of Arbitration related parameters for ACC100 Configuration for UL 103 | * or DL 104 | */ 105 | struct arbitration_t { 106 | /** Default Weight for VF Fairness Arbitration */ 107 | uint16_t round_robin_weight; 108 | uint32_t gbr_threshold1; /**< Guaranteed Bitrate Threshold 1 */ 109 | uint32_t gbr_threshold2; /**< Guaranteed Bitrate Threshold 2 */ 110 | }; 111 | 112 | /** 113 | * Structure to pass ACC100 configuration. 114 | * Note: all VF Bundles will have the same configuration. 115 | */ 116 | struct acc100_conf { 117 | bool pf_mode_en; /**< 1 if PF is used for dataplane, 0 for VFs */ 118 | /** 1 if input '1' bit is represented by a positive LLR value, 0 if '1' 119 | * bit is represented by a negative value. 120 | */ 121 | bool input_pos_llr_1_bit; 122 | /** 1 if output '1' bit is represented by a positive value, 0 if '1' 123 | * bit is represented by a negative value. 124 | */ 125 | bool output_pos_llr_1_bit; 126 | uint16_t num_vf_bundles; /**< Number of VF bundles to setup */ 127 | struct q_topology_t q_ul_4g; /**< Uplink queues */ 128 | struct q_topology_t q_dl_4g; /**< Downlink queues */ 129 | struct q_topology_t q_ul_5g; /**< Uplink queues */ 130 | struct q_topology_t q_dl_5g; /**< Downlink queues */ 131 | /** Uplink arbitration configuration */ 132 | struct arbitration_t arb_ul_4g[ACC100_NUM_VFS]; 133 | /** Downlink arbitration configuration */ 134 | struct arbitration_t arb_dl_4g[ACC100_NUM_VFS]; 135 | /** Uplink arbitration configuration */ 136 | struct arbitration_t arb_ul_5g[ACC100_NUM_VFS]; 137 | /** Downlink arbitration configuration */ 138 | struct arbitration_t arb_dl_5g[ACC100_NUM_VFS]; 139 | }; 140 | 141 | typedef struct { 142 | char *name; 143 | bool use_det_info; 144 | } acc100_ir_int_type_info; 145 | 146 | /* Union describing Info Ring entry */ 147 | union acc100_info_ring_data { 148 | uint32_t val; 149 | struct { 150 | union { 151 | uint16_t detailed_info; 152 | struct { 153 | uint16_t aq_id: 4; 154 | uint16_t qg_id: 4; 155 | uint16_t vf_id: 6; 156 | uint16_t reserved: 2; 157 | }; 158 | }; 159 | uint16_t int_nb: 7; 160 | uint16_t msi_0: 1; 161 | uint16_t vf2pf: 6; 162 | uint16_t loop: 1; 163 | uint16_t valid: 1; 164 | }; 165 | } __attribute__((packed)); 166 | 167 | 168 | /* 169 | * Configure ACC100 170 | */ 171 | 172 | extern int 173 | acc100_parse_conf_file(const char *file_name, struct acc100_conf *acc100_conf); 174 | 175 | #endif /* _ACC100_CFG_APP_H_ */ 176 | 177 | -------------------------------------------------------------------------------- /acc100/acc100_cfg_parser.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "cfg_reader.h" 27 | #include "acc100_cfg_app.h" 28 | 29 | /* Names of sections used in the configuration file */ 30 | #define MODE "MODE" 31 | #define LLR_SIGN "LLR_SIGN" 32 | #define VFBUNDLES "VFBUNDLES" 33 | #define MAXQSIZE "MAXQSIZE" 34 | #define QUL4G "QUL4G" 35 | #define QDL4G "QDL4G" 36 | #define QUL5G "QUL5G" 37 | #define QDL5G "QDL5G" 38 | #define ARBUL4G "ARBUL4G" 39 | #define ARBDL4G "ARBDL4G" 40 | #define ARBUL5G "ARBUL5G" 41 | #define ARBDL5G "ARBDL5G" 42 | 43 | /* Names of entries in sections used in the configuration file */ 44 | #define PFMODE "pf_mode_en" 45 | #define INPUT_POS_LLR_1_BIT "input_pos_llr_1_bit" 46 | #define OUTPUT_POS_LLR_1_BIT "output_pos_llr_1_bit" 47 | #define NUMVF_BUNDLES "num_vf_bundles" 48 | #define MAX_QUEUE_SIZE "max_queue_size" 49 | #define NUM_QGROUPS "num_qgroups" 50 | #define NUM_AQS_PER_GROUPS "num_aqs_per_groups" 51 | #define AQ_DEPTH_LOG2 "aq_depth_log2" 52 | #define ROUND_ROBIN_WEIGHT "round_robin_weight" 53 | #define GBR_THRSH1 "gbr_threshold1" 54 | #define GBR_THRSH2 "gbr_threshold2" 55 | 56 | /* Default values for ACC100 device configuration variables */ 57 | #define NUM_OF_BUNDLES 1 58 | #define DEFAULT_PF_MODE_EN 1 59 | #define QDL_NUM_QGROUPS 1 60 | #define QDL_NUM_AQS_PER_GROUPS 1 61 | #define QDL_AQ_DEPTH_LOG2 8 62 | #define QUL_NUM_QGROUPS 1 63 | #define QUL_NUM_AQS_PER_GROUPS 1 64 | #define QUL_AQ_DEPTH_LOG2 8 65 | #define ARBDL_GBR_THRSH1 0 66 | #define ARBDL_GBR_THRSH2 0 67 | #define ARBDL_ROUND_ROBIN_WEIGHT 1 68 | #define ARBUL_GBR_THRSH1 0 69 | #define ARBUL_GBR_THRSH2 0 70 | #define ARBUL_ROUND_ROBIN_WEIGHT 1 71 | 72 | /* Possible values for MODE and LLR_SIGN */ 73 | #define ZERO "0" 74 | #define ONE "1" 75 | 76 | /* Convert a character to a 16-bit integer */ 77 | static int 78 | parse_number16(const char *str, uint16_t *value) 79 | { 80 | uint64_t val = 0; 81 | char *end; 82 | 83 | if (str == NULL) 84 | return -EINVAL; 85 | 86 | val = strtoul(str, &end, 0); 87 | if (val > UINT16_MAX || str == end) { 88 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 89 | return -ERANGE; 90 | } 91 | 92 | *value = (uint16_t) val; 93 | return 1; 94 | } 95 | 96 | /* Convert a character to a 32-bit integer */ 97 | static int 98 | parse_number32(const char *str, uint32_t *value) 99 | { 100 | uint64_t val = 0; 101 | char *end; 102 | 103 | if (str == NULL) 104 | return -EINVAL; 105 | 106 | val = strtoul(str, &end, 0); 107 | if (val > UINT32_MAX || str == end) { 108 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 109 | return -ERANGE; 110 | } 111 | *value = (uint32_t) val; 112 | return 1; 113 | } 114 | 115 | /* Find the item number for a given item */ 116 | static int 117 | parse_item_no(const char *full_name, const char *base_name) 118 | { 119 | int postfix_len, number_start, ret; 120 | uint16_t item_no = 0; 121 | 122 | postfix_len = strlen(full_name) - strlen(base_name); 123 | if (postfix_len > 0) { 124 | number_start = strlen((const char *) base_name); 125 | ret = parse_number16(&full_name[number_start], &item_no); 126 | if (ret != 1) 127 | printf("ERROR: Parsing item (%d) failed (%d)\n", item_no, ret); 128 | } 129 | 130 | return item_no; 131 | } 132 | 133 | /* Set the default config for the device (if no other config file is given) */ 134 | static void 135 | set_default_config(struct acc100_conf *acc100_conf) 136 | { 137 | int x; 138 | 139 | acc100_conf->num_vf_bundles = NUM_OF_BUNDLES; 140 | acc100_conf->pf_mode_en = DEFAULT_PF_MODE_EN; 141 | 142 | acc100_conf->q_dl_4g.num_qgroups = QDL_NUM_QGROUPS; 143 | acc100_conf->q_dl_4g.num_aqs_per_groups = QDL_NUM_AQS_PER_GROUPS; 144 | acc100_conf->q_dl_4g.aq_depth_log2 = QDL_AQ_DEPTH_LOG2; 145 | acc100_conf->q_ul_4g.num_qgroups = QUL_NUM_QGROUPS; 146 | acc100_conf->q_ul_4g.num_aqs_per_groups = QUL_NUM_AQS_PER_GROUPS; 147 | acc100_conf->q_ul_4g.aq_depth_log2 = QUL_AQ_DEPTH_LOG2; 148 | acc100_conf->q_dl_5g.num_qgroups = QDL_NUM_QGROUPS; 149 | acc100_conf->q_dl_5g.num_aqs_per_groups = QDL_NUM_AQS_PER_GROUPS; 150 | acc100_conf->q_dl_5g.aq_depth_log2 = QDL_AQ_DEPTH_LOG2; 151 | acc100_conf->q_ul_5g.num_qgroups = QUL_NUM_QGROUPS; 152 | acc100_conf->q_ul_5g.num_aqs_per_groups = QUL_NUM_AQS_PER_GROUPS; 153 | acc100_conf->q_ul_5g.aq_depth_log2 = QUL_AQ_DEPTH_LOG2; 154 | 155 | for (x = 0; x < ACC100_NUM_VFS; x++) { 156 | acc100_conf->arb_dl_4g[x].gbr_threshold1 = ARBDL_GBR_THRSH1; 157 | acc100_conf->arb_dl_4g[x].gbr_threshold2 = ARBDL_GBR_THRSH2; 158 | acc100_conf->arb_dl_4g[x].round_robin_weight = 159 | ARBDL_ROUND_ROBIN_WEIGHT; 160 | } 161 | for (x = 0; x < ACC100_NUM_VFS; x++) { 162 | acc100_conf->arb_ul_4g[x].gbr_threshold1 = ARBUL_GBR_THRSH1; 163 | acc100_conf->arb_ul_4g[x].gbr_threshold2 = ARBUL_GBR_THRSH2; 164 | acc100_conf->arb_ul_4g[x].round_robin_weight = 165 | ARBUL_ROUND_ROBIN_WEIGHT; 166 | } 167 | for (x = 0; x < ACC100_NUM_VFS; x++) { 168 | acc100_conf->arb_dl_5g[x].gbr_threshold1 = ARBDL_GBR_THRSH1; 169 | acc100_conf->arb_dl_5g[x].gbr_threshold2 = ARBDL_GBR_THRSH2; 170 | acc100_conf->arb_dl_5g[x].round_robin_weight = 171 | ARBDL_ROUND_ROBIN_WEIGHT; 172 | } 173 | for (x = 0; x < ACC100_NUM_VFS; x++) { 174 | acc100_conf->arb_ul_5g[x].gbr_threshold1 = ARBUL_GBR_THRSH1; 175 | acc100_conf->arb_ul_5g[x].gbr_threshold2 = ARBUL_GBR_THRSH2; 176 | acc100_conf->arb_ul_5g[x].round_robin_weight = 177 | ARBUL_ROUND_ROBIN_WEIGHT; 178 | } 179 | } 180 | 181 | /* Handler function for .ini parser (returns 1 for success) */ 182 | static int 183 | acc100_handler(void *user, const char *section, 184 | const char *name, const char *value) 185 | { 186 | struct acc100_conf *acc100_conf = (struct acc100_conf *) user; 187 | int ret = 1, index; 188 | 189 | if (!strcmp(section, MODE) && !strcmp(name, PFMODE)) { 190 | if (!strcmp(value, ZERO)) 191 | acc100_conf->pf_mode_en = false; 192 | else if (!strcmp(value, ONE)) 193 | acc100_conf->pf_mode_en = true; 194 | else 195 | ret = 0; 196 | } else if (!strcmp(section, LLR_SIGN) && 197 | !strcmp(name, INPUT_POS_LLR_1_BIT)) { 198 | if (!strcmp(value, ZERO)) 199 | acc100_conf->input_pos_llr_1_bit = false; 200 | else if (!strcmp(value, ONE)) 201 | acc100_conf->input_pos_llr_1_bit = true; 202 | else 203 | ret = 0; 204 | } else if (!strcmp(section, LLR_SIGN) && 205 | !strcmp(name, OUTPUT_POS_LLR_1_BIT)) { 206 | if (!strcmp(value, ZERO)) 207 | acc100_conf->output_pos_llr_1_bit = false; 208 | else if (!strcmp(value, ONE)) 209 | acc100_conf->output_pos_llr_1_bit = true; 210 | else 211 | ret = 0; 212 | } else if (!strcmp(section, VFBUNDLES) && 213 | !strcmp(name, NUMVF_BUNDLES)) { 214 | ret = parse_number16(value, &acc100_conf->num_vf_bundles); 215 | } else if (!strcmp(section, MAXQSIZE) && 216 | !strcmp(name, MAX_QUEUE_SIZE)) { 217 | /* MAX_QUEUE_SIZE is not used. Keep it for parsing purposes */ 218 | } else if (!strcmp(section, QUL4G) && !strcmp(name, NUM_QGROUPS)) { 219 | ret = parse_number16(value, &acc100_conf->q_ul_4g.num_qgroups); 220 | } else if (!strcmp(section, QUL4G) && 221 | !strcmp(name, NUM_AQS_PER_GROUPS)) { 222 | ret = parse_number16(value, 223 | &acc100_conf->q_ul_4g.num_aqs_per_groups); 224 | } else if (!strcmp(section, QUL4G) && !strcmp(name, AQ_DEPTH_LOG2)) { 225 | ret = parse_number16(value, 226 | &acc100_conf->q_ul_4g.aq_depth_log2); 227 | } else if (!strcmp(section, QDL4G) && !strcmp(name, NUM_QGROUPS)) { 228 | ret = parse_number16(value, &acc100_conf->q_dl_4g.num_qgroups); 229 | } else if (!strcmp(section, QDL4G) && 230 | !strcmp(name, NUM_AQS_PER_GROUPS)) { 231 | ret = parse_number16(value, 232 | &acc100_conf->q_dl_4g.num_aqs_per_groups); 233 | } else if (!strcmp(section, QDL4G) && !strcmp(name, AQ_DEPTH_LOG2)) { 234 | ret = parse_number16(value, 235 | &acc100_conf->q_dl_4g.aq_depth_log2); 236 | } else if (!strcmp(section, QUL5G) && !strcmp(name, NUM_QGROUPS)) { 237 | ret = parse_number16(value, &acc100_conf->q_ul_5g.num_qgroups); 238 | } else if (!strcmp(section, QUL5G) && 239 | !strcmp(name, NUM_AQS_PER_GROUPS)) { 240 | ret = parse_number16(value, 241 | &acc100_conf->q_ul_5g.num_aqs_per_groups); 242 | } else if (!strcmp(section, QUL5G) && !strcmp(name, AQ_DEPTH_LOG2)) { 243 | ret = parse_number16(value, 244 | &acc100_conf->q_ul_5g.aq_depth_log2); 245 | } else if (!strcmp(section, QDL5G) && !strcmp(name, NUM_QGROUPS)) { 246 | ret = parse_number16(value, &acc100_conf->q_dl_5g.num_qgroups); 247 | } else if (!strcmp(section, QDL5G) && 248 | !strcmp(name, NUM_AQS_PER_GROUPS)) { 249 | ret = parse_number16(value, 250 | &acc100_conf->q_dl_5g.num_aqs_per_groups); 251 | } else if (!strcmp(section, QDL5G) && !strcmp(name, AQ_DEPTH_LOG2)) { 252 | ret = parse_number16(value, 253 | &acc100_conf->q_dl_5g.aq_depth_log2); 254 | } else if (strstr(section, ARBUL4G) && 255 | !strcmp(name, ROUND_ROBIN_WEIGHT)) { 256 | index = parse_item_no(section, ARBUL4G); 257 | ret = parse_number16(value, 258 | &acc100_conf->arb_ul_4g[index].round_robin_weight); 259 | } else if (strstr(section, ARBUL4G) && !strcmp(name, GBR_THRSH1)) { 260 | index = parse_item_no(section, ARBUL4G); 261 | ret = parse_number32(value, 262 | &acc100_conf->arb_ul_4g[index].gbr_threshold1); 263 | } else if (strstr(section, ARBUL4G) && !strcmp(name, GBR_THRSH2)) { 264 | index = parse_item_no(section, ARBUL4G); 265 | ret = parse_number32(value, 266 | &acc100_conf->arb_ul_4g[index].gbr_threshold2); 267 | } else if (strstr(section, ARBDL4G) && 268 | !strcmp(name, ROUND_ROBIN_WEIGHT)) { 269 | index = parse_item_no(section, ARBDL4G); 270 | ret = parse_number16(value, 271 | &acc100_conf->arb_dl_4g[index].round_robin_weight); 272 | } else if (strstr(section, ARBDL4G) && !strcmp(name, GBR_THRSH1)) { 273 | index = parse_item_no(section, ARBDL4G); 274 | ret = parse_number32(value, 275 | &acc100_conf->arb_dl_4g[index].gbr_threshold1); 276 | } else if (strstr(section, ARBDL4G) && !strcmp(name, GBR_THRSH2)) { 277 | index = parse_item_no(section, ARBDL4G); 278 | ret = parse_number32(value, 279 | &acc100_conf->arb_dl_4g[index].gbr_threshold2); 280 | } else if (strstr(section, ARBUL5G) && 281 | !strcmp(name, ROUND_ROBIN_WEIGHT)) { 282 | index = parse_item_no(section, ARBUL5G); 283 | ret = parse_number16(value, 284 | &acc100_conf->arb_ul_5g[index].round_robin_weight); 285 | } else if (strstr(section, ARBUL5G) && !strcmp(name, GBR_THRSH1)) { 286 | index = parse_item_no(section, ARBUL5G); 287 | ret = parse_number32(value, 288 | &acc100_conf->arb_ul_5g[index].gbr_threshold1); 289 | } else if (strstr(section, ARBUL5G) && !strcmp(name, GBR_THRSH2)) { 290 | index = parse_item_no(section, ARBUL5G); 291 | ret = parse_number32(value, 292 | &acc100_conf->arb_ul_5g[index].gbr_threshold2); 293 | } else if (strstr(section, ARBDL5G) && 294 | !strcmp(name, ROUND_ROBIN_WEIGHT)) { 295 | index = parse_item_no(section, ARBDL5G); 296 | ret = parse_number16(value, 297 | &acc100_conf->arb_dl_5g[index].round_robin_weight); 298 | } else if (strstr(section, ARBDL5G) && !strcmp(name, GBR_THRSH1)) { 299 | index = parse_item_no(section, ARBDL5G); 300 | ret = parse_number32(value, 301 | &acc100_conf->arb_dl_5g[index].gbr_threshold1); 302 | } else if (strstr(section, ARBDL5G) && !strcmp(name, GBR_THRSH2)) { 303 | index = parse_item_no(section, ARBDL5G); 304 | ret = parse_number32(value, 305 | &acc100_conf->arb_dl_5g[index].gbr_threshold2); 306 | } else { 307 | printf("ERROR: section (%s) or name (%s) is not valid\n", 308 | section, name); 309 | ret = 0; 310 | } 311 | 312 | if (ret != 1) 313 | printf("ERROR: Conversion of value (%s) failed\n", value); 314 | 315 | return ret; 316 | } 317 | 318 | /* Enforce range check for a given queue configuration */ 319 | int 320 | acc100_queue_range_check(struct q_topology_t q_conf) 321 | { 322 | if ((q_conf.num_aqs_per_groups < 1) || 323 | (q_conf.num_aqs_per_groups > ACC100_NUM_AQS)) { 324 | printf("ERROR: Number of AQs out of range %d\n", 325 | q_conf.num_aqs_per_groups); 326 | return -1; 327 | } 328 | if ((q_conf.aq_depth_log2 < 1) || 329 | (q_conf.aq_depth_log2 > ACC100_MAX_QDEPTH)) { 330 | printf("ERROR: AQ Depth out of range %d\n", 331 | q_conf.aq_depth_log2); 332 | return -1; 333 | } 334 | if (q_conf.num_qgroups > ACC100_NUM_QGRPS) { 335 | printf("ERROR: Number of QG out of range %d\n", 336 | q_conf.num_qgroups); 337 | return -1; 338 | } 339 | return 0; 340 | } 341 | 342 | /* Enforce range check for a given device configuration */ 343 | int 344 | acc100_range_check(struct acc100_conf *acc100_conf) 345 | { 346 | uint16_t totalQgs = acc100_conf->q_ul_4g.num_qgroups + 347 | acc100_conf->q_ul_5g.num_qgroups + 348 | acc100_conf->q_dl_4g.num_qgroups + 349 | acc100_conf->q_dl_5g.num_qgroups; 350 | if (totalQgs > ACC100_NUM_QGRPS) { 351 | printf("ERROR: Number of Qgroups %d > %d\n", 352 | totalQgs, ACC100_NUM_QGRPS); 353 | return -1; 354 | } 355 | if (acc100_conf->num_vf_bundles > ACC100_NUM_VFS) { 356 | printf("ERROR: Number of VFs bundle %d > %d\n", 357 | acc100_conf->num_vf_bundles, ACC100_NUM_VFS); 358 | return -1; 359 | } 360 | 361 | if (acc100_queue_range_check(acc100_conf->q_ul_4g) != 0) 362 | return -1; 363 | if (acc100_queue_range_check(acc100_conf->q_dl_4g) != 0) 364 | return -1; 365 | if (acc100_queue_range_check(acc100_conf->q_ul_5g) != 0) 366 | return -1; 367 | if (acc100_queue_range_check(acc100_conf->q_dl_5g) != 0) 368 | return -1; 369 | return 0; 370 | } 371 | 372 | int 373 | acc100_parse_conf_file(const char *file_name, struct acc100_conf *acc100_conf) 374 | { 375 | int ret; 376 | 377 | set_default_config(acc100_conf); 378 | 379 | ret = cfg_parse(file_name, acc100_handler, acc100_conf); 380 | 381 | if (ret != 0) { 382 | printf("ERROR: Config file parser error\n"); 383 | set_default_config(acc100_conf); 384 | return -1; 385 | } 386 | 387 | ret = acc100_range_check(acc100_conf); 388 | if (ret != 0) { 389 | printf("ERROR: Parameter out of range\n"); 390 | set_default_config(acc100_conf); 391 | return -1; 392 | } 393 | 394 | return 0; 395 | } 396 | -------------------------------------------------------------------------------- /acc100/acc100_config.cfg: -------------------------------------------------------------------------------- 1 | acc100_config_2vf_4g5g.cfg -------------------------------------------------------------------------------- /acc100/acc100_config_1vf_4g5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 1 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 2 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 2 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_1vf_5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 1 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 0 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 0 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_2vf_4g5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 2 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 2 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 2 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_4vf_4g5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 4 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 5 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 5 22 | 23 | [QUL5G] 24 | num_qgroups = 2 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 5 27 | 28 | [QDL5G] 29 | num_qgroups = 2 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 5 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_pf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 2 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 2 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_pf_4g5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 1 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 2 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 2 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 2 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 2 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_vf_4g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 4 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 4 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 0 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 0 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /acc100/acc100_config_vf_5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 0 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 0 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | -------------------------------------------------------------------------------- /agx100/agx100_cfg_app.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "agx100_cfg_app.h" 28 | #include "cfg_reader.h" 29 | 30 | extern int 31 | agx100_parse_conf_file(const char *file_name, 32 | struct agx100_conf *agx100_conf); 33 | 34 | /* Read 8-bit register of AGX100 device */ 35 | static uint8_t 36 | agx100_reg_read_8(void *mmio_base, uint32_t offset) 37 | { 38 | void *reg_addr = mmio_base + offset; 39 | return *((volatile uint8_t *)(reg_addr)); 40 | } 41 | 42 | /* Read 16-bit register of AGX100 device */ 43 | static uint16_t 44 | agx100_reg_read_16(void *mmio_base, uint32_t offset) 45 | { 46 | void *reg_addr = mmio_base + offset; 47 | uint16_t ret = *((volatile uint16_t *)(reg_addr)); 48 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 49 | return __bswap_16(ret); 50 | #else 51 | return ret; 52 | #endif 53 | } 54 | 55 | /* Read 32-bit register of AGX100 device */ 56 | static uint32_t 57 | agx100_reg_read_32(void *mmio_base, uint32_t offset) 58 | { 59 | void *reg_addr = mmio_base + offset; 60 | uint32_t ret = *((volatile uint32_t *)(reg_addr)); 61 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 62 | return __bswap_32(ret); 63 | #else 64 | return ret; 65 | #endif 66 | } 67 | 68 | static inline void 69 | agx100_reg_write_16(void *mmio_base, uint32_t offset, 70 | uint16_t payload) { 71 | void *reg_addr = mmio_base + offset; 72 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 73 | payload = __bswap_16(payload); 74 | #endif 75 | *((volatile uint16_t *) (reg_addr)) = payload; 76 | } 77 | 78 | static inline void 79 | agx100_reg_write_32(void *mmio_base, uint32_t offset, 80 | uint32_t payload) 81 | { 82 | void *reg_addr = mmio_base + offset; 83 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 84 | payload = __bswap_32(payload); 85 | #endif 86 | *((volatile uint32_t *) (reg_addr)) = payload; 87 | } 88 | 89 | static inline void 90 | set_default_agx100_conf(struct agx100_conf *def_conf) 91 | { 92 | /* Set pf mode to true */ 93 | def_conf->pf_mode_en = true; 94 | 95 | /* Set Load Balance Factor to 64 */ 96 | def_conf->dl_load_balance = 64; 97 | def_conf->ul_load_balance = 64; 98 | } 99 | 100 | static int 101 | agx100_read_config_file(const char *arg_cfg_filename, 102 | struct agx100_conf *agx100_conf) 103 | { 104 | bool unsafe_path = cfg_file_check_path_safety(arg_cfg_filename); 105 | if (unsafe_path == true) { 106 | printf("error, config file path \"%s\" is not safe", 107 | arg_cfg_filename); 108 | return -1; 109 | } else 110 | return agx100_parse_conf_file(arg_cfg_filename, 111 | agx100_conf); 112 | } 113 | 114 | /* Read Static Register of AGX100 device */ 115 | static inline void 116 | print_static_reg_debug_info(void *mmio_base) 117 | { 118 | uint8_t i, q_id; 119 | uint32_t fid; 120 | uint32_t version_num_queues = agx100_reg_read_32(mmio_base, AGX100_VERSION_QUEUES_REG); 121 | uint8_t major_version_id = version_num_queues >> 16; 122 | uint8_t minor_version_id = version_num_queues >> 8; 123 | uint8_t patch_id = version_num_queues; 124 | uint8_t qmap_done = agx100_reg_read_8(mmio_base, AGX100_QUEUE_PF_VF_MAP_DONE); 125 | uint16_t lb_factor = agx100_reg_read_16(mmio_base, AGX100_LOAD_BALANCE_FACTOR); 126 | uint16_t ring_desc_len = agx100_reg_read_16(mmio_base, AGX100_RING_DESC_LEN); 127 | 128 | /* Maximum number of queues on device */ 129 | uint8_t total_num_queues = version_num_queues >> 24; 130 | uint8_t num_ul_queues = total_num_queues >> 1; 131 | 132 | printf("AGX100 RTL v%u.%u.%u\n", major_version_id, minor_version_id, patch_id); 133 | printf("Max number of Queues = %u\n", total_num_queues); 134 | printf("UL.DL Load Balance = %u.%u\n", 135 | ((uint8_t)lb_factor), ((uint8_t)(lb_factor >> 8))); 136 | printf("Queue-PF/VF Mapping Table = %s\n", 137 | (qmap_done > 0) ? "READY" : "NOT-READY"); 138 | printf("Ring Descriptor Size = %u bytes\n", 139 | ring_desc_len*AGX100_RING_DESC_LEN_UNIT_BYTES); 140 | 141 | printf("\n--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n"); 142 | printf(" | PF | VF0 | VF1 | VF2 | VF3 | VF4 | VF5 | VF6 | VF7 |\n"); 143 | printf("--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n"); 144 | 145 | for (q_id = 0; q_id < total_num_queues; q_id++) { 146 | 147 | printf("%s-Q'%02u |", 148 | (q_id < num_ul_queues) ? "UL" : "DL", q_id); 149 | 150 | fid = agx100_reg_read_32(mmio_base, 151 | AGX100_QUEUE_MAP + (q_id << 2)); 152 | 153 | for (i = 0; i < 9; ++i) { 154 | 155 | if (!((fid >> 16) & (0x80)) && i == 0) { 156 | printf(" X |"); 157 | continue; 158 | } 159 | 160 | if (((((fid >> 16) & (0x7f)) + 1) == i) && 161 | ((fid >> 16) & (0x80))) 162 | printf(" X |"); 163 | else 164 | printf(" |"); 165 | } 166 | printf("\n"); 167 | } 168 | printf("--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n\n"); 169 | } 170 | 171 | static int 172 | agx100_write_config(void *dev, void *mapaddr, struct agx100_conf *conf) 173 | { 174 | 175 | uint32_t payload_32, address; 176 | uint16_t payload_16; 177 | uint16_t q_id, vf_id, total_q_id, total_ul_q_id, total_dl_q_id; 178 | 179 | uint32_t *bar0addr = mapaddr; 180 | /* Maximum number of queues on device */ 181 | uint8_t total_num_queues = agx100_reg_read_32(bar0addr, AGX100_VERSION_QUEUES_REG) >> 24; 182 | uint8_t num_ul_queues = total_num_queues >> 1; 183 | uint8_t num_dl_queues = total_num_queues >> 1; 184 | 185 | /* Clear all queues registers */ 186 | payload_32 = AGX100_INVALID_HW_QUEUE_ID; 187 | for (q_id = 0; q_id < total_num_queues; ++q_id) { 188 | address = (q_id << 2) + AGX100_QUEUE_MAP; 189 | agx100_reg_write_32(bar0addr, address, payload_32); 190 | } 191 | 192 | /* 193 | * If PF mode is enabled allocate all queues for PF only. 194 | * 195 | * For VF mode each VF can have different number of UL and DL queues. 196 | * Total number of queues to configure cannot exceed AGX100 capabilities. 197 | * Queues mapping is done according to configuration: 198 | * 199 | * UL queues: 200 | * | Q_ID | VF_ID | 201 | * | 0 | 0 | 202 | * | ... | 0 | 203 | * | conf->vf_dl_queues_number[0] - 1 | 0 | 204 | * | conf->vf_dl_queues_number[0] | 1 | 205 | * | ... | 1 | 206 | * | conf->vf_dl_queues_number[1] - 1 | 1 | 207 | * | ... | ... | 208 | * | conf->vf_dl_queues_number[7] - 1 | 7 | 209 | * 210 | * DL queues: 211 | * | Q_ID | VF_ID | 212 | * | 32 | 0 | 213 | * | ... | 0 | 214 | * | conf->vf_ul_queues_number[0] - 1 | 0 | 215 | * | conf->vf_ul_queues_number[0] | 1 | 216 | * | ... | 1 | 217 | * | conf->vf_ul_queues_number[1] - 1 | 1 | 218 | * | ... | ... | 219 | * | conf->vf_ul_queues_number[7] - 1 | 7 | 220 | * 221 | * Example of configuration: 222 | * conf->vf_ul_queues_number[0] = 4; -> 4 UL queues for VF0 223 | * conf->vf_dl_queues_number[0] = 4; -> 4 DL queues for VF0 224 | * conf->vf_ul_queues_number[1] = 2; -> 2 UL queues for VF1 225 | * conf->vf_dl_queues_number[1] = 2; -> 2 DL queues for VF1 226 | * 227 | * UL: 228 | * | Q_ID | VF_ID | 229 | * | 0 | 0 | 230 | * | 1 | 0 | 231 | * | 2 | 0 | 232 | * | 3 | 0 | 233 | * | 4 | 1 | 234 | * | 5 | 1 | 235 | * 236 | * DL: 237 | * | Q_ID | VF_ID | 238 | * | 32 | 0 | 239 | * | 33 | 0 | 240 | * | 34 | 0 | 241 | * | 35 | 0 | 242 | * | 36 | 1 | 243 | * | 37 | 1 | 244 | */ 245 | if (conf->pf_mode_en) { 246 | payload_32 = 0x1; 247 | for (q_id = 0; q_id < total_num_queues; ++q_id) { 248 | address = (q_id << 2) + AGX100_QUEUE_MAP; 249 | agx100_reg_write_32(bar0addr, address, payload_32); 250 | } 251 | } else { 252 | /* Calculate total number of UL and DL queues to configure */ 253 | total_ul_q_id = total_dl_q_id = 0; 254 | for (vf_id = 0; vf_id < AGX100_NUM_VFS; ++vf_id) { 255 | total_ul_q_id += conf->vf_ul_queues_number[vf_id]; 256 | total_dl_q_id += conf->vf_dl_queues_number[vf_id]; 257 | } 258 | total_q_id = total_dl_q_id + total_ul_q_id; 259 | /* 260 | * Check if total number of queues to configure does not exceed 261 | * AGX100 capabilities 262 | */ 263 | if ((total_ul_q_id > num_ul_queues) || 264 | (total_dl_q_id > num_dl_queues) || 265 | (total_q_id > total_num_queues)) { 266 | printf( 267 | "AGX100 Configuration failed. Too many queues to configure: UL_Q %u, DL_Q %u, AGX100_Q %u", 268 | total_ul_q_id, total_dl_q_id, 269 | total_num_queues); 270 | return -EINVAL; 271 | } 272 | total_ul_q_id = 0; 273 | for (vf_id = 0; vf_id < AGX100_NUM_VFS; ++vf_id) { 274 | for (q_id = 0; q_id < conf->vf_ul_queues_number[vf_id]; 275 | ++q_id, ++total_ul_q_id) { 276 | address = (total_ul_q_id << 2) + 277 | AGX100_QUEUE_MAP; 278 | payload_32 = ((0x80 + vf_id) << 16) | 0x1; 279 | agx100_reg_write_32(bar0addr, address, 280 | payload_32); 281 | } 282 | } 283 | total_dl_q_id = 0; 284 | for (vf_id = 0; vf_id < AGX100_NUM_VFS; ++vf_id) { 285 | for (q_id = 0; q_id < conf->vf_dl_queues_number[vf_id]; 286 | ++q_id, ++total_dl_q_id) { 287 | address = ((total_dl_q_id + num_ul_queues) 288 | << 2) + AGX100_QUEUE_MAP; 289 | payload_32 = ((0x80 + vf_id) << 16) | 0x1; 290 | agx100_reg_write_32(bar0addr, address, 291 | payload_32); 292 | } 293 | } 294 | } 295 | 296 | /* Setting Load Balance Factor */ 297 | payload_16 = (conf->dl_load_balance << 8) | (conf->ul_load_balance); 298 | address = AGX100_LOAD_BALANCE_FACTOR; 299 | agx100_reg_write_16(bar0addr, address, payload_16); 300 | 301 | /* Setting length of ring descriptor entry */ 302 | payload_16 = AGX100_RING_DESC_ENTRY_LENGTH; 303 | address = AGX100_RING_DESC_LEN; 304 | agx100_reg_write_16(bar0addr, address, payload_16); 305 | 306 | /* Queue PF/VF mapping table is ready */ 307 | payload_16 = 0x1; 308 | address = AGX100_QUEUE_PF_VF_MAP_DONE; 309 | agx100_reg_write_16(bar0addr, address, payload_16); 310 | 311 | print_static_reg_debug_info(bar0addr); 312 | printf("Mode of operation = %s-mode\n", 313 | conf->pf_mode_en ? "PF" : "VF"); 314 | 315 | return 0; 316 | } 317 | 318 | int 319 | agx100_configure(void *dev, void *bar0addr, const char *cfg_filename, const bool first_cfg) 320 | { 321 | struct agx100_conf agx100_conf; 322 | int ret; 323 | 324 | ret = agx100_read_config_file(cfg_filename, &agx100_conf); 325 | if (ret != 0) { 326 | printf("Error reading config file.\n"); 327 | return -1; 328 | } 329 | 330 | ret = agx100_write_config(dev, bar0addr, &agx100_conf); 331 | if (ret != 0) { 332 | printf("Error writing configuration for AGX100.\n"); 333 | return -1; 334 | } 335 | 336 | return 0; 337 | } 338 | -------------------------------------------------------------------------------- /agx100/agx100_cfg_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _AGX100_CFG_APP_H_ 20 | #define _AGX100_CFG_APP_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* Multiplier of 256 bits (32 bytes) */ 31 | #define AGX100_RING_DESC_ENTRY_LENGTH (8) 32 | #define AGX100_RING_DESC_LEN_UNIT_BYTES (64) 33 | /* Maximum size of queue */ 34 | #define AGX100_RING_MAX_SIZE (1024) 35 | #define AGX100_INVALID_HW_QUEUE_ID (0xFFFFFFFF) 36 | 37 | /* AGX100 Register mapping on BAR0 */ 38 | enum { 39 | AGX100_VERSION_QUEUES_REG = 0x00000000, /**< len: 4B */ 40 | AGX100_QUEUE_PF_VF_MAP_DONE = 0x00000008, /**< len: 1B */ 41 | AGX100_LOAD_BALANCE_FACTOR = 0x0000000A, /**< len: 2B */ 42 | AGX100_RING_DESC_LEN = 0x0000000C, /**< len: 2B */ 43 | AGX100_FLR_TIME_OUT = 0x0000000E, /**< len: 2B */ 44 | AGX100_VFQ_FLUSH_STATUS_LW = 0x00000018, /**< len: 4B */ 45 | AGX100_VFQ_FLUSH_STATUS_HI = 0x0000001C, /**< len: 4B */ 46 | AGX100_QUEUE_MAP = 0x00000100, /**< len: 256B */ 47 | AGX100_RING_CTRL_REGS = 0x00000200, /**< len: 2048B */ 48 | AGX100_DDR4_WR_ADDR_REGS = 0x00000A00, /**< len: 4B */ 49 | AGX100_DDR4_WR_DATA_REGS = 0x00000A08, /**< len: 8B */ 50 | AGX100_DDR4_WR_DONE_REGS = 0x00000A10, /**< len: 1B */ 51 | AGX100_DDR4_RD_ADDR_REGS = 0x00000A18, /**< len: 4B */ 52 | AGX100_DDR4_RD_DONE_REGS = 0x00000A20, /**< len: 1B */ 53 | AGX100_DDR4_RD_RDY_REGS = 0x00000A28, /**< len: 1B */ 54 | AGX100_DDR4_RD_DATA_REGS = 0x00000A30, /**< len: 8B */ 55 | AGX100_DDR4_ADDR_RDY_REGS = 0x00000A38, /**< len: 1B */ 56 | AGX100_HARQ_BUF_SIZE_RDY_REGS = 0x00000A40, /**< len: 1B */ 57 | AGX100_HARQ_BUF_SIZE_REGS = 0x00000A48, /**< len: 4B */ 58 | AGX100_MUTEX = 0x00000A60, /**< len: 4B */ 59 | AGX100_MUTEX_RESET = 0x00000A68 /**< len: 4B */ 60 | }; 61 | 62 | /* AGX100 Ring Control Registers */ 63 | enum { 64 | AGX100_RING_HEAD_ADDR = 0x00000008, 65 | AGX100_RING_SIZE = 0x00000010, 66 | AGX100_RING_MISC = 0x00000014, 67 | AGX100_RING_ENABLE = 0x00000015, 68 | AGX100_RING_FLUSH_QUEUE_EN = 0x00000016, 69 | AGX100_RING_SHADOW_TAIL = 0x00000018, 70 | AGX100_RING_HEAD_POINT = 0x0000001C 71 | }; 72 | 73 | /**< Number of Virtual Functions AGX100 supports */ 74 | #define AGX100_NUM_VFS 8 75 | 76 | struct 77 | agx100_conf { 78 | /**< 1 if PF is used for dataplane, 0 for VFs */ 79 | bool pf_mode_en; 80 | /**< Number of UL queues per VF */ 81 | uint8_t vf_ul_queues_number[AGX100_NUM_VFS]; 82 | /**< Number of DL queues per VF */ 83 | uint8_t vf_dl_queues_number[AGX100_NUM_VFS]; 84 | /**< UL Load Balance */ 85 | uint8_t ul_load_balance; 86 | /**< DL Load Balance */ 87 | uint8_t dl_load_balance; 88 | }; 89 | 90 | #endif /* _AGX100_CFG_APP_H_ */ 91 | -------------------------------------------------------------------------------- /agx100/agx100_cfg_parser.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "cfg_reader.h" 27 | #include "agx100_cfg_app.h" 28 | 29 | /* Names of sections used in the configuration file */ 30 | #define MODE "MODE" 31 | #define UL "UL" 32 | #define DL "DL" 33 | 34 | /* Names of entries in sections used in the configuration file */ 35 | #define PFMODE "pf_mode_en" 36 | #define BANDWIDTH "bandwidth" 37 | #define LOAD_BALANCE "load_balance" 38 | #define QUEUE_MAP "vfqmap" 39 | 40 | /* Default values for AGX100 device configuration variables */ 41 | #define DEFAULT_PF_MODE_EN 1 42 | #define DEFAULT_UL_LOAD_BALANCE 64 43 | #define DEFAULT_DL_LOAD_BALANCE 64 44 | #define DEFAULT_NUM_VF_QUEUE 8 45 | 46 | /* Possible values for MODE and LLR_SIGN */ 47 | #define ZERO "0" 48 | #define ONE "1" 49 | 50 | static int 51 | parse_number8(const char *str, uint8_t *value) 52 | { 53 | uint64_t val = 0; 54 | char *end; 55 | 56 | if (str == NULL) 57 | return -EINVAL; 58 | 59 | val = strtoul(str, &end, 0); 60 | if (val > UINT8_MAX || str == end) { 61 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 62 | return -ERANGE; 63 | } 64 | 65 | *value = (uint8_t) val; 66 | return 1; 67 | } 68 | 69 | static int 70 | parse_array8(const char *str, uint8_t *array) 71 | { 72 | int i; 73 | uint64_t val = 0; 74 | char *end; 75 | 76 | if (str == NULL) 77 | return -EINVAL; 78 | 79 | char *val_ch = strtok((char *)str, ","); 80 | for (i = 0; i < 8 && NULL != val_ch; i++) { 81 | 82 | val = strtoul(val_ch, &end, 0); 83 | if (val > UINT8_MAX || val_ch == end) { 84 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 85 | return -ERANGE; 86 | } 87 | array[i] = (uint8_t) val; 88 | 89 | val_ch = strtok(NULL, ","); 90 | } 91 | return 1; 92 | } 93 | 94 | static void 95 | set_default_config(struct agx100_conf *agx100_conf) 96 | { 97 | int i; 98 | 99 | /* Set pf mode to true */ 100 | agx100_conf->pf_mode_en = DEFAULT_PF_MODE_EN; 101 | 102 | /* Set Load Balance Factor to 64 */ 103 | agx100_conf->ul_load_balance = DEFAULT_UL_LOAD_BALANCE; 104 | agx100_conf->dl_load_balance = DEFAULT_DL_LOAD_BALANCE; 105 | 106 | for (i = 0; i < AGX100_NUM_VFS; i++) { 107 | agx100_conf->vf_ul_queues_number[i] = DEFAULT_NUM_VF_QUEUE / 2; 108 | agx100_conf->vf_dl_queues_number[i] = DEFAULT_NUM_VF_QUEUE / 2; 109 | } 110 | } 111 | 112 | static int 113 | agx100_handler(void *user, const char *section, 114 | const char *name, const char *value) 115 | { 116 | struct agx100_conf *agx100_conf = 117 | (struct agx100_conf *) user; 118 | int ret = 1; 119 | 120 | if (!strcmp(section, MODE) && !strcmp(name, PFMODE)) { 121 | if (!strcmp(value, ZERO)) 122 | agx100_conf->pf_mode_en = false; 123 | else if (!strcmp(value, ONE)) 124 | agx100_conf->pf_mode_en = true; 125 | else 126 | ret = 0; 127 | } else if (!strcmp(section, UL) && !strcmp(name, LOAD_BALANCE)) { 128 | ret = parse_number8(value, &agx100_conf->ul_load_balance); 129 | } else if (!strcmp(section, DL) && !strcmp(name, LOAD_BALANCE)) { 130 | ret = parse_number8(value, &agx100_conf->dl_load_balance); 131 | } else if (!strcmp(section, UL) && !strcmp(name, QUEUE_MAP)) { 132 | ret = parse_array8(value, agx100_conf->vf_ul_queues_number); 133 | } else if (!strcmp(section, DL) && !strcmp(name, QUEUE_MAP)) { 134 | ret = parse_array8(value, agx100_conf->vf_dl_queues_number); 135 | } else { 136 | printf("ERROR: Section (%s) or name (%s) is not valid.\n", 137 | section, name); 138 | return 0; 139 | } 140 | if (ret != 1) 141 | printf("Error: Conversion of value (%s) failed.\n", value); 142 | 143 | return ret; 144 | } 145 | 146 | int 147 | agx100_parse_conf_file(const char *file_name, 148 | struct agx100_conf *agx100_conf) 149 | { 150 | int ret; 151 | 152 | set_default_config(agx100_conf); 153 | 154 | ret = cfg_parse(file_name, agx100_handler, agx100_conf); 155 | 156 | if (ret == -1) { 157 | printf("ERROR: Error loading configuration file %s\n", 158 | file_name); 159 | set_default_config(agx100_conf); 160 | return -ENOENT; 161 | } else if (ret == -2) { 162 | printf("ERROR: Memory allocation error\n"); 163 | set_default_config(agx100_conf); 164 | return -ENOMEM; 165 | } 166 | 167 | return 0; 168 | } 169 | -------------------------------------------------------------------------------- /agx100/agx100_config.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [UL] 8 | load_balance = 128 9 | vfqmap = 4,4,4,4,4,4,4,4 10 | 11 | [DL] 12 | load_balance = 128 13 | vfqmap = 4,4,4,4,4,4,4,4 14 | -------------------------------------------------------------------------------- /agx100/agx100_config_1vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | load_balance = 128 9 | vfqmap = 32,0,0,0,0,0,0,0 10 | 11 | [DL] 12 | load_balance = 128 13 | vfqmap = 32,0,0,0,0,0,0,0 14 | -------------------------------------------------------------------------------- /agx100/agx100_config_2vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | load_balance = 128 9 | vfqmap = 16,16,0,0,0,0,0,0 10 | 11 | [DL] 12 | load_balance = 128 13 | vfqmap = 16,16,0,0,0,0,0,0 14 | -------------------------------------------------------------------------------- /agx100/agx100_config_4vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | load_balance = 128 9 | vfqmap = 8,8,8,8,0,0,0,0 10 | 11 | [DL] 12 | load_balance = 128 13 | vfqmap = 8,8,8,8,0,0,0,0 14 | -------------------------------------------------------------------------------- /agx100/agx100_config_8vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | load_balance = 128 9 | vfqmap = 4,4,4,4,4,4,4,4 10 | 11 | [DL] 12 | load_balance = 128 13 | vfqmap = 4,4,4,4,4,4,4,4 14 | -------------------------------------------------------------------------------- /bb_acc.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef __BB_ACC_H__ 20 | #define __BB_ACC_H__ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "pf_bb_config_cli.h" 42 | 43 | #define SYS_DIR "/sys/bus/pci/devices" 44 | #define CUR_DIR "." 45 | #define PREV_DIR ".." 46 | 47 | #define DEVICE_FILE "device" 48 | #define VENDOR_FILE "vendor" 49 | #define BAR0_FILE "resource0" 50 | 51 | #define PCI_STR_SIZE 15 52 | #define NULL_PAD 2 53 | 54 | #define ACC100_VENDOR_ID 0x8086 55 | #define ACC100_DEVICE_ID 0x0D5C 56 | #define VRB1_VENDOR_ID 0x8086 57 | #define VRB1_DEVICE_ID 0x57C0 58 | #define VRB2_VENDOR_ID 0x8086 59 | #define VRB2_DEVICE_ID 0x57C2 60 | #define FPGA_LTE_FEC_VENDOR_ID 0x1172 61 | #define FPGA_LTE_FEC_DEVICE_ID 0x5052 62 | #define FPGA_5GNR_FEC_VENDOR_ID 0x8086 63 | #define FPGA_5GNR_FEC_DEVICE_ID 0x0D8F 64 | #define AGX100_VENDOR_ID 0x8086 65 | #define AGX100_DEVICE_ID 0x5799 66 | 67 | #define VFIO_VF_TOKEN_LEN 16 68 | #define VFIO_VF_TOKEN_STR_LEN 36 69 | #define VFIO_PCI_CONFIG_REGION_SIZE 256 70 | #define VFIO_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + sizeof(int)) 71 | 72 | #define BB_ACC_MAX_VFS 64 73 | #define BB_ACC_MAX_WIN 16 74 | 75 | #define BB_ACC_PF_TO_VF_DBELL_REG_OFFSET 0x100 76 | 77 | #define __bf_shf(x) (__builtin_ffsll(x) - 1) 78 | 79 | #define GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) 80 | 81 | #define FIELD_GET(mask, reg) \ 82 | ((typeof(mask))(((reg) & (mask)) >> __bf_shf(mask))) 83 | 84 | #define BITS_PER_LONG (__SIZEOF_LONG__ * 8) 85 | 86 | #define BIT(nr) (1UL << (nr)) 87 | 88 | #define BB_ACC_INFO_RING_NUM_ENTRIES 1024 89 | /* Mask used to calculate an index in an Info Ring array (not a byte offset) */ 90 | #define BB_ACC_INFO_RING_MASK (BB_ACC_INFO_RING_NUM_ENTRIES - 1) 91 | #define BB_ACC_INFO_RING_PTR_MASK ((BB_ACC_INFO_RING_NUM_ENTRIES * 4) - 1) 92 | #define BB_ACC_INFO_RING_SIZE (BB_ACC_INFO_RING_NUM_ENTRIES * sizeof(uint32_t)) 93 | 94 | #define BB_ACC_FIRST_CFG true 95 | #define BB_ACC_RECFG false 96 | 97 | #define MAX(x, y) ((x) >= (y) ? (x) : (y)) 98 | 99 | /** 100 | * Flags indicate the status of the device to the application 101 | */ 102 | enum bb_acc_device_status { 103 | RTE_BBDEV_DEV_NOSTATUS, /**< Nothing being reported */ 104 | RTE_BBDEV_DEV_NOT_SUPPORTED, /**< Device status is not supported on the PMD */ 105 | RTE_BBDEV_DEV_RESET, /**< Device in reset and un-configured state */ 106 | RTE_BBDEV_DEV_CONFIGURED, /**< Device is configured and ready to use */ 107 | RTE_BBDEV_DEV_ACTIVE, /**< Device is configured and VF is being used */ 108 | RTE_BBDEV_DEV_FATAL_ERR, /**< Device has hit a fatal uncorrectable error */ 109 | RTE_BBDEV_DEV_RESTART_REQ, /**< Device requires application to restart */ 110 | RTE_BBDEV_DEV_RECONFIG_REQ, /**< Device requires application to reconfigure queues */ 111 | RTE_BBDEV_DEV_CORRECT_ERR, /**< Warning of a correctable error event happened */ 112 | }; 113 | 114 | /** 115 | * Flags indicate the status of the device to the application 116 | */ 117 | enum bb_acc_device_request { 118 | REQ_DEV_STATUS = 1, /**< Request the device status report */ 119 | REQ_DEV_NEW = 2, /**< New VF device being used */ 120 | REQ_DEV_LUT_VER = 3, /**< Request the device LUT version number. */ 121 | REQ_DEV_FFT_WIN_SIZE = 4, /**< Request window width. */ 122 | REQ_DEV_FFT_WIN_START = 5, /**< Request window start point. */ 123 | REQ_DEV_MASK = 0xFFFF 124 | }; 125 | 126 | /* Function pointers for bb dev operations */ 127 | struct bb_acc_operations { 128 | int (*open)(void *dev); 129 | int (*conf)(void *dev, void *bar0addr, const char *arg_cfg_filename, bool firstConfig); 130 | int (*enable_intr)(void *dev); 131 | int (*disable_intr)(void *dev); 132 | int (*dev_enable_intr)(void *dev); 133 | int (*dev_disable_intr)(void *dev); 134 | int (*dev_isr)(void *dev); 135 | int (*flr)(void *dev); 136 | void (*cluster_reset)(void *dev); 137 | void *(*get_bar0_addr)(const char *pci_addr, unsigned int bar_size, void *dev); 138 | void (*close)(void *dev); 139 | void (*device_data)(void *dev); 140 | }; 141 | 142 | typedef struct hw_device { 143 | const char *device_name; 144 | char *config_file; 145 | char *fft_lut_filename; 146 | int vendor_id; 147 | int device_id; 148 | char pci_address[PCI_STR_SIZE]; 149 | bool driver_found; 150 | struct bb_acc_operations ops; 151 | 152 | void *info_ring; 153 | uint64_t info_ring_phys_addr; 154 | size_t info_ring_total_size; 155 | uint16_t info_ring_head; 156 | void *bar0Addr; 157 | unsigned int bar_size; 158 | 159 | /* vfio specific */ 160 | int vfio_mode; 161 | int vfio_dev_fd; 162 | int irq_event_fd; 163 | int vfio_int_mode; 164 | int num_regions; 165 | void *iommu_map_dma_vaddr; 166 | int iommu_map_dma_size; 167 | unsigned char vfio_vf_token[VFIO_VF_TOKEN_LEN]; 168 | 169 | unsigned long dev_status[BB_ACC_MAX_VFS]; 170 | unsigned long prev_status[BB_ACC_MAX_VFS]; 171 | int auto_reconfig_on_fatal_error; 172 | int device_reset_using_flr; 173 | int numvfs; 174 | uint16_t fft_version_md5sum; 175 | int fft_win_start[BB_ACC_MAX_WIN]; 176 | int fft_win_size[BB_ACC_MAX_WIN]; 177 | } hw_device; 178 | 179 | #define PCI_VENDOR_ID 0x00 /* 16 bits */ 180 | #define PCI_DEVICE_ID 0x02 /* 16 bits */ 181 | #define PCI_COMMAND 0x04 /* 16 bits */ 182 | #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ 183 | #define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ 184 | #define PCI_REVISION_ID 0x08 /* Revision ID */ 185 | 186 | #define MAX_BB_ACC_DEV_COUNT 10 187 | #define MAX_EVENTS (MAX_BB_ACC_DEV_COUNT + 1) 188 | 189 | #define DEVICE_RESET_USING_CLUSTER 0 190 | #define DEVICE_RESET_USING_FLR 1 191 | #define DEVICE_RESET_AUTO_RECONFIG 1 192 | 193 | typedef void (*cbFp_t)(int fd, void *data); 194 | 195 | extern void *vfio_dma_alloc(void *dev, size_t size, uint64_t *phy); 196 | extern void vfio_dma_free(void *virt, size_t size); 197 | extern void *vfio_get_bar0_mapping(const char *pci_addr, unsigned int bar_size, void *hwd); 198 | extern int vfio_device_open(void *dev); 199 | extern int vfio_device_reset(void *dev); 200 | extern int vfio_enable_intr(void *dev); 201 | extern int vfio_disable_intr(void *dev); 202 | extern int vfio_irq_loopback_test(hw_device *hwd); 203 | extern int vfio_write(int fd, void *buf, size_t len, off_t off); 204 | extern int vfio_read(int fd, void *buf, size_t len, off_t off); 205 | extern int vfio_uuid_parse(char *uuid_str, unsigned char *uuid); 206 | extern void vfio_device_close(hw_device *dev); 207 | extern int event_add_fd(int fd, cbFp_t cbFp, void *cbData); 208 | extern int event_del_fd(int fd); 209 | extern void event_init_fd(void); 210 | 211 | extern int bb_acc_dev_reset_and_reconfig(void *accel_dev); 212 | extern int bb_acc_cluster_reset_and_reconfig(void *accel_dev); 213 | extern int bb_acc_cluster_reset_and_flr_reconfig(void *accel_dev); 214 | extern void bb_acc_set_all_device_status(void *dev, unsigned int status); 215 | extern const char *bb_acc_device_status_str(unsigned int status); 216 | 217 | extern int cmd_handler(int argc, char *argv[]); 218 | extern void daemonize(hw_device *dev); 219 | 220 | extern int update_reset_mode(void *dev, int mode); 221 | extern int auto_reset_mode(void *dev, int mode); 222 | 223 | extern void clear_log_file(void *dev); 224 | extern void clear_log_resp_file(void *dev); 225 | extern void exit_app_mode(void *dev); 226 | extern int acc_reg_dump(void *dev, int devId); 227 | extern int acc_mem_read(void *dev, int rwFlag, int regAddr, int wPayload); 228 | extern void acc_device_data(void *dev); 229 | 230 | int unix_channel_init(void); 231 | int unix_channel_rx(void); 232 | 233 | extern int 234 | print_stat32(char *buf, int offset, int len, uint32_t stat); 235 | 236 | extern void 237 | print_all_stat32(hw_device *accel_dev, uint32_t address, int num, int reg_offset); 238 | 239 | /* 240 | * Configure ACC100 241 | */ 242 | extern int 243 | acc100_configure(void *dev, void *bar0addr, const char *arg_cfg_filename, const bool first_cfg); 244 | 245 | extern void 246 | acc100_device_data(void *dev); 247 | 248 | /* 249 | * Configure VRB1 250 | */ 251 | extern int 252 | vrb1_configure(void *dev, void *bar0addr, const char *arg_cfg_filename, const bool first_cfg); 253 | 254 | extern int 255 | vrb1_enable_intr(void *); 256 | 257 | extern int 258 | vrb1_disable_intr(void *); 259 | 260 | extern int 261 | vrb1_irq_handler(void *dev); 262 | 263 | extern void 264 | vrb1_cluster_reset(void *dev); 265 | 266 | extern int vrb1_get_info_ring_size(void); 267 | 268 | extern void 269 | vrb1_device_data(void *dev); 270 | 271 | /* 272 | * Configure VRB2 273 | */ 274 | extern int 275 | vrb2_configure(void *dev, void *bar0addr, const char *arg_cfg_filename, const bool first_cfg); 276 | 277 | extern int 278 | vrb2_enable_intr(void *); 279 | 280 | extern int 281 | vrb2_disable_intr(void *); 282 | 283 | extern int 284 | vrb2_irq_handler(void *dev); 285 | 286 | extern void 287 | vrb2_cluster_reset(void *dev); 288 | 289 | extern int 290 | vrb2_get_info_ring_size(void); 291 | 292 | extern void 293 | vrb2_device_data(void *dev); 294 | 295 | extern void 296 | vrb_fft_lut_md5sum(const char *lut_filename, hw_device *accel_pci_dev); 297 | 298 | extern void 299 | vrb_fft_win_check(int16_t *gTDWinCoff, hw_device *accel_pci_dev); 300 | 301 | /* 302 | * Configure FPGA 303 | */ 304 | extern int 305 | fpga_lte_configure(void *dev, void *bar0addr, const char *arg_cfg_filename, const bool first_cfg); 306 | extern int 307 | fpga_5gnr_configure(void *dev, void *bar0addr, const char *arg_cfg_filename, const bool first_cfg); 308 | extern int 309 | agx100_configure(void *dev, void *bar0addr, const char *arg_cfg_filename, const bool first_cfg); 310 | 311 | extern void sig_fun(int sig); 312 | #endif /* __BB_ACC_H__ */ 313 | -------------------------------------------------------------------------------- /bb_acc_common.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "cfg_reader.h" 28 | #include "bb_acc_reg_dump.h" 29 | #include "bb_acc.h" 30 | #include "bb_acc_log.h" 31 | 32 | #define BBDEV_DEV_STATUS_COUNT 9 33 | 34 | /* Protected address ranges. */ 35 | #define VRB1_QMGR_BA_START 0xA01000 36 | #define VRB1_QMGR_BA_END 0xA02000 37 | #define VRB1_ARAM_START 0x818000 38 | #define VRB1_ARAM_END 0x820000 39 | #define VRB1_QOS_A_START 0xB900C0 40 | #define VRB1_QOS_A_END 0xB900E0 41 | #define VRB1_QOS_B_START 0xBA00C0 42 | #define VRB1_QOS_B_END 0xBA00E0 43 | #define VRB1_QOS_C_START 0xBB00C0 44 | #define VRB1_QOS_C_END 0xBB00E0 45 | #define VRB2_QMGR_BA_START 0xA08000 46 | #define VRB2_QMGR_BA_END 0xA0A000 47 | #define VRB2_ARAM_START 0x818000 48 | #define VRB2_ARAM_END 0x820000 49 | #define VRB2_MLD_START 0xB5E000 50 | #define VRB2_MLD_END 0xB60000 51 | 52 | static uint32_t 53 | reg_read(uint8_t *mmio_base, uint32_t offset) 54 | { 55 | 56 | void *reg_addr = mmio_base + offset; 57 | uint32_t ret = *((volatile uint32_t *)(reg_addr)); 58 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 59 | ret = __bswap_32(ret); 60 | #endif 61 | return ret; 62 | } 63 | 64 | static void 65 | reg_write(uint8_t *mmio_base, uint32_t offset, uint32_t payload) 66 | { 67 | void *reg_addr = mmio_base + offset; 68 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 69 | payload = __bswap_32(payload); 70 | #endif 71 | *((volatile uint32_t *) (reg_addr)) = payload; 72 | } 73 | 74 | const char * 75 | bb_acc_device_status_str(unsigned int status) 76 | { 77 | static const char * const dev_sta_string[] = { 78 | "RTE_BBDEV_DEV_NOSTATUS", 79 | "RTE_BBDEV_DEV_NOT_SUPPORTED", 80 | "RTE_BBDEV_DEV_RESET", 81 | "RTE_BBDEV_DEV_CONFIGURED", 82 | "RTE_BBDEV_DEV_ACTIVE", 83 | "RTE_BBDEV_DEV_FATAL_ERR", 84 | "RTE_BBDEV_DEV_RESTART_REQ", 85 | "RTE_BBDEV_DEV_RECONFIG_REQ", 86 | "RTE_BBDEV_DEV_CORRECT_ERR", 87 | }; 88 | 89 | if (status < BBDEV_DEV_STATUS_COUNT) 90 | return dev_sta_string[status]; 91 | 92 | LOG(ERR, "Invalid device status"); 93 | 94 | return NULL; 95 | } 96 | 97 | static int 98 | bb_acc_reconfigure_device(hw_device *accel_dev) 99 | { 100 | 101 | /* Call device specific configuration function */ 102 | if (accel_dev->ops.conf(accel_dev, accel_dev->bar0Addr, accel_dev->config_file, 103 | BB_ACC_RECFG)) { 104 | LOG(ERR, "Reconfiguration failed"); 105 | return -1; 106 | } 107 | 108 | /* enable intr if supported, applicable only in case of vfio */ 109 | if ((accel_dev->ops.enable_intr) && 110 | (accel_dev->ops.enable_intr(accel_dev))) { 111 | LOG(ERR, "Enable interrupts failed"); 112 | return -1; 113 | } 114 | 115 | LOG(INFO, "%s PF [%s] Reconfiguration complete!", 116 | accel_dev->device_name, accel_dev->pci_address); 117 | 118 | bb_acc_set_all_device_status(accel_dev, RTE_BBDEV_DEV_CONFIGURED); 119 | 120 | return 0; 121 | } 122 | 123 | int 124 | bb_acc_dev_reset_and_reconfig(void *dev) 125 | { 126 | hw_device *accel_dev = (hw_device *)dev; 127 | 128 | if (dev == NULL) { 129 | LOG(ERR, "Device not set"); 130 | return -1; 131 | } 132 | 133 | /* disable interrupts */ 134 | if ((accel_dev->ops.disable_intr) && 135 | (accel_dev->ops.disable_intr(accel_dev))) { 136 | LOG(ERR, "Disable interrupts failed"); 137 | return -1; 138 | } 139 | 140 | /* reset */ 141 | if ((accel_dev->ops.flr) && 142 | (accel_dev->ops.flr(accel_dev))) { 143 | LOG(ERR, "Device reset failed"); 144 | } 145 | 146 | /* re-init and configure the device */ 147 | if (bb_acc_reconfigure_device(accel_dev)) 148 | return -1; 149 | 150 | return 0; 151 | } 152 | 153 | int 154 | bb_acc_cluster_reset_and_reconfig(void *dev) 155 | { 156 | hw_device *accel_dev = (hw_device *)dev; 157 | 158 | LOG(DEBUG, "Cluster reset and reconfig"); 159 | 160 | if (accel_dev == NULL) 161 | return 0; 162 | 163 | /* disable interrupts */ 164 | if ((accel_dev->ops.disable_intr) && 165 | (accel_dev->ops.disable_intr(accel_dev))) { 166 | LOG(ERR, "Disable interrupts failed"); 167 | return -1; 168 | } 169 | 170 | if (accel_dev->ops.cluster_reset) 171 | accel_dev->ops.cluster_reset(accel_dev); 172 | else 173 | LOG(ERR, "Cluster reset is not supported"); 174 | 175 | /* re-init and configure the device */ 176 | if (bb_acc_reconfigure_device(accel_dev)) 177 | return -1; 178 | 179 | LOG(DEBUG, "Done"); 180 | return 0; 181 | } 182 | 183 | /* Do both a cluster reset then a PFLR. */ 184 | int 185 | bb_acc_cluster_reset_and_flr_reconfig(void *dev) 186 | { 187 | hw_device *accel_dev = (hw_device *)dev; 188 | 189 | LOG(DEBUG, "Cluster reset and reconfig"); 190 | 191 | if (accel_dev == NULL) 192 | return 0; 193 | 194 | /* Disable interrupts. */ 195 | if ((accel_dev->ops.disable_intr) && 196 | (accel_dev->ops.disable_intr(accel_dev))) { 197 | LOG(ERR, "Disable interrupts failed"); 198 | return -1; 199 | } 200 | 201 | /* Cluster reset first. */ 202 | if (accel_dev->ops.cluster_reset) 203 | accel_dev->ops.cluster_reset(accel_dev); 204 | else 205 | LOG(ERR, "Cluster reset is not supported"); 206 | 207 | /* PF FLR. */ 208 | if ((accel_dev->ops.flr) && 209 | (accel_dev->ops.flr(accel_dev))) { 210 | LOG(ERR, "Device reset failed"); 211 | } 212 | 213 | /* Re-init and configure the device. */ 214 | if (bb_acc_reconfigure_device(accel_dev)) 215 | return -1; 216 | 217 | LOG(DEBUG, "Done"); 218 | return 0; 219 | } 220 | 221 | 222 | void 223 | bb_acc_set_all_device_status(void *dev, unsigned int status) 224 | { 225 | unsigned int i; 226 | hw_device *accel_dev = (hw_device *)dev; 227 | 228 | for (i = 0; i < BB_ACC_MAX_VFS; i++) { 229 | if (status == RTE_BBDEV_DEV_CONFIGURED) { 230 | /* After Hard reset the application needs to restart/reconfigure */ 231 | if (accel_dev->dev_status[i] == RTE_BBDEV_DEV_FATAL_ERR) { 232 | if (accel_dev->device_reset_using_flr == DEVICE_RESET_USING_FLR) 233 | accel_dev->dev_status[i] = RTE_BBDEV_DEV_RESTART_REQ; 234 | else 235 | accel_dev->dev_status[i] = RTE_BBDEV_DEV_RECONFIG_REQ; 236 | } else 237 | accel_dev->dev_status[i] = RTE_BBDEV_DEV_CONFIGURED; 238 | } else 239 | accel_dev->dev_status[i] = status; 240 | } 241 | } 242 | 243 | int 244 | update_reset_mode(void *dev, int mode) 245 | { 246 | hw_device *accel_dev = (hw_device *)dev; 247 | 248 | LOG(DEBUG, "Change reset mode:"); 249 | 250 | accel_dev->device_reset_using_flr = mode; 251 | 252 | LOG(DEBUG, "Done"); 253 | 254 | return 0; 255 | } 256 | 257 | int 258 | auto_reset_mode(void *dev, int mode) 259 | { 260 | hw_device *accel_dev = (hw_device *)dev; 261 | 262 | LOG(DEBUG, "Auto reset mode change: "); 263 | 264 | accel_dev->auto_reconfig_on_fatal_error = mode; 265 | 266 | LOG(DEBUG, "Done"); 267 | 268 | return 0; 269 | } 270 | 271 | void 272 | clear_log_file(void *dev) 273 | { 274 | char log_file[BB_ACC_LOG_FILE_LEN]; 275 | hw_device *accel_dev = (hw_device *)dev; 276 | sprintf(log_file, "%s/pf_bb_cfg_%s.log", BB_ACC_DEFAULT_LOG_PATH, 277 | accel_dev->pci_address); 278 | LOG(DEBUG, "log_file = %s", log_file); 279 | bb_acc_reset_logFile(log_file, BB_ACC_LOG_MAIN); 280 | } 281 | 282 | void 283 | clear_log_resp_file(void *dev) 284 | { 285 | char log_file[BB_ACC_LOG_FILE_LEN]; 286 | hw_device *accel_dev = (hw_device *)dev; 287 | sprintf(log_file, "%s/pf_bb_cfg_%s_response.log", BB_ACC_DEFAULT_LOG_PATH, 288 | accel_dev->pci_address); 289 | LOG(DEBUG, "logRespFile = %s", log_file); 290 | bb_acc_reset_logFile(log_file, BB_ACC_LOG_RESP); 291 | } 292 | 293 | int 294 | acc100_reg_dump(hw_device *accel_dev, 295 | struct acc100_reg_dump_info *rd_db, 296 | int num_regs) 297 | { 298 | int i = 0; 299 | int payload = 0; 300 | for (i = 0; i < num_regs; i++) { 301 | payload = reg_read( 302 | accel_dev->bar0Addr, 303 | rd_db[i].reg_offset); 304 | LOG_RESP(INFO, "%s\t\t, 0x%08x, 0x%08x", rd_db[i].reg_name, 305 | rd_db[i].reg_offset, payload); 306 | } 307 | return 0; 308 | } 309 | 310 | int 311 | vrb1_reg_dump(hw_device *accel_dev, 312 | struct vrb1_reg_dump_info *rd_db, 313 | int num_regs) 314 | { 315 | int i = 0; 316 | int payload = 0; 317 | for (i = 0; i < num_regs; i++) { 318 | payload = reg_read( 319 | accel_dev->bar0Addr, 320 | rd_db[i].reg_offset); 321 | LOG_RESP(INFO, "%s\t\t, 0x%08x, 0x%08x", rd_db[i].reg_name, 322 | rd_db[i].reg_offset, payload); 323 | } 324 | return 0; 325 | } 326 | 327 | int 328 | vrb2_reg_dump(hw_device *accel_dev, 329 | struct vrb2_reg_dump_info *rd_db, 330 | int num_regs) 331 | { 332 | int i = 0; 333 | int payload = 0; 334 | for (i = 0; i < num_regs; i++) { 335 | payload = reg_read( 336 | accel_dev->bar0Addr, 337 | rd_db[i].reg_offset); 338 | LOG_RESP(INFO, "%s\t\t, 0x%08x, 0x%08x", rd_db[i].reg_name, 339 | rd_db[i].reg_offset, payload); 340 | } 341 | return 0; 342 | } 343 | 344 | int acc_reg_dump(void *dev, int devType) 345 | { 346 | hw_device *device = (hw_device *)dev; 347 | int num; 348 | 349 | if (device->device_id != devType) { 350 | printf("ERR: Wrong device configured\n"); 351 | return 0; 352 | } 353 | clear_log_resp_file(dev); 354 | 355 | if (devType == ACC100_DEVICE_ID) { 356 | num = sizeof(acc100_rd_db) / sizeof(struct acc100_reg_dump_info); 357 | acc100_reg_dump(device, acc100_rd_db, num); 358 | } else if (devType == VRB1_DEVICE_ID) { 359 | num = sizeof(vrb1_rd_db) / sizeof(struct vrb1_reg_dump_info); 360 | vrb1_reg_dump(device, vrb1_rd_db, num); 361 | } else if (devType == VRB2_DEVICE_ID) { 362 | num = sizeof(vrb2_rd_db) / sizeof(struct vrb2_reg_dump_info); 363 | vrb2_reg_dump(device, vrb2_rd_db, num); 364 | } else 365 | LOG_RESP(ERR, "Wrong Device for ref_dump!"); 366 | 367 | LOG_RESP_END(); 368 | return 0; 369 | } 370 | 371 | int acc_mem_read(void *dev, int rwFlag, int regAddr, int wPayload) 372 | { 373 | hw_device *device = (hw_device *)dev; 374 | uint32_t payload = 0x0; 375 | LOG(DEBUG, "rwFlag = %d, regAddr = 0x%x, wPayload = 0x%x\n", 376 | rwFlag, regAddr, wPayload); 377 | clear_log_resp_file(dev); 378 | /* Protection specific to VRB registers. */ 379 | if (device->device_id == VRB1_DEVICE_ID) { 380 | if ((regAddr >= VRB1_QMGR_BA_START) && (regAddr < VRB1_QMGR_BA_END)) { 381 | LOG_RESP(ERR, "Invalid Address for VRB1 0x%x", regAddr); 382 | LOG_RESP_END(); 383 | return 0; 384 | } 385 | if ((regAddr >= VRB1_ARAM_START) && (regAddr < VRB1_ARAM_END)) { 386 | LOG_RESP(ERR, "Invalid ARAM Address for VRB1 0x%x", regAddr); 387 | LOG_RESP_END(); 388 | return 0; 389 | } 390 | if ((regAddr >= VRB1_QOS_A_START) && (regAddr < VRB1_QOS_A_END)) { 391 | LOG_RESP(ERR, "Invalid QoS A Address for VRB1 0x%x", regAddr); 392 | LOG_RESP_END(); 393 | return 0; 394 | } 395 | if ((regAddr >= VRB1_QOS_B_START) && (regAddr < VRB1_QOS_B_END)) { 396 | LOG_RESP(ERR, "Invalid QoS B Address for VRB1 0x%x", regAddr); 397 | LOG_RESP_END(); 398 | return 0; 399 | } 400 | if ((regAddr >= VRB1_QOS_C_START) && (regAddr < VRB1_QOS_C_END)) { 401 | LOG_RESP(ERR, "Invalid QoS C Address for VRB1 0x%x", regAddr); 402 | LOG_RESP_END(); 403 | return 0; 404 | } 405 | } 406 | if (device->device_id == VRB2_DEVICE_ID) { 407 | if ((regAddr >= VRB2_QMGR_BA_START) && (regAddr < VRB2_QMGR_BA_END)) { 408 | LOG_RESP(ERR, "Invalid Address for VRB2 0x%x", regAddr); 409 | LOG_RESP_END(); 410 | return 0; 411 | } 412 | if ((regAddr >= VRB2_ARAM_START) && (regAddr < VRB2_ARAM_END)) { 413 | LOG_RESP(ERR, "Invalid ARAM Address for VRB2 0x%x", regAddr); 414 | LOG_RESP_END(); 415 | return 0; 416 | } 417 | if ((regAddr >= VRB2_MLD_START) && (regAddr < VRB2_MLD_END)) { 418 | LOG_RESP(ERR, "Invalid MLD Address for VRB2 0x%x", regAddr); 419 | LOG_RESP_END(); 420 | return 0; 421 | } 422 | } 423 | 424 | /* Prevent 4B read outside of PF BAR. */ 425 | if ((regAddr + 4) > device->bar_size) { 426 | LOG_RESP(ERR, "Invalid address range for PF BAR 0x%x", regAddr); 427 | LOG_RESP_END(); 428 | return 0; 429 | } 430 | 431 | switch (rwFlag) { 432 | default: 433 | case MM_READ_REG_READ: 434 | payload = reg_read(device->bar0Addr, regAddr); 435 | LOG_RESP(INFO, "Read 0x%08X 0x%08X\n", regAddr, payload); 436 | break; 437 | case MM_READ_REG_WRITE: 438 | LOG_RESP(INFO, "Write 0x%08X 0x%08X\n", regAddr, wPayload); 439 | reg_write(device->bar0Addr, regAddr, wPayload); 440 | break; 441 | } 442 | LOG_RESP_END(); 443 | return 0; 444 | } 445 | 446 | void 447 | print_all_stat32(hw_device *accel_dev, uint32_t address, int num, int reg_offset) 448 | { 449 | char buf[512]; 450 | size_t len; 451 | uint32_t vf_idx, payload; 452 | 453 | memset(buf, 0, 512); 454 | len = 0; 455 | 456 | for (vf_idx = 0; vf_idx < num; vf_idx++) { 457 | payload = reg_read(accel_dev->bar0Addr, address + reg_offset * vf_idx); 458 | len = print_stat32(buf, len, 1024, payload); 459 | } 460 | LOG_RESP(INFO, "%s", buf); 461 | } 462 | 463 | int 464 | print_stat32(char *buf, int offset, int len, uint32_t stat) 465 | { 466 | offset += snprintf(buf + offset, len - offset, "%u ", stat); 467 | return offset; 468 | } 469 | 470 | void acc_device_data(void *dev) 471 | { 472 | hw_device *device = (hw_device *)dev; 473 | clear_log_resp_file(dev); 474 | 475 | if (device->device_id == ACC100_DEVICE_ID) 476 | acc100_device_data(device); 477 | else if (device->device_id == VRB1_DEVICE_ID) 478 | vrb1_device_data(device); 479 | else if (device->device_id == VRB2_DEVICE_ID) 480 | vrb2_device_data(device); 481 | LOG_RESP_END(); 482 | } 483 | 484 | -------------------------------------------------------------------------------- /bb_acc_log.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define BB_ACC_MAX_LOG_FILE_NAME 500 27 | struct bb_acc_logCtl { 28 | int level; 29 | FILE *main_fp; 30 | FILE *secondary_fp; 31 | uint64_t maxSize; 32 | int vfiopciMode; 33 | }; 34 | 35 | const char *logStr[] = { 36 | "ERR", 37 | "WARN", 38 | "INFO", 39 | "DEBUG" 40 | }; 41 | 42 | static struct bb_acc_logCtl logCtl; 43 | 44 | static int 45 | bb_acc_vlog(int level, int log_type, const char *format, va_list ap) 46 | { 47 | int ret; 48 | if (!logCtl.vfiopciMode) { 49 | if (level > logCtl.level) 50 | return 0; 51 | ret = vprintf(format, ap); 52 | } else { 53 | FILE *fp = logCtl.main_fp; 54 | if (log_type != 0) 55 | fp = logCtl.secondary_fp; 56 | 57 | if (level > logCtl.level) 58 | return 0; 59 | 60 | if (fp == NULL) 61 | return -1; 62 | 63 | if (ftell(fp) > logCtl.maxSize) 64 | fseek(fp, 0, SEEK_SET); 65 | 66 | ret = vfprintf(fp, format, ap); 67 | fflush(fp); 68 | } 69 | return ret; 70 | } 71 | 72 | int 73 | bb_acc_log(int level, int log_type, const char *format, ...) 74 | { 75 | va_list ap; 76 | int ret; 77 | 78 | va_start(ap, format); 79 | ret = bb_acc_vlog(level, log_type, format, ap); 80 | va_end(ap); 81 | 82 | return ret; 83 | } 84 | 85 | int 86 | bb_acc_logInit(char *main_file_name, char *resp_file_name, uint64_t size, int level, 87 | int vfiopciMode) 88 | { 89 | FILE *fp = NULL, *fp_2 = NULL; 90 | 91 | if (!vfiopciMode) { 92 | /* igb_uio mode. */ 93 | logCtl.main_fp = fp; 94 | logCtl.secondary_fp = fp; 95 | logCtl.maxSize = size; /* having no use. */ 96 | logCtl.level = level; 97 | logCtl.vfiopciMode = vfiopciMode; 98 | } else { 99 | if (logCtl.main_fp != NULL) 100 | return 0; 101 | 102 | fp = fopen(main_file_name, "r+"); 103 | if (fp == NULL) { 104 | fp = fopen(main_file_name, "w+"); 105 | if (fp == NULL) { 106 | perror("Log file open failed"); 107 | return -1; 108 | } 109 | } 110 | fp_2 = fopen(resp_file_name, "r+"); 111 | if (fp_2 == NULL) { 112 | fp_2 = fopen(resp_file_name, "w+"); 113 | if (fp_2 == NULL) { 114 | perror("Log file open failed"); 115 | fclose(fp); 116 | return -1; 117 | } 118 | } 119 | 120 | logCtl.main_fp = fp; 121 | logCtl.secondary_fp = fp_2; 122 | logCtl.maxSize = size; 123 | logCtl.level = level; 124 | logCtl.vfiopciMode = vfiopciMode; 125 | fseek(fp, 0, SEEK_END); 126 | fseek(fp_2, 0, SEEK_END); 127 | } 128 | return 0; 129 | } 130 | 131 | void 132 | bb_acc_logExit() 133 | { 134 | if (logCtl.main_fp == NULL) 135 | return; 136 | 137 | fclose(logCtl.main_fp); 138 | fclose(logCtl.secondary_fp); 139 | } 140 | 141 | void 142 | bb_acc_reset_logFile(char *file_name, int log_type) 143 | { 144 | char sysCmd[1024]; 145 | memset(sysCmd, 0, sizeof(sysCmd)); 146 | if (logCtl.main_fp == NULL) 147 | return; 148 | sprintf(sysCmd, "truncate -s 0 %s", file_name); 149 | if (system(sysCmd)) { 150 | perror("Failed to clear the log file"); 151 | return; 152 | } 153 | if (log_type == 0) 154 | fseek(logCtl.main_fp, 0, SEEK_SET); 155 | else 156 | fseek(logCtl.secondary_fp, 0, SEEK_SET); 157 | } 158 | -------------------------------------------------------------------------------- /bb_acc_log.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef __BB_ACC_LOG_H__ 20 | #define __BB_ACC_LOG_H__ 21 | 22 | #include 23 | 24 | typedef enum { 25 | ERR = 0, 26 | WARN, 27 | INFO, 28 | DEBUG 29 | } bb_acc_log_level; 30 | 31 | extern const char *logStr[]; 32 | 33 | static char *timestamp() 34 | { 35 | char *time_s; 36 | time_t now = time(NULL); 37 | const struct tm *gtm = gmtime(&now); 38 | if (gtm == NULL) 39 | return NULL; 40 | 41 | time_s = asctime(gtm); 42 | if (time_s == NULL) 43 | return NULL; 44 | 45 | time_s[strlen(time_s)-1] = '\0'; 46 | return time_s; 47 | } 48 | 49 | /* Default log file size is 2MB */ 50 | #define BB_ACC_MAX_LOG_FILE_SIZE (2 * 1024 * 1024) 51 | 52 | /* Default log file path and name */ 53 | #define BB_ACC_DEFAULT_LOG_PATH "/var/log" 54 | #define BB_ACC_LOG_FILE_LEN 128 55 | 56 | #define BB_ACC_LOG_MAIN 0 57 | #define BB_ACC_LOG_RESP 1 58 | 59 | #define BB_ACC_LOG_RAW(level, fmt, args...) \ 60 | bb_acc_log(level, BB_ACC_LOG_MAIN, "%s:%s:%s(): " fmt "\n", \ 61 | timestamp(), logStr[level], __func__, ## args) 62 | 63 | #define BB_ACC_LOG(level, fmt, args...) \ 64 | bb_acc_log(level, BB_ACC_LOG_MAIN, "%s:%s:" fmt "\n", timestamp(), logStr[level], ## args) 65 | 66 | #define LOG(level, fmt, args...) \ 67 | ({\ 68 | if (level == DEBUG)\ 69 | BB_ACC_LOG_RAW(level, fmt, ## args);\ 70 | else\ 71 | BB_ACC_LOG(level, fmt, ## args);\ 72 | }) 73 | 74 | #define LOG_RESP(level, fmt, args...) \ 75 | bb_acc_log(level, BB_ACC_LOG_RESP, "%s:%s:" fmt "\n", timestamp(), logStr[level], ## args) 76 | 77 | #define LOG_RESP_END() \ 78 | LOG_RESP(INFO, "-- End of Response --") 79 | 80 | 81 | extern int bb_acc_log(int level, int log_type, const char *format, ...); 82 | extern int bb_acc_logInit(char *main_file_name, char *resp_file_name, uint64_t size, 83 | int level, int vfiopciMode); 84 | extern void bb_acc_logExit(void); 85 | extern void bb_acc_reset_logFile(char *file_name, int log_type); 86 | 87 | #endif /* __BB_ACC_LOG_H__ */ 88 | -------------------------------------------------------------------------------- /bsd-3-clause.txt: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 2 | 3 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 4 | 5 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 6 | 7 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION_STRING=`git describe --tags --long` 4 | echo ${VERSION_STRING} 5 | sed -i "s/#VERSION_STRING#/${VERSION_STRING}/g" config_app.c 6 | make clean 7 | make 8 | -------------------------------------------------------------------------------- /cfg_reader/cfg_reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "cfg_reader.h" 5 | 6 | /*rstrip function, remove right space*/ 7 | static char* 8 | rstrip(char *s) 9 | { 10 | char *p = s + strlen(s); 11 | while (p > s) { 12 | p--; 13 | if (*p == ' ' || *s == '\t' || *p == '\n') 14 | *p = '\0'; 15 | else 16 | break; 17 | } 18 | return s; 19 | } 20 | 21 | /*lstrip function, remove left space*/ 22 | static char* 23 | lstrip(char *s) 24 | { 25 | while (*s && (*s == ' ' || *s == '\t' || *s == '\n')) 26 | s++; 27 | return s; 28 | } 29 | 30 | 31 | 32 | /*forward search targets location and pointer move to it*/ 33 | static char* 34 | jump_to_targets_location(char *s, char *targets) 35 | { 36 | if (targets == NULL) { 37 | while (*s && (*s != '\0')) 38 | s++; 39 | return s; 40 | } 41 | while (*s && (*s != '\0')) { 42 | if (strchr(targets, *s)) 43 | break; 44 | s++; 45 | } 46 | return s; 47 | } 48 | 49 | /*cfg parse main workflow*/ 50 | int 51 | cfg_parse_contents(void *contents, cfg_handler handler, void *user) 52 | { 53 | 54 | char line[CFG_MAX_LINE_LEN]; 55 | int max_line_len = CFG_MAX_LINE_LEN; 56 | 57 | char section[MAX_SECTION_LEN] = ""; 58 | char name[MAX_NAME_LEN] = ""; 59 | 60 | char *left; 61 | char *right; 62 | char *cur_name; 63 | char *value; 64 | int line_num = 0; 65 | int error_line_index = 0; 66 | 67 | while (fgets(line, max_line_len, contents) != NULL) { 68 | 69 | line_num++; 70 | left = line; 71 | /* skip UTF-8 BOM char sequence if it exists */ 72 | left = (line_num == 1 && left[0] == 0xEF && left[1] == 0xBB 73 | && left[2] == 0xBF) ? (left + 3) : left; 74 | 75 | left = lstrip(rstrip(left)); 76 | 77 | if (*left == ';' || *left == '#') { 78 | /* skip start-of-line comment */ 79 | continue; 80 | } else if (*left == '[') { 81 | /* parse "section" */ 82 | right = jump_to_targets_location(left + 1, "]"); 83 | if (*right == ']') { 84 | *right = '\0'; 85 | strncpy(section, left + 1, MAX_SECTION_LEN - 1); 86 | section[MAX_SECTION_LEN - 1] = '\0'; 87 | } else { 88 | printf("error, no [ exists\n"); 89 | error_line_index = line_num; 90 | break; 91 | } 92 | } else if (*left) { 93 | right = jump_to_targets_location(left, "=:"); 94 | if (*right == '=' || *right == ':') { 95 | /* parse "name" and "value" */ 96 | *right = '\0'; 97 | cur_name = rstrip(left); 98 | strncpy(name, cur_name, MAX_NAME_LEN - 1); 99 | name[MAX_NAME_LEN - 1] = '\0'; 100 | value = right + 1; 101 | value = lstrip(rstrip(value)); 102 | if (handler(user, section, name, value) != 1) { 103 | error_line_index = line_num; 104 | break; 105 | } 106 | } else { 107 | printf("error, no \":\" or \"=\" exists\n"); 108 | error_line_index = line_num; 109 | break; 110 | } 111 | } 112 | } 113 | 114 | return error_line_index; 115 | } 116 | 117 | /*cfg parse interface*/ 118 | int 119 | cfg_parse(const char *filename, cfg_handler handler, void *user) 120 | { 121 | 122 | FILE *file; 123 | int error_line_index; 124 | file = fopen(filename, "r"); 125 | if (!file) { 126 | printf("error, cannot load cfg files\n"); 127 | return -1; 128 | } 129 | error_line_index = cfg_parse_contents(file, handler, user); 130 | fclose(file); 131 | return error_line_index; 132 | } 133 | 134 | /*check config path's safety, return true when found unsafe path*/ 135 | bool 136 | cfg_file_check_path_safety(const char *cfg_filename) { 137 | if (cfg_filename == NULL) { 138 | /* check if the config path is "NULL" */ 139 | return true; 140 | } 141 | int offset = 0; 142 | int len = strlen(cfg_filename) + 1; 143 | if (len < 3) 144 | return false; 145 | /* check if the config path includes "../" */ 146 | for (offset = 0; offset <= len - 3; offset++) { 147 | int a = (*(cfg_filename + offset) == '.'); 148 | int b = (*(cfg_filename + offset + 1) == '.'); 149 | int c = (*(cfg_filename + offset + 2) == '/'); 150 | if (a && b && c) 151 | return true; 152 | } 153 | return false; 154 | } 155 | -------------------------------------------------------------------------------- /cfg_reader/cfg_reader.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CFG_READER_H__ 3 | #define __CFG_READER_H__ 4 | 5 | /* Make this header file easier to include in C++ code */ 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define MAX_SECTION_LEN 50 15 | #define MAX_NAME_LEN 50 16 | #define CFG_MAX_LINE_LEN 200 17 | 18 | typedef int (*cfg_handler)(void *user, const char *section, 19 | const char *name, const char *value); 20 | 21 | 22 | int cfg_parse(const char *filename, cfg_handler handler, void *user); 23 | bool cfg_file_check_path_safety(const char *cfg_filename); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* __CFG_READER_H__ */ 30 | -------------------------------------------------------------------------------- /daemon.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "bb_acc.h" 38 | #include "bb_acc_log.h" 39 | 40 | struct event_fd { 41 | int fd[MAX_EVENTS]; 42 | cbFp_t cbFp[MAX_EVENTS]; 43 | void *cbData[MAX_EVENTS]; 44 | struct pollfd pfds[MAX_EVENTS]; 45 | int pollfd_count; 46 | }; 47 | 48 | static struct event_fd eventFd; 49 | 50 | struct cmdReq cmdReq_g; 51 | 52 | static int is_sig_term_rcv; 53 | 54 | static int reset_mode_exec(struct cmdDef *cmd, void *ci); 55 | static int auto_reset_exec(struct cmdDef *cmd, void *ci); 56 | static int clear_log_exec(struct cmdDef *cmd, void *ci); 57 | static int exit_app_exec(struct cmdDef *cmd, void *ci); 58 | static int reg_dump_exec(struct cmdDef *cmd, void *ci); 59 | static int reconfigure_acc_exec(struct cmdDef *cmd, void *ci); 60 | static int mem_read_exec(struct cmdDef *cmd, void *ci); 61 | static int device_data_exec(struct cmdDef *cmd, void *ci); 62 | 63 | struct cmdDef cmd_defs[] = { 64 | { 65 | RESET_MODE_CMD_ID, "reset_mode", 66 | NULL_HELP_FP, 67 | NULL_PARSE_FP, 68 | NULL_SEND_FP, 69 | NULL_RESP_FP, 70 | NULL_PRINT_FP, 71 | reset_mode_exec, 72 | "", 73 | }, 74 | { 75 | AUTO_RESET_CMD_ID, "auto_reset", 76 | NULL_HELP_FP, 77 | NULL_PARSE_FP, 78 | NULL_SEND_FP, 79 | NULL_RESP_FP, 80 | NULL_PRINT_FP, 81 | auto_reset_exec, 82 | "", 83 | }, 84 | { 85 | CLEAR_LOG_CMD_ID, "clear_log", 86 | NULL_HELP_FP, 87 | NULL_PARSE_FP, 88 | NULL_SEND_FP, 89 | NULL_RESP_FP, 90 | NULL_PRINT_FP, 91 | clear_log_exec, 92 | "", 93 | }, 94 | { 95 | EXIT_APP_CMD_ID, "exit_app", 96 | NULL_HELP_FP, 97 | NULL_PARSE_FP, 98 | NULL_SEND_FP, 99 | NULL_RESP_FP, 100 | NULL_PRINT_FP, 101 | exit_app_exec, 102 | "", 103 | }, 104 | { 105 | REG_DUMP_CMD_ID, "reg_dump", 106 | NULL_HELP_FP, 107 | NULL_PARSE_FP, 108 | NULL_SEND_FP, 109 | NULL_RESP_FP, 110 | NULL_PRINT_FP, 111 | reg_dump_exec, 112 | "", 113 | }, 114 | { 115 | RECONFIG_ACC_CMD_ID, "reconfigure_acc", 116 | NULL_HELP_FP, 117 | NULL_PARSE_FP, 118 | NULL_SEND_FP, 119 | NULL_RESP_FP, 120 | NULL_PRINT_FP, 121 | reconfigure_acc_exec, 122 | "", 123 | }, 124 | { 125 | MM_READ_CMD_ID, "mm_read", 126 | NULL_HELP_FP, 127 | NULL_PARSE_FP, 128 | NULL_SEND_FP, 129 | NULL_RESP_FP, 130 | NULL_PRINT_FP, 131 | mem_read_exec, 132 | "", 133 | }, 134 | { 135 | DEVICE_DATA_CMD_ID, "device_data", 136 | NULL_HELP_FP, 137 | NULL_PARSE_FP, 138 | NULL_SEND_FP, 139 | NULL_RESP_FP, 140 | NULL_PRINT_FP, 141 | device_data_exec, 142 | "", 143 | }, 144 | { /* must be at the end */ 145 | -1, "", 146 | NULL_HELP_FP, 147 | NULL_PARSE_FP, 148 | NULL_SEND_FP, 149 | NULL_RESP_FP, 150 | NULL_PRINT_FP, 151 | NULL_EXEC_FP, 152 | "" 153 | } 154 | }; 155 | #define NO_OF_CMDS (int)((sizeof(cmd_defs)/sizeof(struct cmdDef))-1) 156 | 157 | int 158 | unix_channel_srv_init(hw_device *dev) 159 | { 160 | int fd; 161 | int rc; 162 | struct sockaddr_un serveraddr; 163 | char unix_channel_file[UNIX_CHANNEL_FILE_LEN]; 164 | 165 | LOG(DEBUG, "cli channel init"); 166 | sprintf(unix_channel_file, "%s.%s.sock", UNIX_CHANNEL_PATH, dev->pci_address); 167 | 168 | /* Check if the .sock file already exists */ 169 | if (access(unix_channel_file, F_OK) == 0) { 170 | LOG(INFO, "pf_bb_config might have previously exited abruptly, removing %s", 171 | unix_channel_file); 172 | /* File exists, remove it */ 173 | if (unlink(unix_channel_file) == -1) { 174 | LOG(ERR, "cli channel: failed to remove %s", unix_channel_file); 175 | return -1; 176 | } 177 | } 178 | 179 | fd = socket(AF_UNIX, SOCK_STREAM, 0); 180 | if (fd < 0) { 181 | LOG(ERR, "cli channel: socket() open failed"); 182 | return -1; 183 | } 184 | 185 | memset(&serveraddr, 0, sizeof(serveraddr)); 186 | serveraddr.sun_family = AF_UNIX; 187 | strcpy(serveraddr.sun_path, unix_channel_file); 188 | 189 | rc = bind(fd, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr)); 190 | if (rc < 0) { 191 | LOG(ERR, "cli channel: bind() failed"); 192 | close(fd); 193 | return -1; 194 | } 195 | 196 | /* supports only one client connection at a time */ 197 | rc = listen(fd, 1); 198 | if (rc < 0) { 199 | LOG(ERR, "cli channel: listen() failed"); 200 | close(fd); 201 | return -1; 202 | } 203 | 204 | LOG(DEBUG, "Done"); 205 | 206 | return fd; 207 | } 208 | 209 | static int 210 | unix_channel_srv_rx(int fd, struct cmdReq *req) 211 | { 212 | int rc; 213 | int client_fd; 214 | 215 | LOG(DEBUG, "data received on cli channel"); 216 | 217 | client_fd = accept(fd, NULL, NULL); 218 | if (client_fd < 0) { 219 | LOG(ERR, "cli channel: accept() failed"); 220 | return -1; 221 | } 222 | LOG(DEBUG, "client connected fd: %d", client_fd); 223 | 224 | rc = recv(client_fd, req, sizeof(struct cmdReq), 0); 225 | if (rc < 0) { 226 | LOG(ERR, "cmd request recv() failed"); 227 | close(client_fd); 228 | return -1; 229 | } 230 | 231 | LOG(DEBUG, "Req id: %04x, len: %d", req->id, req->len); 232 | 233 | close(client_fd); 234 | 235 | return 0; 236 | } 237 | 238 | void event_init_fd(void) 239 | { 240 | int i; 241 | 242 | LOG(DEBUG, "Event init fd"); 243 | 244 | for (i = 0; i < MAX_EVENTS; i++) 245 | eventFd.fd[i] = -1; 246 | } 247 | 248 | int event_add_fd(int fd, cbFp_t cbFp, void *cbData) 249 | { 250 | int i; 251 | 252 | if (eventFd.pollfd_count >= MAX_EVENTS) { 253 | LOG(ERR, "failed to add event fd"); 254 | return -1; 255 | } 256 | 257 | for (i = 0; i < MAX_EVENTS; i++) { 258 | if (eventFd.fd[i] != -1) 259 | continue; 260 | 261 | eventFd.fd[i] = fd; 262 | eventFd.cbFp[i] = cbFp; 263 | eventFd.cbData[i] = cbData; 264 | eventFd.pollfd_count++; 265 | LOG(DEBUG, "location: %d, pollfd_count=%d", i, eventFd.pollfd_count); 266 | return 0; 267 | } 268 | 269 | LOG(ERR, "Event fd add failed"); 270 | return -1; 271 | } 272 | 273 | int event_del_fd(int fd) 274 | { 275 | int i; 276 | 277 | for (i = 0; i < MAX_EVENTS; i++) { 278 | if (eventFd.fd[i] == fd) { 279 | eventFd.fd[i] = -1; 280 | eventFd.cbFp[i] = NULL; 281 | eventFd.cbData[i] = NULL; 282 | eventFd.pollfd_count--; 283 | LOG(DEBUG, "location: %d, pollfd_count=%d", i, eventFd.pollfd_count); 284 | return 0; 285 | } 286 | } 287 | 288 | LOG(ERR, "Event del failed"); 289 | return -1; 290 | } 291 | 292 | static void event_set_pfds(void) 293 | { 294 | int i; 295 | 296 | for (i = 0; i < MAX_EVENTS; i++) { 297 | eventFd.pfds[i].fd = eventFd.fd[i]; 298 | eventFd.pfds[i].events = POLLIN; 299 | } 300 | } 301 | 302 | static void event_process_fds(void) 303 | { 304 | int i; 305 | 306 | for (i = 0; i < MAX_EVENTS; i++) { 307 | if ((eventFd.pfds[i].fd != -1) && (eventFd.pfds[i].revents & POLLIN)) { 308 | eventFd.pfds[i].revents = 0; 309 | if (eventFd.cbFp[i]) 310 | eventFd.cbFp[i](eventFd.pfds[i].fd, eventFd.cbData[i]); 311 | } 312 | } 313 | } 314 | 315 | static int 316 | get_cmd_by_id(int cmd_id, struct cmdDef **cd) 317 | { 318 | int i; 319 | 320 | for (i = 0; i < NO_OF_CMDS; i++) { 321 | if (cmd_id == cmd_defs[i].id) 322 | break; 323 | } 324 | 325 | if (cmd_defs[i].id == -1) { 326 | LOG(ERR, "command id: %d is not supported", cmd_id); 327 | return -1; 328 | } 329 | 330 | *cd = &cmd_defs[i]; 331 | 332 | LOG(DEBUG, "found command: %s, id: %d", cmd_defs[i].cmd, cmd_defs[i].id); 333 | 334 | return 0; 335 | } 336 | 337 | void cli_channel_event_processor(int fd, void *data) 338 | { 339 | struct cmdReq *req = (struct cmdReq *)&cmdReq_g; 340 | struct cmdDef *cmd; 341 | 342 | if (data == NULL) { 343 | LOG(ERR, "event data is null"); 344 | return; 345 | } 346 | if (!unix_channel_srv_rx(fd, req)) { 347 | if (get_cmd_by_id(req->id, &cmd) == -1) 348 | return; 349 | if (cmd->exec != NULL) { 350 | req->priv = data; 351 | cmd->exec(cmd, (void *)req); 352 | } 353 | } 354 | } 355 | 356 | int cli_channel_init(hw_device *dev) 357 | { 358 | int fd; 359 | 360 | fd = unix_channel_srv_init(dev); 361 | if (fd < 0) 362 | return -1; 363 | 364 | if (event_add_fd(fd, cli_channel_event_processor, dev) < 0) { 365 | close(fd); 366 | return -1; 367 | } 368 | 369 | return fd; 370 | } 371 | 372 | /* Check events on in the given fds list 373 | * blocks on events 374 | */ 375 | static void 376 | event_processor(hw_device *dev) 377 | { 378 | char unix_channel_file[UNIX_CHANNEL_FILE_LEN]; 379 | char sysCmd[1024]; 380 | int r; 381 | 382 | while (!is_sig_term_rcv) { 383 | 384 | event_set_pfds(); 385 | 386 | LOG(DEBUG, "Waiting on poll..."); 387 | 388 | /* Waits on list of events */ 389 | r = poll(eventFd.pfds, MAX_EVENTS, -1); 390 | 391 | LOG(DEBUG, "poll() unblocked, check events (return %d)", r); 392 | 393 | /* process all events that are set */ 394 | event_process_fds(); 395 | } 396 | if (is_sig_term_rcv == 1) { 397 | LOG(INFO, "Exit event processor\n"); 398 | /* Remove the socket file */ 399 | memset(sysCmd, 0, sizeof(sysCmd)); 400 | sprintf(unix_channel_file, "%s.%s.sock", UNIX_CHANNEL_PATH, dev->pci_address); 401 | sprintf(sysCmd, "rm -fr %s", unix_channel_file); 402 | r = system(sysCmd); 403 | LOG(DEBUG, "system cmd returns = %d\n", r); 404 | /* Close the log file */ 405 | bb_acc_logExit(); 406 | } 407 | } 408 | 409 | void 410 | daemonize(hw_device *dev) 411 | { 412 | pid_t pid, sid; 413 | 414 | (void) signal(SIGTERM, sig_fun); 415 | (void) signal(SIGKILL, sig_fun); 416 | (void) signal(SIGABRT, sig_fun); 417 | (void) signal(SIGSEGV, sig_fun); 418 | (void) signal(SIGBUS, sig_fun); 419 | (void) signal(SIGILL, sig_fun); 420 | 421 | pid = fork(); 422 | if (pid < 0) 423 | exit(EXIT_FAILURE); 424 | 425 | /* exit the parent */ 426 | if (pid > 0) 427 | exit(EXIT_SUCCESS); 428 | 429 | umask(0); 430 | 431 | /* do not let the child to become orphan */ 432 | sid = setsid(); 433 | if (sid < 0) 434 | exit(EXIT_FAILURE); 435 | 436 | close(STDIN_FILENO); 437 | close(STDOUT_FILENO); 438 | close(STDERR_FILENO); 439 | 440 | if (cli_channel_init(dev) < 0) { 441 | LOG(ERR, "cli channel init failed"); 442 | return; 443 | } 444 | 445 | LOG(DEBUG, "Event processor started"); 446 | 447 | /* blocks on events */ 448 | event_processor(dev); 449 | 450 | } 451 | 452 | static int 453 | reset_mode_exec(struct cmdDef *cmd, void *ci) 454 | { 455 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 456 | struct reset_mode_req *reset_mode = (struct reset_mode_req *)CMD_REQ(ci); 457 | const char *reset_mode_str[2] = {"cluster_reset", "pf_flr"}; 458 | 459 | 460 | if ((reset_mode->mode != RESET_MODE_CLUSTER_LEVEL) && 461 | (reset_mode->mode != RESET_MODE_FLR)) { 462 | LOG(ERR, "Unknown reset_mode request:%d", reset_mode->mode); 463 | return -1; 464 | } 465 | LOG(INFO, "reset_mode set to : %s", reset_mode_str[reset_mode->mode]); 466 | 467 | update_reset_mode(cmd_req->priv, reset_mode->mode); 468 | 469 | return 0; 470 | } 471 | 472 | static int 473 | auto_reset_exec(struct cmdDef *cmd, void *ci) 474 | { 475 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 476 | struct auto_reset_req *auto_reset = (struct auto_reset_req *)CMD_REQ(ci); 477 | const char *auto_reset_str[2] = {"off", "on"}; 478 | 479 | if ((auto_reset->mode != AUTO_RESET_OFF) && 480 | (auto_reset->mode != AUTO_RESET_ON)) { 481 | LOG(ERR, "Unknown auto_reset mode: %d", auto_reset->mode); 482 | return -1; 483 | } 484 | LOG(INFO, "Auto reset set to : %s", auto_reset_str[auto_reset->mode]); 485 | 486 | auto_reset_mode(cmd_req->priv, auto_reset->mode); 487 | 488 | return 0; 489 | } 490 | 491 | static int 492 | clear_log_exec(struct cmdDef *cmd, void *ci) 493 | { 494 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 495 | 496 | LOG(DEBUG, "clear_log command received"); 497 | 498 | clear_log_file(cmd_req->priv); 499 | 500 | return 0; 501 | } 502 | static int 503 | exit_app_exec(struct cmdDef *cmd, void *ci) 504 | { 505 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 506 | hw_device *accel_dev = (hw_device *)cmd_req->priv; 507 | 508 | /* disable interrupts */ 509 | if ((accel_dev->ops.disable_intr) && 510 | (accel_dev->ops.disable_intr(accel_dev))) { 511 | LOG(ERR, "Disable interrupts failed"); 512 | return -1; 513 | } 514 | 515 | LOG(INFO, "exit_app command received"); 516 | sig_fun(0); 517 | return 0; 518 | } 519 | 520 | static int 521 | reg_dump_exec(struct cmdDef *cmd, void *ci) 522 | { 523 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 524 | struct reg_dump_req *reg_dump = (struct reg_dump_req *)CMD_REQ(ci); 525 | 526 | LOG(INFO, "reg_dump command received, device_id : 0x%x", reg_dump->device_id); 527 | 528 | acc_reg_dump(cmd_req->priv, reg_dump->device_id); 529 | 530 | return 0; 531 | } 532 | 533 | static int 534 | reconfigure_acc_exec(struct cmdDef *cmd, void *ci) 535 | { 536 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 537 | 538 | LOG(INFO, "reconfigure_acc command received"); 539 | 540 | bb_acc_dev_reset_and_reconfig(cmd_req->priv); 541 | 542 | return 0; 543 | } 544 | 545 | static int 546 | mem_read_exec(struct cmdDef *cmd, void *ci) 547 | { 548 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 549 | struct mm_read_req *mm_read = (struct mm_read_req *)CMD_REQ(ci); 550 | 551 | LOG(INFO, "mm_read command received"); 552 | LOG(DEBUG, "mm_read: reg_op_flag = 0x%x\n", mm_read->reg_op_flag); 553 | LOG(DEBUG, "mm_read: reg_rw_address = 0x%x\n", mm_read->reg_rw_address); 554 | LOG(DEBUG, "mm_read: write_payload = 0x%x\n", mm_read->write_payload); 555 | 556 | acc_mem_read(cmd_req->priv, mm_read->reg_op_flag, 557 | mm_read->reg_rw_address, mm_read->write_payload); 558 | 559 | return 0; 560 | } 561 | 562 | static int 563 | device_data_exec(struct cmdDef *cmd, void *ci) 564 | { 565 | struct cmdReq *cmd_req = (struct cmdReq *)ci; 566 | 567 | LOG(DEBUG, "device_data command received"); 568 | 569 | acc_device_data(cmd_req->priv); 570 | 571 | return 0; 572 | } 573 | 574 | void sig_fun(int sig) 575 | { 576 | uint8_t loopCnt = 0; 577 | uint16_t fdCnt = eventFd.pollfd_count; 578 | LOG(INFO, "Signal Received with sigNum = %u", sig); 579 | while (loopCnt < fdCnt) { 580 | /* Close all the communications */ 581 | close(eventFd.fd[eventFd.pollfd_count]); 582 | eventFd.pollfd_count--; 583 | loopCnt++; 584 | } 585 | /* set "is_sig_term_rcv = 1"; so that event_processor exits */ 586 | is_sig_term_rcv = 1; 587 | } 588 | -------------------------------------------------------------------------------- /fpga_5gnr/fpga_5gnr_cfg_app.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "fpga_5gnr_cfg_app.h" 28 | #include "cfg_reader.h" 29 | 30 | extern int 31 | fpga_5gnr_parse_conf_file(const char *file_name, 32 | struct fpga_5gnr_fec_conf *fpga_conf); 33 | 34 | /* Read 8-bit register of FPGA 5GNR FEC device */ 35 | static uint8_t 36 | fpga_reg_read_8(void *mmio_base, uint32_t offset) 37 | { 38 | void *reg_addr = mmio_base + offset; 39 | return *((volatile uint8_t *)(reg_addr)); 40 | } 41 | 42 | /* Read 16-bit register of FPGA 5GNR FEC device */ 43 | static uint16_t 44 | fpga_reg_read_16(void *mmio_base, uint32_t offset) 45 | { 46 | void *reg_addr = mmio_base + offset; 47 | uint16_t ret = *((volatile uint16_t *)(reg_addr)); 48 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 49 | return __bswap_16(ret); 50 | #else 51 | return ret; 52 | #endif 53 | } 54 | 55 | /* Read 32-bit register of FPGA 5GNR FEC device */ 56 | static uint32_t 57 | fpga_reg_read_32(void *mmio_base, uint32_t offset) 58 | { 59 | void *reg_addr = mmio_base + offset; 60 | uint32_t ret = *((volatile uint32_t *)(reg_addr)); 61 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 62 | return __bswap_32(ret); 63 | #else 64 | return ret; 65 | #endif 66 | } 67 | 68 | static inline void 69 | fpga_reg_write_16(void *mmio_base, uint32_t offset, 70 | uint16_t payload) { 71 | void *reg_addr = mmio_base + offset; 72 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 73 | payload = __bswap_16(payload); 74 | #endif 75 | *((volatile uint16_t *) (reg_addr)) = payload; 76 | } 77 | 78 | static inline void 79 | fpga_reg_write_32(void *mmio_base, uint32_t offset, 80 | uint32_t payload) 81 | { 82 | void *reg_addr = mmio_base + offset; 83 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 84 | payload = __bswap_32(payload); 85 | #endif 86 | *((volatile uint32_t *) (reg_addr)) = payload; 87 | } 88 | 89 | static inline void 90 | set_default_fpga_conf(struct fpga_5gnr_fec_conf *def_conf) 91 | { 92 | /* Set pf mode to true */ 93 | def_conf->pf_mode_en = true; 94 | 95 | /* Set ratio between UL and DL to 1:1 (unit of weight is 3 CBs) */ 96 | def_conf->ul_bandwidth = 3; 97 | def_conf->dl_bandwidth = 3; 98 | 99 | /* Set Load Balance Factor to 64 */ 100 | def_conf->dl_load_balance = 64; 101 | def_conf->ul_load_balance = 64; 102 | } 103 | 104 | static int 105 | fpga_read_config_file(const char *arg_cfg_filename, 106 | struct fpga_5gnr_fec_conf *fpga_5gnr_fec_conf) 107 | { 108 | bool unsafe_path = cfg_file_check_path_safety(arg_cfg_filename); 109 | if (unsafe_path == true) { 110 | printf("error, config file path \"%s\" is not safe", 111 | arg_cfg_filename); 112 | return -1; 113 | } else 114 | return fpga_5gnr_parse_conf_file(arg_cfg_filename, 115 | fpga_5gnr_fec_conf); 116 | } 117 | 118 | /* Read Static Register of FPGA 5GNR FEC device */ 119 | static inline void 120 | print_static_reg_debug_info(void *mmio_base) 121 | { 122 | uint8_t i, q_id; 123 | uint32_t fid; 124 | uint32_t version_id = fpga_reg_read_32(mmio_base, 125 | FPGA_5GNR_FEC_VERSION_ID); 126 | uint16_t config = fpga_reg_read_16(mmio_base, 127 | FPGA_5GNR_FEC_CONFIGURATION); 128 | uint8_t qmap_done = fpga_reg_read_8(mmio_base, 129 | FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE); 130 | uint16_t lb_factor = fpga_reg_read_16(mmio_base, 131 | FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR); 132 | uint16_t ring_desc_len = fpga_reg_read_16(mmio_base, 133 | FPGA_5GNR_FEC_RING_DESC_LEN); 134 | 135 | printf("FEC FPGA RTL v%u.%u\n", 136 | ((uint16_t)(version_id >> 16)), ((uint16_t)version_id)); 137 | printf("UL.DL Weights = %u.%u\n", 138 | ((uint8_t)config), ((uint8_t)(config >> 8))); 139 | printf("UL.DL Load Balance = %u.%u\n", 140 | ((uint8_t)lb_factor), ((uint8_t)(lb_factor >> 8))); 141 | printf("Queue-PF/VF Mapping Table = %s\n", 142 | (qmap_done > 0) ? "READY" : "NOT-READY"); 143 | printf("Ring Descriptor Size = %u bytes\n", 144 | ring_desc_len*FPGA_RING_DESC_LEN_UNIT_BYTES); 145 | 146 | printf("\n--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n"); 147 | printf(" | PF | VF0 | VF1 | VF2 | VF3 | VF4 | VF5 | VF6 | VF7 |\n"); 148 | printf("--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n"); 149 | 150 | for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; q_id++) { 151 | 152 | printf("%s-Q'%02u |", 153 | (q_id < FPGA_NUM_UL_QUEUES) ? "UL" : "DL", q_id); 154 | 155 | fid = fpga_reg_read_32(mmio_base, 156 | FPGA_5GNR_FEC_QUEUE_MAP + (q_id << 2)); 157 | 158 | for (i = 0; i < 9; ++i) { 159 | 160 | if (!((fid >> 16) & (0x80)) && i == 0) { 161 | printf(" X |"); 162 | continue; 163 | } 164 | 165 | if (((((fid >> 16) & (0x7f)) + 1) == i) && 166 | ((fid >> 16) & (0x80))) 167 | printf(" X |"); 168 | else 169 | printf(" |"); 170 | } 171 | printf("\n"); 172 | } 173 | printf("--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n\n"); 174 | } 175 | 176 | static int 177 | fpga_write_config(void *dev, void *mapaddr, struct fpga_5gnr_fec_conf *conf) 178 | { 179 | 180 | uint32_t payload_32, address; 181 | uint16_t payload_16; 182 | uint16_t q_id, vf_id, total_q_id, total_ul_q_id, total_dl_q_id; 183 | 184 | uint32_t *bar0addr = mapaddr; 185 | 186 | /* 187 | * Configure UL:DL ratio. 188 | * [7:0]: UL weight 189 | * [15:8]: DL weight 190 | */ 191 | payload_16 = (conf->dl_bandwidth << 8) | conf->ul_bandwidth; 192 | address = FPGA_5GNR_FEC_CONFIGURATION; 193 | fpga_reg_write_16(bar0addr, address, payload_16); 194 | 195 | /* Clear all queues registers */ 196 | payload_32 = FPGA_INVALID_HW_QUEUE_ID; 197 | for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) { 198 | address = (q_id << 2) + FPGA_5GNR_FEC_QUEUE_MAP; 199 | fpga_reg_write_32(bar0addr, address, payload_32); 200 | } 201 | 202 | /* 203 | * If PF mode is enabled allocate all queues for PF only. 204 | * 205 | * For VF mode each VF can have different number of UL and DL queues. 206 | * Total number of queues to configure cannot exceed FPGA 207 | * capabilities - 64 queues - 32 queues for UL and 32 queues for DL. 208 | * Queues mapping is done according to configuration: 209 | * 210 | * UL queues: 211 | * | Q_ID | VF_ID | 212 | * | 0 | 0 | 213 | * | ... | 0 | 214 | * | conf->vf_dl_queues_number[0] - 1 | 0 | 215 | * | conf->vf_dl_queues_number[0] | 1 | 216 | * | ... | 1 | 217 | * | conf->vf_dl_queues_number[1] - 1 | 1 | 218 | * | ... | ... | 219 | * | conf->vf_dl_queues_number[7] - 1 | 7 | 220 | * 221 | * DL queues: 222 | * | Q_ID | VF_ID | 223 | * | 32 | 0 | 224 | * | ... | 0 | 225 | * | conf->vf_ul_queues_number[0] - 1 | 0 | 226 | * | conf->vf_ul_queues_number[0] | 1 | 227 | * | ... | 1 | 228 | * | conf->vf_ul_queues_number[1] - 1 | 1 | 229 | * | ... | ... | 230 | * | conf->vf_ul_queues_number[7] - 1 | 7 | 231 | * 232 | * Example of configuration: 233 | * conf->vf_ul_queues_number[0] = 4; -> 4 UL queues for VF0 234 | * conf->vf_dl_queues_number[0] = 4; -> 4 DL queues for VF0 235 | * conf->vf_ul_queues_number[1] = 2; -> 2 UL queues for VF1 236 | * conf->vf_dl_queues_number[1] = 2; -> 2 DL queues for VF1 237 | * 238 | * UL: 239 | * | Q_ID | VF_ID | 240 | * | 0 | 0 | 241 | * | 1 | 0 | 242 | * | 2 | 0 | 243 | * | 3 | 0 | 244 | * | 4 | 1 | 245 | * | 5 | 1 | 246 | * 247 | * DL: 248 | * | Q_ID | VF_ID | 249 | * | 32 | 0 | 250 | * | 33 | 0 | 251 | * | 34 | 0 | 252 | * | 35 | 0 | 253 | * | 36 | 1 | 254 | * | 37 | 1 | 255 | */ 256 | if (conf->pf_mode_en) { 257 | payload_32 = 0x1; 258 | for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) { 259 | address = (q_id << 2) + FPGA_5GNR_FEC_QUEUE_MAP; 260 | fpga_reg_write_32(bar0addr, address, payload_32); 261 | } 262 | } else { 263 | /* Calculate total number of UL and DL queues to configure */ 264 | total_ul_q_id = total_dl_q_id = 0; 265 | for (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) { 266 | total_ul_q_id += conf->vf_ul_queues_number[vf_id]; 267 | total_dl_q_id += conf->vf_dl_queues_number[vf_id]; 268 | } 269 | total_q_id = total_dl_q_id + total_ul_q_id; 270 | /* 271 | * Check if total number of queues to configure does not exceed 272 | * FPGA capabilities (64 queues - 32 UL and 32 DL queues) 273 | */ 274 | if ((total_ul_q_id > FPGA_NUM_UL_QUEUES) || 275 | (total_dl_q_id > FPGA_NUM_DL_QUEUES) || 276 | (total_q_id > FPGA_TOTAL_NUM_QUEUES)) { 277 | printf( 278 | "FPGA Configuration failed. Too many queues to configure: UL_Q %u, DL_Q %u, FPGA_Q %u", 279 | total_ul_q_id, total_dl_q_id, 280 | FPGA_TOTAL_NUM_QUEUES); 281 | return -EINVAL; 282 | } 283 | total_ul_q_id = 0; 284 | for (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) { 285 | for (q_id = 0; q_id < conf->vf_ul_queues_number[vf_id]; 286 | ++q_id, ++total_ul_q_id) { 287 | address = (total_ul_q_id << 2) + 288 | FPGA_5GNR_FEC_QUEUE_MAP; 289 | payload_32 = ((0x80 + vf_id) << 16) | 0x1; 290 | fpga_reg_write_32(bar0addr, address, 291 | payload_32); 292 | } 293 | } 294 | total_dl_q_id = 0; 295 | for (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) { 296 | for (q_id = 0; q_id < conf->vf_dl_queues_number[vf_id]; 297 | ++q_id, ++total_dl_q_id) { 298 | address = ((total_dl_q_id + FPGA_NUM_UL_QUEUES) 299 | << 2) + FPGA_5GNR_FEC_QUEUE_MAP; 300 | payload_32 = ((0x80 + vf_id) << 16) | 0x1; 301 | fpga_reg_write_32(bar0addr, address, 302 | payload_32); 303 | } 304 | } 305 | } 306 | 307 | /* Setting Load Balance Factor */ 308 | payload_16 = (conf->dl_load_balance << 8) | (conf->ul_load_balance); 309 | address = FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR; 310 | fpga_reg_write_16(bar0addr, address, payload_16); 311 | 312 | /* Setting length of ring descriptor entry */ 313 | payload_16 = FPGA_RING_DESC_ENTRY_LENGTH; 314 | address = FPGA_5GNR_FEC_RING_DESC_LEN; 315 | fpga_reg_write_16(bar0addr, address, payload_16); 316 | 317 | /* Queue PF/VF mapping table is ready */ 318 | payload_16 = 0x1; 319 | address = FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE; 320 | fpga_reg_write_16(bar0addr, address, payload_16); 321 | 322 | print_static_reg_debug_info(bar0addr); 323 | printf("Mode of operation = %s-mode\n", 324 | conf->pf_mode_en ? "PF" : "VF"); 325 | 326 | return 0; 327 | } 328 | 329 | int 330 | fpga_5gnr_configure(void *dev, void *bar0addr, const char *cfg_filename, const bool first_cfg) 331 | { 332 | struct fpga_5gnr_fec_conf fpga_conf; 333 | int ret; 334 | 335 | ret = fpga_read_config_file(cfg_filename, &fpga_conf); 336 | if (ret != 0) { 337 | printf("Error reading config file.\n"); 338 | return -1; 339 | } 340 | 341 | ret = fpga_write_config(dev, bar0addr, &fpga_conf); 342 | if (ret != 0) { 343 | printf("Error writing configuration for FPGA.\n"); 344 | return -1; 345 | } 346 | 347 | return 0; 348 | } 349 | -------------------------------------------------------------------------------- /fpga_5gnr/fpga_5gnr_cfg_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _FPGA_5GNR_CFG_APP_H_ 20 | #define _FPGA_5GNR_CFG_APP_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* Multiplier of 256 bits (32 bytes) */ 31 | #define FPGA_RING_DESC_ENTRY_LENGTH (8) 32 | #define FPGA_RING_DESC_LEN_UNIT_BYTES (32) 33 | /* Maximum size of queue */ 34 | #define FPGA_RING_MAX_SIZE (1024) 35 | 36 | #define FPGA_NUM_UL_QUEUES (32) 37 | #define FPGA_NUM_DL_QUEUES (32) 38 | #define FPGA_TOTAL_NUM_QUEUES (FPGA_NUM_UL_QUEUES + FPGA_NUM_DL_QUEUES) 39 | 40 | #define FPGA_INVALID_HW_QUEUE_ID (0xFFFFFFFF) 41 | 42 | /* FPGA 5GNR FEC Register mapping on BAR0 */ 43 | enum { 44 | FPGA_5GNR_FEC_VERSION_ID = 0x00000000, /* len: 4B */ 45 | FPGA_5GNR_FEC_CONFIGURATION = 0x00000004, /* len: 2B */ 46 | FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE = 0x00000008, /* len: 1B */ 47 | FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR = 0x0000000a, /* len: 2B */ 48 | FPGA_5GNR_FEC_RING_DESC_LEN = 0x0000000c, /* len: 2B */ 49 | FPGA_5GNR_FEC_VFQ_FLUSH_STATUS_LW = 0x00000018, /* len: 4B */ 50 | FPGA_5GNR_FEC_VFQ_FLUSH_STATUS_HI = 0x0000001c, /* len: 4B */ 51 | FPGA_5GNR_FEC_QUEUE_MAP = 0x00000040, /* len: 256B */ 52 | FPGA_5GNR_FEC_RING_CTRL_REGS = 0x00000200, /* len: 2048B */ 53 | FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS = 0x00000A00, /* len: 4B */ 54 | FPGA_5GNR_FEC_DDR4_WR_DATA_REGS = 0x00000A08, /* len: 8B */ 55 | FPGA_5GNR_FEC_DDR4_WR_DONE_REGS = 0x00000A10, /* len: 1B */ 56 | FPGA_5GNR_FEC_DDR4_RD_ADDR_REGS = 0x00000A18, /* len: 4B */ 57 | FPGA_5GNR_FEC_DDR4_RD_DONE_REGS = 0x00000A20, /* len: 1B */ 58 | FPGA_5GNR_FEC_DDR4_RD_RDY_REGS = 0x00000A28, /* len: 1B */ 59 | FPGA_5GNR_FEC_DDR4_RD_DATA_REGS = 0x00000A30, /* len: 8B */ 60 | FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS = 0x00000A38, /* len: 1B */ 61 | FPGA_5GNR_FEC_HARQ_BUF_SIZE_RDY_REGS = 0x00000A40, /* len: 1B */ 62 | FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48, /* len: 4B */ 63 | FPGA_5GNR_FEC_MUTEX = 0x00000A60, /* len: 4B */ 64 | FPGA_5GNR_FEC_MUTEX_RESET = 0x00000A68 /* len: 4B */ 65 | }; 66 | 67 | /* FPGA 5GNR FEC Ring Control Registers */ 68 | enum { 69 | FPGA_5GNR_FEC_RING_HEAD_ADDR = 0x00000008, 70 | FPGA_5GNR_FEC_RING_SIZE = 0x00000010, 71 | FPGA_5GNR_FEC_RING_MISC = 0x00000014, 72 | FPGA_5GNR_FEC_RING_ENABLE = 0x00000015, 73 | FPGA_5GNR_FEC_RING_FLUSH_QUEUE_EN = 0x00000016, 74 | FPGA_5GNR_FEC_RING_SHADOW_TAIL = 0x00000018, 75 | FPGA_5GNR_FEC_RING_HEAD_POINT = 0x0000001C 76 | }; 77 | 78 | /**< Number of Virtual Functions FGPA 5GNR FEC supports */ 79 | #define FPGA_5GNR_FEC_NUM_VFS 8 80 | 81 | struct 82 | fpga_5gnr_fec_conf { 83 | /**< 1 if PF is used for dataplane, 0 for VFs */ 84 | bool pf_mode_en; 85 | /**< Number of UL queues per VF */ 86 | uint8_t vf_ul_queues_number[FPGA_5GNR_FEC_NUM_VFS]; 87 | /**< Number of DL queues per VF */ 88 | uint8_t vf_dl_queues_number[FPGA_5GNR_FEC_NUM_VFS]; 89 | /**< UL bandwidth. Needed for schedule algorithm */ 90 | uint8_t ul_bandwidth; 91 | /**< DL bandwidth. Needed for schedule algorithm */ 92 | uint8_t dl_bandwidth; 93 | /**< UL Load Balance */ 94 | uint8_t ul_load_balance; 95 | /**< DL Load Balance */ 96 | uint8_t dl_load_balance; 97 | }; 98 | 99 | #endif /* _FPGA_5GNR_CFG_APP_H_ */ 100 | -------------------------------------------------------------------------------- /fpga_5gnr/fpga_5gnr_cfg_parser.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "cfg_reader.h" 27 | #include "fpga_5gnr_cfg_app.h" 28 | 29 | /* Names of sections used in the configuration file */ 30 | #define MODE "MODE" 31 | #define UL "UL" 32 | #define DL "DL" 33 | 34 | /* Names of entries in sections used in the configuration file */ 35 | #define PFMODE "pf_mode_en" 36 | #define BANDWIDTH "bandwidth" 37 | #define LOAD_BALANCE "load_balance" 38 | #define QUEUE_MAP "vfqmap" 39 | 40 | /* Default values for FPGA device configuration variables */ 41 | #define DEFAULT_PF_MODE_EN 1 42 | #define DEFAULT_UL_BANDWIDTH 3 43 | #define DEFAULT_DL_BANDWIDTH 3 44 | #define DEFAULT_UL_LOAD_BALANCE 64 45 | #define DEFAULT_DL_LOAD_BALANCE 64 46 | #define DEFAULT_NUM_VF_QUEUE 8 47 | 48 | /* Possible values for MODE and LLR_SIGN */ 49 | #define ZERO "0" 50 | #define ONE "1" 51 | 52 | static int 53 | parse_number8(const char *str, uint8_t *value) 54 | { 55 | uint64_t val = 0; 56 | char *end; 57 | 58 | if (str == NULL) 59 | return -EINVAL; 60 | 61 | val = strtoul(str, &end, 0); 62 | if (val > UINT8_MAX || str == end) { 63 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 64 | return -ERANGE; 65 | } 66 | 67 | *value = (uint8_t) val; 68 | return 1; 69 | } 70 | 71 | static int 72 | parse_array8(const char *str, uint8_t *array) 73 | { 74 | int i; 75 | uint64_t val = 0; 76 | char *end; 77 | 78 | if (str == NULL) 79 | return -EINVAL; 80 | 81 | char *val_ch = strtok((char *)str, ","); 82 | for (i = 0; i < 8 && NULL != val_ch; i++) { 83 | 84 | val = strtoul(val_ch, &end, 0); 85 | if (val > UINT8_MAX || val_ch == end) { 86 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 87 | return -ERANGE; 88 | } 89 | array[i] = (uint8_t) val; 90 | 91 | val_ch = strtok(NULL, ","); 92 | } 93 | return 1; 94 | } 95 | 96 | static void 97 | set_default_config(struct fpga_5gnr_fec_conf *fpga_conf) 98 | { 99 | int i; 100 | 101 | /* Set pf mode to true */ 102 | fpga_conf->pf_mode_en = DEFAULT_PF_MODE_EN; 103 | 104 | /* Set ratio between UL and DL to 1:1 (unit of weight is 3 CBs) */ 105 | fpga_conf->ul_bandwidth = DEFAULT_UL_BANDWIDTH; 106 | fpga_conf->dl_bandwidth = DEFAULT_DL_BANDWIDTH; 107 | 108 | /* Set Load Balance Factor to 64 */ 109 | fpga_conf->ul_load_balance = DEFAULT_UL_LOAD_BALANCE; 110 | fpga_conf->dl_load_balance = DEFAULT_DL_LOAD_BALANCE; 111 | 112 | for (i = 0; i < FPGA_5GNR_FEC_NUM_VFS; i++) { 113 | fpga_conf->vf_ul_queues_number[i] = DEFAULT_NUM_VF_QUEUE / 2; 114 | fpga_conf->vf_dl_queues_number[i] = DEFAULT_NUM_VF_QUEUE / 2; 115 | } 116 | } 117 | 118 | static int 119 | fpga_handler(void *user, const char *section, 120 | const char *name, const char *value) 121 | { 122 | struct fpga_5gnr_fec_conf *fpga_conf = 123 | (struct fpga_5gnr_fec_conf *) user; 124 | int ret = 1; 125 | 126 | if (!strcmp(section, MODE) && !strcmp(name, PFMODE)) { 127 | if (!strcmp(value, ZERO)) 128 | fpga_conf->pf_mode_en = false; 129 | else if (!strcmp(value, ONE)) 130 | fpga_conf->pf_mode_en = true; 131 | else 132 | ret = 0; 133 | } else if (!strcmp(section, UL) && !strcmp(name, BANDWIDTH)) { 134 | ret = parse_number8(value, &fpga_conf->ul_bandwidth); 135 | } else if (!strcmp(section, DL) && !strcmp(name, BANDWIDTH)) { 136 | ret = parse_number8(value, &fpga_conf->dl_bandwidth); 137 | } else if (!strcmp(section, UL) && !strcmp(name, LOAD_BALANCE)) { 138 | ret = parse_number8(value, &fpga_conf->ul_load_balance); 139 | } else if (!strcmp(section, DL) && !strcmp(name, LOAD_BALANCE)) { 140 | ret = parse_number8(value, &fpga_conf->dl_load_balance); 141 | } else if (!strcmp(section, UL) && !strcmp(name, QUEUE_MAP)) { 142 | ret = parse_array8(value, fpga_conf->vf_ul_queues_number); 143 | } else if (!strcmp(section, DL) && !strcmp(name, QUEUE_MAP)) { 144 | ret = parse_array8(value, fpga_conf->vf_dl_queues_number); 145 | } else { 146 | printf("ERROR: Section (%s) or name (%s) is not valid.\n", 147 | section, name); 148 | return 0; 149 | } 150 | if (ret != 1) 151 | printf("Error: Conversion of value (%s) failed.\n", value); 152 | 153 | return ret; 154 | } 155 | 156 | int 157 | fpga_5gnr_parse_conf_file(const char *file_name, 158 | struct fpga_5gnr_fec_conf *fpga_conf) 159 | { 160 | int ret; 161 | 162 | set_default_config(fpga_conf); 163 | 164 | ret = cfg_parse(file_name, fpga_handler, fpga_conf); 165 | 166 | if (ret == -1) { 167 | printf("ERROR: Error loading configuration file %s\n", 168 | file_name); 169 | set_default_config(fpga_conf); 170 | return -ENOENT; 171 | } else if (ret == -2) { 172 | printf("ERROR: Memory allocation error\n"); 173 | set_default_config(fpga_conf); 174 | return -ENOMEM; 175 | } 176 | 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /fpga_5gnr/fpga_5gnr_config.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [UL] 8 | bandwidth = 3 9 | load_balance = 128 10 | vfqmap = 4,4,4,4,4,4,4,4 11 | 12 | [DL] 13 | bandwidth = 3 14 | load_balance = 128 15 | vfqmap = 4,4,4,4,4,4,4,4 16 | -------------------------------------------------------------------------------- /fpga_5gnr/fpga_5gnr_config_1vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2021 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | bandwidth = 3 9 | load_balance = 128 10 | vfqmap = 32,0,0,0,0,0,0,0 11 | 12 | [DL] 13 | bandwidth = 3 14 | load_balance = 128 15 | vfqmap = 32,0,0,0,0,0,0,0 16 | -------------------------------------------------------------------------------- /fpga_5gnr/fpga_5gnr_config_vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | bandwidth = 3 9 | load_balance = 128 10 | vfqmap = 16,16,0,0,0,0,0,0 11 | 12 | [DL] 13 | bandwidth = 3 14 | load_balance = 128 15 | vfqmap = 16,16,0,0,0,0,0,0 16 | -------------------------------------------------------------------------------- /fpga_lte/fpga_lte_cfg_app.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "fpga_lte_cfg_app.h" 28 | #include "cfg_reader.h" 29 | 30 | /* Multiplier of 256 bits (32 bytes) */ 31 | #define FPGA_RING_DESC_ENTRY_LENGTH (8) 32 | #define FPGA_RING_DESC_LEN_UNIT_BYTES (32) 33 | /* Maximum size of queue */ 34 | #define FPGA_RING_MAX_SIZE (1024) 35 | #define FPGA_FLR_TIMEOUT_UNIT (16.384) 36 | 37 | #define FPGA_NUM_UL_QUEUES (32) 38 | #define FPGA_NUM_DL_QUEUES (32) 39 | #define FPGA_TOTAL_NUM_QUEUES (FPGA_NUM_UL_QUEUES + FPGA_NUM_DL_QUEUES) 40 | 41 | #define FPGA_INVALID_HW_QUEUE_ID (0xFFFFFFFF) 42 | 43 | /* FPGA LTE FEC Register mapping on BAR0 */ 44 | enum { 45 | FPGA_LTE_FEC_VERSION_ID = 0x00000000, /* len: 4B */ 46 | FPGA_LTE_FEC_CONFIGURATION = 0x00000004, /* len: 2B */ 47 | FPGA_LTE_FEC_QUEUE_PF_VF_MAP_DONE = 0x00000008, /* len: 1B */ 48 | FPGA_LTE_FEC_LOAD_BALANCE_FACTOR = 0x0000000a, /* len: 2B */ 49 | FPGA_LTE_FEC_RING_DESC_LEN = 0x0000000c, /* len: 2B */ 50 | FPGA_LTE_FEC_FLR_TIME_OUT = 0x0000000e, /* len: 2B */ 51 | FPGA_LTE_FEC_VFQ_FLUSH_STATUS_LW = 0x00000018, /* len: 4B */ 52 | FPGA_LTE_FEC_VFQ_FLUSH_STATUS_HI = 0x0000001c, /* len: 4B */ 53 | FPGA_LTE_FEC_VF0_DEBUG = 0x00000020, /* len: 4B */ 54 | FPGA_LTE_FEC_VF1_DEBUG = 0x00000024, /* len: 4B */ 55 | FPGA_LTE_FEC_VF2_DEBUG = 0x00000028, /* len: 4B */ 56 | FPGA_LTE_FEC_VF3_DEBUG = 0x0000002c, /* len: 4B */ 57 | FPGA_LTE_FEC_VF4_DEBUG = 0x00000030, /* len: 4B */ 58 | FPGA_LTE_FEC_VF5_DEBUG = 0x00000034, /* len: 4B */ 59 | FPGA_LTE_FEC_VF6_DEBUG = 0x00000038, /* len: 4B */ 60 | FPGA_LTE_FEC_VF7_DEBUG = 0x0000003c, /* len: 4B */ 61 | FPGA_LTE_FEC_QUEUE_MAP = 0x00000040, /* len: 256B */ 62 | FPGA_LTE_FEC_RING_CTRL_REGS = 0x00000200 /* len: 2048B */ 63 | }; 64 | 65 | /* FPGA LTE FEC Ring Control Registers */ 66 | enum { 67 | FPGA_LTE_FEC_RING_HEAD_ADDR = 0x00000008, 68 | FPGA_LTE_FEC_RING_SIZE = 0x00000010, 69 | FPGA_LTE_FEC_RING_MISC = 0x00000014, 70 | FPGA_LTE_FEC_RING_ENABLE = 0x00000015, 71 | FPGA_LTE_FEC_RING_FLUSH_QUEUE_EN = 0x00000016, 72 | FPGA_LTE_FEC_RING_SHADOW_TAIL = 0x00000018, 73 | FPGA_LTE_FEC_RING_HEAD_POINT = 0x0000001C 74 | }; 75 | 76 | extern int 77 | fpga_lte_parse_conf_file(const char *file_name, 78 | struct fpga_lte_fec_conf *fpga_conf); 79 | 80 | /* Read 8-bit register of FPGA LTE FEC device */ 81 | static uint8_t 82 | fpga_reg_read_8(void *mmio_base, uint32_t offset) 83 | { 84 | void *reg_addr = mmio_base + offset; 85 | return *((volatile uint8_t *)(reg_addr)); 86 | } 87 | 88 | /* Read 16-bit register of FPGA LTE FEC device */ 89 | static uint16_t 90 | fpga_reg_read_16(void *mmio_base, uint32_t offset) 91 | { 92 | void *reg_addr = mmio_base + offset; 93 | uint16_t ret = *((volatile uint16_t *)(reg_addr)); 94 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 95 | return __bswap_16(ret); 96 | #else 97 | return ret; 98 | #endif 99 | } 100 | 101 | /* Read 32-bit register of FPGA LTE FEC device */ 102 | static uint32_t 103 | fpga_reg_read_32(void *mmio_base, uint32_t offset) 104 | { 105 | void *reg_addr = mmio_base + offset; 106 | uint32_t ret = *((volatile uint32_t *)(reg_addr)); 107 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 108 | return __bswap_32(ret); 109 | #else 110 | return ret; 111 | #endif 112 | } 113 | 114 | static inline void 115 | fpga_reg_write_16(void *mmio_base, uint32_t offset, 116 | uint16_t payload) { 117 | void *reg_addr = mmio_base + offset; 118 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 119 | payload = __bswap_16(payload); 120 | #endif 121 | *((volatile uint16_t *) (reg_addr)) = payload; 122 | } 123 | 124 | static inline void 125 | fpga_reg_write_32(void *mmio_base, uint32_t offset, 126 | uint32_t payload) 127 | { 128 | void *reg_addr = mmio_base + offset; 129 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 130 | payload = __bswap_32(payload); 131 | #endif 132 | *((volatile uint32_t *) (reg_addr)) = payload; 133 | } 134 | 135 | static inline void 136 | set_default_fpga_conf(struct fpga_lte_fec_conf *def_conf) 137 | { 138 | /* Set pf mode to true */ 139 | def_conf->pf_mode_en = true; 140 | 141 | /* Set ratio between UL and DL to 1:1 (unit of weight is 3 CBs) */ 142 | def_conf->ul_bandwidth = 3; 143 | def_conf->dl_bandwidth = 3; 144 | 145 | /* Set Load Balance Factor to 64 */ 146 | def_conf->dl_load_balance = 64; 147 | def_conf->ul_load_balance = 64; 148 | } 149 | 150 | static int 151 | fpga_read_config_file(const char *arg_cfg_filename, 152 | struct fpga_lte_fec_conf *fpga_lte_fec_conf) 153 | { 154 | bool unsafe_path = cfg_file_check_path_safety(arg_cfg_filename); 155 | if (unsafe_path == true) { 156 | printf("error, config file path \"%s\" is not safe", 157 | arg_cfg_filename); 158 | return -1; 159 | } else 160 | return fpga_lte_parse_conf_file(arg_cfg_filename, 161 | fpga_lte_fec_conf); 162 | } 163 | 164 | /* Read Static Register of FPGA LTE FEC device */ 165 | static inline void 166 | print_static_reg_debug_info(void *mmio_base) 167 | { 168 | uint8_t i, q_id; 169 | uint32_t fid; 170 | uint32_t version_id = fpga_reg_read_32(mmio_base, 171 | FPGA_LTE_FEC_VERSION_ID); 172 | uint16_t config = fpga_reg_read_16(mmio_base, 173 | FPGA_LTE_FEC_CONFIGURATION); 174 | uint8_t qmap_done = fpga_reg_read_8(mmio_base, 175 | FPGA_LTE_FEC_QUEUE_PF_VF_MAP_DONE); 176 | uint16_t lb_factor = fpga_reg_read_16(mmio_base, 177 | FPGA_LTE_FEC_LOAD_BALANCE_FACTOR); 178 | uint16_t ring_desc_len = fpga_reg_read_16(mmio_base, 179 | FPGA_LTE_FEC_RING_DESC_LEN); 180 | uint16_t flr_time_out = fpga_reg_read_16(mmio_base, 181 | FPGA_LTE_FEC_FLR_TIME_OUT); 182 | 183 | printf("FEC FPGA RTL v%u.%u\n", 184 | ((uint16_t)(version_id >> 16)), ((uint16_t)version_id)); 185 | printf("UL.DL Weights = %u.%u\n", 186 | ((uint8_t)config), ((uint8_t)(config >> 8))); 187 | printf("UL.DL Load Balance = %u.%u\n", 188 | ((uint8_t)lb_factor), ((uint8_t)(lb_factor >> 8))); 189 | printf("Queue-PF/VF Mapping Table = %s\n", 190 | (qmap_done > 0) ? "READY" : "NOT-READY"); 191 | printf("Ring Descriptor Size = %u bytes\n", 192 | ring_desc_len*FPGA_RING_DESC_LEN_UNIT_BYTES); 193 | printf("FLR Timeout = %f usec\n", 194 | (float)flr_time_out*FPGA_FLR_TIMEOUT_UNIT); 195 | 196 | printf("\n--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n"); 197 | printf(" | PF | VF0 | VF1 | VF2 | VF3 | VF4 | VF5 | VF6 | VF7 |\n"); 198 | printf("--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n"); 199 | 200 | for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; q_id++) { 201 | 202 | printf("%s-Q'%02u |", 203 | (q_id < FPGA_NUM_UL_QUEUES) ? "UL" : "DL", q_id); 204 | 205 | fid = fpga_reg_read_32(mmio_base, 206 | FPGA_LTE_FEC_QUEUE_MAP + (q_id << 2)); 207 | 208 | for (i = 0; i < 9; ++i) { 209 | 210 | if (!((fid >> 16) & (0x80)) && i == 0) { 211 | printf(" X |"); 212 | continue; 213 | } 214 | 215 | if (((((fid >> 16) & (0x7f)) + 1) == i) && 216 | ((fid >> 16) & (0x80))) 217 | printf(" X |"); 218 | else 219 | printf(" |"); 220 | } 221 | printf("\n"); 222 | } 223 | printf("--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n\n"); 224 | } 225 | 226 | static int 227 | fpga_write_config(void *dev, void *mapaddr, struct fpga_lte_fec_conf *conf) 228 | { 229 | 230 | uint32_t payload_32, address; 231 | uint16_t payload_16; 232 | uint16_t q_id, vf_id, total_q_id, total_ul_q_id, total_dl_q_id; 233 | 234 | uint32_t *bar0addr = mapaddr; 235 | 236 | /* 237 | * Configure UL:DL ratio. 238 | * [7:0]: UL weight 239 | * [15:8]: DL weight 240 | */ 241 | payload_16 = (conf->dl_bandwidth << 8) | conf->ul_bandwidth; 242 | address = FPGA_LTE_FEC_CONFIGURATION; 243 | fpga_reg_write_16(bar0addr, address, payload_16); 244 | 245 | /* Clear all queues registers */ 246 | payload_32 = FPGA_INVALID_HW_QUEUE_ID; 247 | for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) { 248 | address = (q_id << 2) + FPGA_LTE_FEC_QUEUE_MAP; 249 | fpga_reg_write_32(bar0addr, address, payload_32); 250 | } 251 | 252 | /* 253 | * If PF mode is enabled allocate all queues for PF only. 254 | * 255 | * For VF mode each VF can have different number of UL and DL queues. 256 | * Total number of queues to configure cannot exceed FPGA 257 | * capabilities - 64 queues - 32 queues for UL and 32 queues for DL. 258 | * Queues mapping is done according to configuration: 259 | * 260 | * UL queues: 261 | * | Q_ID | VF_ID | 262 | * | 0 | 0 | 263 | * | ... | 0 | 264 | * | conf->vf_dl_queues_number[0] - 1 | 0 | 265 | * | conf->vf_dl_queues_number[0] | 1 | 266 | * | ... | 1 | 267 | * | conf->vf_dl_queues_number[1] - 1 | 1 | 268 | * | ... | ... | 269 | * | conf->vf_dl_queues_number[7] - 1 | 7 | 270 | * 271 | * DL queues: 272 | * | Q_ID | VF_ID | 273 | * | 32 | 0 | 274 | * | ... | 0 | 275 | * | conf->vf_ul_queues_number[0] - 1 | 0 | 276 | * | conf->vf_ul_queues_number[0] | 1 | 277 | * | ... | 1 | 278 | * | conf->vf_ul_queues_number[1] - 1 | 1 | 279 | * | ... | ... | 280 | * | conf->vf_ul_queues_number[7] - 1 | 7 | 281 | * 282 | * Example of configuration: 283 | * conf->vf_ul_queues_number[0] = 4; -> 4 UL queues for VF0 284 | * conf->vf_dl_queues_number[0] = 4; -> 4 DL queues for VF0 285 | * conf->vf_ul_queues_number[1] = 2; -> 2 UL queues for VF1 286 | * conf->vf_dl_queues_number[1] = 2; -> 2 DL queues for VF1 287 | * 288 | * UL: 289 | * | Q_ID | VF_ID | 290 | * | 0 | 0 | 291 | * | 1 | 0 | 292 | * | 2 | 0 | 293 | * | 3 | 0 | 294 | * | 4 | 1 | 295 | * | 5 | 1 | 296 | * 297 | * DL: 298 | * | Q_ID | VF_ID | 299 | * | 32 | 0 | 300 | * | 33 | 0 | 301 | * | 34 | 0 | 302 | * | 35 | 0 | 303 | * | 36 | 1 | 304 | * | 37 | 1 | 305 | */ 306 | if (conf->pf_mode_en) { 307 | payload_32 = 0x1; 308 | for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) { 309 | address = (q_id << 2) + FPGA_LTE_FEC_QUEUE_MAP; 310 | fpga_reg_write_32(bar0addr, address, payload_32); 311 | } 312 | } else { 313 | /* Calculate total number of UL and DL queues to configure */ 314 | total_ul_q_id = total_dl_q_id = 0; 315 | for (vf_id = 0; vf_id < FPGA_LTE_FEC_NUM_VFS; ++vf_id) { 316 | total_ul_q_id += conf->vf_ul_queues_number[vf_id]; 317 | total_dl_q_id += conf->vf_dl_queues_number[vf_id]; 318 | } 319 | total_q_id = total_dl_q_id + total_ul_q_id; 320 | /* 321 | * Check if total number of queues to configure does not exceed 322 | * FPGA capabilities (64 queues - 32 UL and 32 DL queues) 323 | */ 324 | if ((total_ul_q_id > FPGA_NUM_UL_QUEUES) || 325 | (total_dl_q_id > FPGA_NUM_DL_QUEUES) || 326 | (total_q_id > FPGA_TOTAL_NUM_QUEUES)) { 327 | printf( 328 | "FPGA Configuration failed. Too many queues to configure: UL_Q %u, DL_Q %u, FPGA_Q %u", 329 | total_ul_q_id, total_dl_q_id, 330 | FPGA_TOTAL_NUM_QUEUES); 331 | return -EINVAL; 332 | } 333 | total_ul_q_id = 0; 334 | for (vf_id = 0; vf_id < FPGA_LTE_FEC_NUM_VFS; ++vf_id) { 335 | for (q_id = 0; q_id < conf->vf_ul_queues_number[vf_id]; 336 | ++q_id, ++total_ul_q_id) { 337 | address = (total_ul_q_id << 2) + 338 | FPGA_LTE_FEC_QUEUE_MAP; 339 | payload_32 = ((0x80 + vf_id) << 16) | 0x1; 340 | fpga_reg_write_32(bar0addr, address, 341 | payload_32); 342 | } 343 | } 344 | total_dl_q_id = 0; 345 | for (vf_id = 0; vf_id < FPGA_LTE_FEC_NUM_VFS; ++vf_id) { 346 | for (q_id = 0; q_id < conf->vf_dl_queues_number[vf_id]; 347 | ++q_id, ++total_dl_q_id) { 348 | address = ((total_dl_q_id + FPGA_NUM_UL_QUEUES) 349 | << 2) + FPGA_LTE_FEC_QUEUE_MAP; 350 | payload_32 = ((0x80 + vf_id) << 16) | 0x1; 351 | fpga_reg_write_32(bar0addr, address, 352 | payload_32); 353 | } 354 | } 355 | } 356 | 357 | /* Setting Load Balance Factor */ 358 | payload_16 = (conf->dl_load_balance << 8) | (conf->ul_load_balance); 359 | address = FPGA_LTE_FEC_LOAD_BALANCE_FACTOR; 360 | fpga_reg_write_16(bar0addr, address, payload_16); 361 | 362 | /* Setting length of ring descriptor entry */ 363 | payload_16 = FPGA_RING_DESC_ENTRY_LENGTH; 364 | address = FPGA_LTE_FEC_RING_DESC_LEN; 365 | fpga_reg_write_16(bar0addr, address, payload_16); 366 | 367 | /* Setting FLR timeout value */ 368 | payload_16 = conf->flr_time_out; 369 | address = FPGA_LTE_FEC_FLR_TIME_OUT; 370 | fpga_reg_write_16(bar0addr, address, payload_16); 371 | 372 | /* Queue PF/VF mapping table is ready */ 373 | payload_16 = 0x1; 374 | address = FPGA_LTE_FEC_QUEUE_PF_VF_MAP_DONE; 375 | fpga_reg_write_16(bar0addr, address, payload_16); 376 | 377 | print_static_reg_debug_info(bar0addr); 378 | printf("Mode of operation = %s-mode\n", 379 | conf->pf_mode_en ? "PF" : "VF"); 380 | 381 | return 0; 382 | } 383 | 384 | int 385 | fpga_lte_configure(void *dev, void *bar0addr, const char *cfg_filename, const bool first_cfg) 386 | { 387 | struct fpga_lte_fec_conf fpga_conf; 388 | int ret; 389 | 390 | ret = fpga_read_config_file(cfg_filename, &fpga_conf); 391 | if (ret != 0) { 392 | printf("Error reading config file.\n"); 393 | return -1; 394 | } 395 | 396 | ret = fpga_write_config(dev, bar0addr, &fpga_conf); 397 | if (ret != 0) { 398 | printf("Error writing configuration for FPGA.\n"); 399 | return -1; 400 | } 401 | 402 | return 0; 403 | } 404 | -------------------------------------------------------------------------------- /fpga_lte/fpga_lte_cfg_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _FPGA_LTE_CFG_APP_H_ 20 | #define _FPGA_LTE_CFG_APP_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /**< Number of Virtual Functions FGPA LTE FEC supports */ 31 | #define FPGA_LTE_FEC_NUM_VFS 8 32 | 33 | struct 34 | fpga_lte_fec_conf { 35 | /**< 1 if PF is used for dataplane, 0 for VFs */ 36 | bool pf_mode_en; 37 | /**< Number of UL queues per VF */ 38 | uint8_t vf_ul_queues_number[FPGA_LTE_FEC_NUM_VFS]; 39 | /**< Number of DL queues per VF */ 40 | uint8_t vf_dl_queues_number[FPGA_LTE_FEC_NUM_VFS]; 41 | /**< UL bandwidth. Needed for schedule algorithm */ 42 | uint8_t ul_bandwidth; 43 | /**< DL bandwidth. Needed for schedule algorithm */ 44 | uint8_t dl_bandwidth; 45 | /**< UL Load Balance */ 46 | uint8_t ul_load_balance; 47 | /**< DL Load Balance */ 48 | uint8_t dl_load_balance; 49 | /**< FLR timeout value */ 50 | uint16_t flr_time_out; 51 | }; 52 | 53 | #endif /* _FPGA_CFG_APP_H_ */ 54 | -------------------------------------------------------------------------------- /fpga_lte/fpga_lte_cfg_parser.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2020 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "cfg_reader.h" 27 | #include "fpga_lte_cfg_app.h" 28 | 29 | /* Names of sections used in the configuration file */ 30 | #define MODE "MODE" 31 | #define UL "UL" 32 | #define DL "DL" 33 | #define FLR "FLR" 34 | 35 | /* Names of entries in sections used in the configuration file */ 36 | #define PFMODE "pf_mode_en" 37 | #define BANDWIDTH "bandwidth" 38 | #define LOAD_BALANCE "load_balance" 39 | #define QUEUE_MAP "vfqmap" 40 | #define FLR_TIME_OUT "flr_time_out" 41 | 42 | /* Default values for FPGA device configuration variables */ 43 | #define DEFAULT_PF_MODE_EN 1 44 | #define DEFAULT_UL_BANDWIDTH 3 45 | #define DEFAULT_DL_BANDWIDTH 3 46 | #define DEFAULT_UL_LOAD_BALANCE 64 47 | #define DEFAULT_DL_LOAD_BALANCE 64 48 | #define DEFAULT_NUM_VF_QUEUE 8 49 | 50 | /* Possible values for MODE and LLR_SIGN */ 51 | #define ZERO "0" 52 | #define ONE "1" 53 | 54 | static int 55 | parse_number8(const char *str, uint8_t *value) 56 | { 57 | uint64_t val = 0; 58 | char *end; 59 | 60 | if (str == NULL) 61 | return -EINVAL; 62 | 63 | val = strtoul(str, &end, 0); 64 | if (val > UINT8_MAX || str == end) { 65 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 66 | return -ERANGE; 67 | } 68 | 69 | *value = (uint8_t) val; 70 | return 1; 71 | } 72 | 73 | static int 74 | parse_number16(const char *str, uint16_t *value) 75 | { 76 | uint64_t val = 0; 77 | char *end; 78 | 79 | if (str == NULL) 80 | return -EINVAL; 81 | 82 | val = strtoul(str, &end, 0); 83 | if (val > UINT16_MAX || str == end) { 84 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 85 | return -ERANGE; 86 | } 87 | 88 | *value = (uint16_t) val; 89 | return 1; 90 | } 91 | 92 | static int 93 | parse_array8(const char *str, uint8_t *array) 94 | { 95 | int i; 96 | uint64_t val = 0; 97 | char *end; 98 | 99 | if (str == NULL) 100 | return -EINVAL; 101 | 102 | char *val_ch = strtok((char *)str, ","); 103 | for (i = 0; i < 8 && NULL != val_ch; i++) { 104 | 105 | val = strtoul(val_ch, &end, 0); 106 | if (val > UINT8_MAX || val_ch == end) { 107 | printf("ERROR: Invalid value %" PRIu64 "\n", val); 108 | return -ERANGE; 109 | } 110 | array[i] = (uint8_t) val; 111 | 112 | val_ch = strtok(NULL, ","); 113 | } 114 | return 1; 115 | } 116 | 117 | static void 118 | set_default_config(struct fpga_lte_fec_conf *fpga_conf) 119 | { 120 | int i; 121 | 122 | /* Set pf mode to true */ 123 | fpga_conf->pf_mode_en = DEFAULT_PF_MODE_EN; 124 | 125 | /* Set ratio between UL and DL to 1:1 (unit of weight is 3 CBs) */ 126 | fpga_conf->ul_bandwidth = DEFAULT_UL_BANDWIDTH; 127 | fpga_conf->dl_bandwidth = DEFAULT_DL_BANDWIDTH; 128 | 129 | /* Set Load Balance Factor to 64 */ 130 | fpga_conf->ul_load_balance = DEFAULT_UL_LOAD_BALANCE; 131 | fpga_conf->dl_load_balance = DEFAULT_DL_LOAD_BALANCE; 132 | 133 | for (i = 0; i < FPGA_LTE_FEC_NUM_VFS; i++) { 134 | fpga_conf->vf_ul_queues_number[i] = DEFAULT_NUM_VF_QUEUE/2; 135 | fpga_conf->vf_dl_queues_number[i] = DEFAULT_NUM_VF_QUEUE/2; 136 | } 137 | } 138 | 139 | static int 140 | fpga_handler(void *user, const char *section, 141 | const char *name, const char *value) 142 | { 143 | struct fpga_lte_fec_conf *fpga_conf = (struct fpga_lte_fec_conf *) user; 144 | int ret = 1; 145 | 146 | if (!strcmp(section, MODE) && !strcmp(name, PFMODE)) { 147 | if (!strcmp(value, ZERO)) 148 | fpga_conf->pf_mode_en = false; 149 | else if (!strcmp(value, ONE)) 150 | fpga_conf->pf_mode_en = true; 151 | else 152 | ret = 0; 153 | } else if (!strcmp(section, UL) && !strcmp(name, BANDWIDTH)) { 154 | ret = parse_number8(value, &fpga_conf->ul_bandwidth); 155 | } else if (!strcmp(section, DL) && !strcmp(name, BANDWIDTH)) { 156 | ret = parse_number8(value, &fpga_conf->dl_bandwidth); 157 | } else if (!strcmp(section, UL) && !strcmp(name, LOAD_BALANCE)) { 158 | ret = parse_number8(value, &fpga_conf->ul_load_balance); 159 | } else if (!strcmp(section, DL) && !strcmp(name, LOAD_BALANCE)) { 160 | ret = parse_number8(value, &fpga_conf->dl_load_balance); 161 | } else if (!strcmp(section, UL) && !strcmp(name, QUEUE_MAP)) { 162 | ret = parse_array8(value, fpga_conf->vf_ul_queues_number); 163 | } else if (!strcmp(section, DL) && !strcmp(name, QUEUE_MAP)) { 164 | ret = parse_array8(value, fpga_conf->vf_dl_queues_number); 165 | } else if (!strcmp(section, FLR) && !strcmp(name, FLR_TIME_OUT)) { 166 | ret = parse_number16(value, &fpga_conf->flr_time_out); 167 | } else { 168 | printf("ERROR: Section (%s) or name (%s) is not valid.\n", 169 | section, name); 170 | return 0; 171 | } 172 | if (ret != 1) 173 | printf("Error: Conversion of value (%s) failed.\n", value); 174 | 175 | return ret; 176 | } 177 | 178 | int 179 | fpga_lte_parse_conf_file(const char *file_name, 180 | struct fpga_lte_fec_conf *fpga_conf) 181 | { 182 | int ret; 183 | 184 | set_default_config(fpga_conf); 185 | 186 | ret = cfg_parse(file_name, fpga_handler, fpga_conf); 187 | 188 | if (ret == -1) { 189 | printf("ERROR: Error loading configuration file %s\n", 190 | file_name); 191 | set_default_config(fpga_conf); 192 | return -ENOENT; 193 | } else if (ret == -2) { 194 | printf("ERROR: Memory allocation error\n"); 195 | set_default_config(fpga_conf); 196 | return -ENOMEM; 197 | } 198 | 199 | return 0; 200 | } 201 | -------------------------------------------------------------------------------- /fpga_lte/fpga_lte_config.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [UL] 8 | bandwidth = 3 9 | load_balance = 128 10 | vfqmap = 16,16,0,0,0,0,0,0 11 | 12 | [DL] 13 | bandwidth = 3 14 | load_balance = 128 15 | vfqmap = 16,16,0,0,0,0,0,0 16 | 17 | [FLR] 18 | flr_time_out = 610 19 | -------------------------------------------------------------------------------- /fpga_lte/fpga_lte_config_vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [UL] 8 | bandwidth = 3 9 | load_balance = 128 10 | vfqmap = 16,16,0,0,0,0,0,0 11 | 12 | [DL] 13 | bandwidth = 3 14 | load_balance = 128 15 | vfqmap = 16,16,0,0,0,0,0,0 16 | 17 | [FLR] 18 | flr_time_out = 610 19 | -------------------------------------------------------------------------------- /pf_bb_config_cli.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef __PF_BB_CONFIG_CLI_H__ 20 | #define __PF_BB_CONFIG_CLI_H__ 21 | 22 | #define UNIX_CHANNEL_PATH "/tmp/pf_bb_config" 23 | #define UNIX_CHANNEL_FILE_LEN 64 24 | 25 | #define NO_WAIT_ON_RESP 0 26 | #define WAIT_ON_RESP 1 27 | 28 | /* 29 | * enum defining different commands supported 30 | * by pf_bb_config_cli. 31 | * HELP_CMD_ID -->To displays argument list, NULL if nor required. 32 | * RESET_MODE_CMD_ID -->To set reset mode of ACC devices (pf_flr / cluster_reset). 33 | * AUTO_RESET_CMD_ID -->To auto reset ACC devices (on / off). 34 | * CLEAR_LOG_CMD_ID -->To clear the previous content of logfile file. 35 | * EXIT_APP_CMD_ID -->To gracefully shutdown the application. 36 | * REG_DUMP_CMD_ID -->To dump all the register status of the ACC device (DEVICE_ID). 37 | * RECONFIG_ACC_CMD_ID -->To reconfigure the ACC device (DEVICE_ID). 38 | * MM_READ_CMD_ID -->To read/write to a register. 39 | * DEVICE_DATA_CMD_ID -->To dump telemetry data. 40 | */ 41 | 42 | enum { 43 | HELP_CMD_ID = 0x1, 44 | RESET_MODE_CMD_ID = 0x2, 45 | AUTO_RESET_CMD_ID = 0x3, 46 | CLEAR_LOG_CMD_ID = 0x4, 47 | EXIT_APP_CMD_ID = 0x5, 48 | REG_DUMP_CMD_ID = 0x6, 49 | RECONFIG_ACC_CMD_ID = 0x7, 50 | MM_READ_CMD_ID = 0x8, 51 | DEVICE_DATA_CMD_ID = 0x9 52 | }; 53 | 54 | #define CLI_CMD_MAX_LEN 64 55 | struct cmdDef { 56 | int id; 57 | char cmd[CLI_CMD_MAX_LEN]; 58 | void (*help)(void); 59 | int (*parse)(int argc, char *argv[], void *ci); 60 | int (*send)(struct cmdDef *, void *); 61 | int (*resp)(struct cmdDef *, void *); 62 | void (*print)(struct cmdDef *, void *); 63 | int (*exec)(struct cmdDef *, void *); 64 | char *short_help; 65 | }; 66 | 67 | #define NULL_HELP_FP NULL 68 | #define NULL_PARSE_FP NULL 69 | #define NULL_SEND_FP NULL 70 | #define NULL_RESP_FP NULL 71 | #define NULL_PRINT_FP NULL 72 | #define NULL_EXEC_FP NULL 73 | 74 | struct help_req { 75 | void (*cmd_help)(void); 76 | }; 77 | 78 | #define RESET_MODE_CLUSTER_LEVEL 0 79 | #define RESET_MODE_FLR 1 80 | struct reset_mode_req { 81 | unsigned int mode; 82 | } __attribute__((__packed__)); 83 | 84 | #define AUTO_RESET_OFF 0 85 | #define AUTO_RESET_ON 1 86 | struct auto_reset_req { 87 | unsigned int mode; 88 | } __attribute__((__packed__)); 89 | 90 | #define DEVICE_ID_ACC100 0x0D5C 91 | #define DEVICE_ID_VRB1 0x57C0 92 | #define DEVICE_ID_VRB2 0x57C2 93 | 94 | struct reg_dump_req { 95 | unsigned int device_id; 96 | } __attribute__((__packed__)); 97 | 98 | struct reg_dump_resp { 99 | int code; 100 | } __attribute__((__packed__)); 101 | 102 | #define MM_READ_REG_READ 0 103 | #define MM_READ_REG_WRITE 1 104 | struct mm_read_req { 105 | /* reg_op_flag describes read/write operation*/ 106 | unsigned int reg_op_flag; 107 | unsigned int reg_rw_address; 108 | unsigned int write_payload; 109 | } __attribute__((__packed__)); 110 | 111 | #define CMD_REQ(ci) (&(((struct cmdReq *)ci)->req)) 112 | struct cmdReq { 113 | short id; 114 | short len; 115 | void *priv; 116 | union { 117 | struct help_req help; 118 | struct reset_mode_req reset_mode_req; 119 | struct auto_reset_req auto_reset_req; 120 | struct reg_dump_req reg_dump_req; 121 | struct mm_read_req mm_read_req; 122 | } req; 123 | }; 124 | 125 | struct cmdResp { 126 | short id; 127 | short len; 128 | unsigned int resp_code; 129 | union { 130 | struct reg_dump_resp reg_dump_resp; 131 | } resp; 132 | }; 133 | 134 | #endif /* __PF_BB_CONFIG_CLI_H__ */ 135 | -------------------------------------------------------------------------------- /rel_notes.txt: -------------------------------------------------------------------------------- 1 | pf_bb_config Release Note 2 | ========================= 3 | 4 | 25.01 new features and fixes 5 | ---------------------------- 6 | * VRB2: Allow for extra time when updating Power Gating to avoid potential condition when 7 | status is not updated fast enough. 8 | * Minor documentation update. 9 | 10 | 24.11 new features and fixes 11 | ---------------------------- 12 | * VRB2: Support for the GNR-D B0 ES2 device. 13 | This version 24.11 or later is required to support VRB2. 14 | * VRB2: Update of the default FFT windowing for VRB2 with variety of window sizes. 15 | * Fix: Minor error handling fix in case number of devices being provided is invalid. 16 | * Fix: Minor explicit set turbo-decoder fallback settings to avoid unlikely negative scenario. 17 | 18 | 24.07 new features and fixes 19 | ---------------------------- 20 | * VRB2: Enforce maximum 256 total queues configured per operation type. 21 | * Prevent negative scenario with MMIO marginally outside of PF BAR. 22 | * Cosmetic change to remind user to use VRB1 instead of deprecated ACC200, and VF mode by default. 23 | * Cosmetic change to adjust log level when not required to be logged as INFO. 24 | * Cosmetic change to remove obsolete directory ./acc200/ since ./vrb1 should be used. 25 | 26 | 24.03 new features and fixes 27 | ---------------------------- 28 | * Update support for Intel vRAN Boost v2 on GNR-D (Early Access Alpha) including VRB2 fixes. 29 | * Refactor of the FFT window loading and documentation improvement of provided LUTs format. 30 | * ACC100: Add an error report in case of exception after partial soft reboot and reconfiguration. 31 | * Fix: Engines counters were not consistently exposed as part of Telemetry. 32 | * Fix: Support for N3000 LTE using vfio-pci. 33 | 34 | 23.11 new features and fixes 35 | ---------------------------- 36 | * Initial support for Intel vRAN Boost v2 on GNR-D (Early Access Pre-Alpha). 37 | * Expose the FFT windowing configuration towards bbdev-api PMD and respective window sizes. 38 | * Fix: Increase the default arbitration FIFO depth. 39 | * Fix: Response string missing for invalid address request. 40 | 41 | 23.07 new features and fixes 42 | ---------------------------- 43 | * Intel vRAN Boost v1 update to FFT windowing: 44 | * Update of the default FFT windowing bin file for VRB1. 45 | * Adding option to point to path of the FFT windowing bin file. 46 | * Support to expose the FFT window bin version number towards bbdev. 47 | * Log management update. The device telemetry is now captured in a distinct file from the main log. 48 | * Clean socket file in case still present after ungraceful exit. 49 | * Protection to avoid illegal MMIO access. 50 | * Fix to the -p option to allow a specific PCIe address to use. 51 | * Fix to exception from negative test and coverity warning. 52 | 53 | 23.03 new features and fixes 54 | ---------------------------- 55 | * Intel vRAN Boost v1 (SPR-EE PRQ) specific changes : 56 | * Code refactor for refreshed product branding: ACC200 -> VRB1. Backward compatible usage. 57 | * Protection for MMIO Read interface to bar access to specific register range. 58 | * Explicit reset of SRAM to avoid risk of parity error false alarm. 59 | * Set explictly dynamic clock gating after reconfiguration. 60 | * Improvement to FFT memory loading after reconfiguration. 61 | * Improvement to the speed for reconfiguration after reset. 62 | * Extension of telemetry related to DMA latency measurements. 63 | * Fix for minor coverity warnings. 64 | * Fix minor leak with opened sysfs directory. 65 | * Support for vfio-pci kernel module with N3000. 66 | * Support for flexible number of queues with N6000. 67 | 68 | 22.11 new features and fixes 69 | ---------------------------- 70 | * Improvement for ACC200 accelerator management (still prePRQ) 71 | including mitigations for known sightings as well as RAS improvements. 72 | * Removing the -a optional argument (all devices) which was not supported in practice. 73 | * Support for FPGA N6000 variant (AGX100) 74 | * Fix for handling negative scenario of mmap failure 75 | * Fix for big endian build 76 | * Fix for cli socket reliability 77 | 78 | 22.07 new features and fixes 79 | ---------------------------- 80 | * acc200: Support for ACC200 accelerator (SPR-EE Early Access) 81 | * pf_bb_config: Support for CLI interface and telemetry 82 | * pf_bb_config: Update to Makefile for stronger security check 83 | * acc100: update of the PCIe adaptation for improved PCIe BER performance 84 | * acc100: enabling queue at the end to prevent access while configuration is ongoing 85 | * pf_bb_config: refactor logging mechanism 86 | 87 | 22.03 new features and fixes 88 | ---------------------------- 89 | * pf_bb_config: Remove dependency on inih library for config file parsing 90 | * pf_bb_config: Support for binding PF to vfio-pci and related VF token 91 | * config files: Adjustment for PF which only needs a single VF bundle set 92 | * doc: Documentation update and clarifications 93 | 94 | 21.11 new features and Fixes 95 | ---------------------------- 96 | * acc100: range check for configuration file parsing 97 | * acc100: report ROM version of ACC100 device 98 | * acc100: clear persistent error registers 99 | * acc100: avoid interrupt to be enabled by default 100 | * acc100: adjust default DDR ROW address to be out of range 101 | * build: build script includes the version string 102 | * doc: clarification on Readme documentation and reset procedure 103 | 104 | 21.06 new features and Fixes 105 | ---------------------------- 106 | * acc100: adjust the default fabric mode 107 | * acc100: fixes Qmgr ARAM mapping based on number of VFs 108 | * acc100: new examples of config files 109 | 110 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | Please report any security vulnerabilities in this project [utilizing the guidelines here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 6 | -------------------------------------------------------------------------------- /vrb1/srs_fft_windows_coefficient.txt: -------------------------------------------------------------------------------- 1 | Description of provided FFT windows LUT: 2 | ======================================== 3 | 4 | The windowing LUT is made of 16 windows indexes for each of the supported FFT size (from 32 to 2048) in binary format using int16_t (fixed point). 5 | Note that the stored window lengths are equal to half the FFT size (non-stored entries are assumed to be zero) => hence 65024 B total size. 6 | In term of layout the content of these windows is concatenated back to back starting from the smaller FFT: 7 | - first, 16 windows of size 16 x int16_t for the FFT size 32 8 | - then 16 windows of size 32 x int16_t for the FFT size 64 9 | - etc… 10 | 11 | Said otherwise the pointer for the start of the window `Widx` and FFT of index `Fidx` of window size ‘Wsize(Fidx)’ can be computed as: 12 | int16_t *offset(Fidx, Widx) = 16 x Sum(Wsize(i), 0 , Fidx-1) + Widx x Wsize(Fidx) 13 | 14 | A few examples of LUT are included in this directory and are described below. 15 | The tabular format below provides for each window index the start position and the width of each window. 16 | For instance in srs_fft_windows_coefficient_vrb2.bin, for FFT 2048 and window index 1, the window starts at sample -256 and is 388 samples wide. 17 | 18 | d588afc68165192a7155489c39a7a21c srs_fft_windows_coefficient_wide.bin 19 | Recommended windows for VRB1: square window with mix of size and offset 20 | FFT Size 32: (0, -3, 7), (1, -3, 4), (2, -2, 4), (3, -1, 4), (4, 0, 4), (5, -3, 3), (6, -2, 3), (7, -1, 3), (8, 0, 3), (9, 1, 3), (10, -3, 2), (11, -2, 2), (12, -1, 2), (13, 0, 2), (14, 1, 2), (15, 2, 2) 21 | FFT Size 64: (0, -5, 13), (1, -5, 9), (2, -4, 9), (3, -3, 9), (4, -2, 9), (5, -1, 9), (6, -5, 4), (7, -4, 4), (8, -3, 4), (9, -2, 4), (10, -1, 4), (11, 0, 4), (12, 1, 4), (13, 2, 4), (14, 3, 4), (15, 4, 4) 22 | FFT Size 128: (0, -10, 26), (1, -10, 14), (2, -7, 14), (3, -4, 14), (4, -1, 14), (5, 2, 14), (6, -10, 8), (7, -8, 8), (8, -6, 8), (9, -4, 8), (10, -2, 8), (11, 0, 8), (12, 2, 8), (13, 4, 8), (14, 6, 8), (15, 8, 8) 23 | FFT Size 256: (0, -20, 52), (1, -20, 28), (2, -14, 28), (3, -8, 28), (4, -2, 28), (5, 4, 28), (6, -20, 16), (7, -16, 16), (8, -12, 16), (9, -8, 16), (10, -4, 16), (11, 0, 16), (12, 4, 16), (13, 8, 16), (14, 12, 16), (15, 16, 16) 24 | FFT Size 512: (0, -40, 104), (1, -40, 52), (2, -27, 52), (3, -14, 52), (4, -1, 52), (5, 12, 52), (6, -40, 32), (7, -32, 32), (8, -24, 32), (9, -16, 32), (10, -8, 32), (11, 0, 32), (12, 8, 32), (13, 16, 32), (14, 24, 32), (15, 32, 32) 25 | FFT Size 1024: (0, -40, 168), (1, -40, 88), (2, -24, 88), (3, -8, 88), (4, 8, 88), (5, 24, 88), (6, 40, 88), (7, -40, 45), (8, -30, 45), (9, -20, 45), (10, -10, 45), (11, 0, 45), (12, 10, 45), (13, 20, 45), (14, 30, 45), (15, 40, 45) 26 | FFT Size 2048: (0, -40, 296), (1, -40, 160), (2, -24, 160), (3, -8, 160), (4, 8, 160), (5, 24, 160), (6, 40, 160), (7, -40, 80), (8, -30, 80), (9, -20, 80), (10, -10, 80), (11, 0, 80), (12, 10, 80), (13, 20, 80), (14, 30, 80), (15, 40, 80) 27 | 28 | e74a5c8212d5e436be35d446bca16989 srs_fft_windows_coefficient_vrb2.bin 29 | Recommended windows VRB2: square windows with different sizes. 30 | FFT Size 32: (0, -4, 8), (1, -4, 7), (2, -4, 6), (3, -4, 5), (4, -4, 4), (5, -4, 3), (6, -4, 2), (7, -4, 1), (8, 0, 1), (9, 0, 1), (10, 0, 1), (11, 0, 1), (12, 0, 1), (13, 0, 1), (14, 0, 1), (15, 0, 1) 31 | FFT Size 64: (0, -8, 16), (1, -8, 15), (2, -8, 14), (3, -8, 13), (4, -8, 12), (5, -8, 11), (6, -8, 10), (7, -8, 9), (8, -8, 8), (9, -8, 7), (10, -8, 6), (11, -8, 5), (12, -8, 4), (13, -8, 3), (14, -8, 2), (15, -8, 1) 32 | FFT Size 128: (0, -16, 32), (1, -16, 30), (2, -16, 28), (3, -16, 26), (4, -16, 24), (5, -16, 22), (6, -16, 20), (7, -16, 18), (8, -16, 16), (9, -16, 14), (10, -16, 12), (11, -16, 10), (12, -16, 8), (13, -16, 6), (14, -16, 4), (15, -16, 2) 33 | FFT Size 256: (0, -32, 64), (1, -32, 60), (2, -32, 56), (3, -32, 52), (4, -32, 48), (5, -32, 44), (6, -32, 40), (7, -32, 36), (8, -32, 32), (9, -32, 28), (10, -32, 24), (11, -32, 20), (12, -32, 16), (13, -32, 12), (14, -32, 8), (15, -32, 4) 34 | FFT Size 512: (0, -64, 128), (1, -64, 106), (2, -64, 88), (3, -64, 74), (4, -64, 61), (5, -64, 51), (6, -64, 42), (7, -64, 35), (8, -64, 29), (9, -64, 24), (10, -64, 20), (11, -64, 17), (12, -64, 14), (13, -64, 12), (14, -64, 10), (15, -64, 8) 35 | FFT Size 1024: (0, -128, 256), (1, -128, 203), (2, -128, 161), (3, -128, 128), (4, -128, 102), (5, -128, 81), (6, -128, 64), (7, -128, 51), (8, -128, 40), (9, -128, 32), (10, -128, 25), (11, -128, 20), (12, -128, 16), (13, -128, 13), (14, -128, 10), (15, -128, 8) 36 | FFT Size 2048: (0, -256, 512), (1, -256, 388), (2, -256, 294), (3, -256, 223), (4, -256, 169), (5, -256, 128), (6, -256, 97), (7, -256, 74), (8, -256, 56), (9, -256, 42), (10, -256, 32), (11, -256, 24), (12, -256, 18), (13, -256, 14), (14, -256, 11), (15, -256, 8) 37 | 38 | 568ebabc2835e5569fbb21f020b075fa srs_fft_windows_coefficient_legacy.bin 39 | Historical windows for initial vector genenration, for reference only. 40 | FFT Size 32: (0, 0, 3), (1, 0, 2), (2, 0, 4), (3, 0, 3), (4, 0, 2), (5, 0, 4), (6, -2, 3), (7, -1, 2), (8, -2, 4), (9, -2, 3), (10, -1, 2), (11, -2, 4), (12, -2, 3), (13, -1, 2), (14, -2, 4), (15, 0, 3) 41 | FFT Size 64: (0, 0, 6), (1, 0, 4), (2, 0, 8), (3, 0, 6), (4, 0, 4), (5, 0, 8), (6, -3, 6), (7, -2, 4), (8, -4, 8), (9, -3, 6), (10, -2, 4), (11, -4, 8), (12, -3, 6), (13, -2, 4), (14, -4, 8), (15, 0, 6) 42 | FFT Size 128: (0, 0, 12), (1, 0, 8), (2, 0, 16), (3, 0, 8), (4, 0, 8), (5, 0, 8), (6, -6, 12), (7, -4, 8), (8, -9, 16), (9, -6, 12), (10, -4, 8), (11, -8, 15), (12, -6, 12), (13, -4, 8), (14, -9, 16), (15, 0, 12) 43 | FFT Size 256: (0, 0, 24), (1, 0, 16), (2, 0, 32), (3, 0, 15), (4, 0, 8), (5, 0, 15), (6, -13, 24), (7, -9, 16), (8, -17, 32), (9, -8, 16), (10, -8, 15), (11, -8, 16), (12, -13, 24), (13, -9, 16), (14, -16, 31), (15, 0, 24) 44 | FFT Size 512: (0, 0, 48), (1, 0, 32), (2, 0, 64), (3, 0, 22), (4, 0, 15), (5, 0, 29), (6, -26, 48), (7, -17, 32), (8, -34, 64), (9, -24, 28), (10, -8, 16), (11, -34, 31), (12, -16, 32), (13, -16, 31), (14, -34, 33), (15, 0, 48) 45 | FFT Size 1024: (0, 0, 96), (1, 0, 64), (2, 0, 128), (3, 0, 43), (4, 0, 29), (5, 0, 57), (6, -51, 96), (7, -34, 64), (8, -68, 128), (9, -51, 46), (10, -34, 31), (11, -68, 61), (12, -48, 59), (13, -34, 33), (14, -68, 65), (15, 0, 96) 46 | FFT Size 2048: (0, 0, 192), (1, 0, 128), (2, 0, 256), (3, 0, 85), (4, 0, 57), (5, 0, 113), (6, -102, 192), (7, -68, 128), (8, -137, 256), (9, -102, 91), (10, -68, 61), (11, -136, 120), (12, -102, 97), (13, -68, 65), (14, -137, 130), (15, 0, 192) 47 | -------------------------------------------------------------------------------- /vrb1/srs_fft_windows_coefficient_legacy.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/pf-bb-config/812e032e229f1831998eeb3df36ddc57e2686df9/vrb1/srs_fft_windows_coefficient_legacy.bin -------------------------------------------------------------------------------- /vrb1/vrb1_cfg_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _VRB1_CFG_APP_H_ 20 | #define _VRB1_CFG_APP_H_ 21 | 22 | #include "acc100_cfg_app.h" 23 | 24 | #define VRB1_BYTES_IN_WORD 4 25 | 26 | #define VRB1_NUM_VFS 16 27 | #define VRB1_NUM_QGRPS 16 28 | #define VRB1_NUM_QGRPS_PER_WORD 8 29 | #define VRB1_NUM_AQS 16 30 | #define VRB1_MAX_QDEPTH 12 31 | #define VRB1_QM_BA_SIZE 1024 32 | #define MAX_ENQ_BATCH_SIZE 255 33 | #define VRB1_NUM_TMPL 32 34 | #define VF_OFFSET_QOS 16 /* offset in Memory Space specific to QoS Mon */ 35 | #define VRB1_MON_OFFSET 0x10000 36 | #define VRB1_MON_NUMS 3 37 | #define VRB1_NUM_QOS 3 38 | #define VRB1_TMPL_PRI_0 0x03020100 39 | #define VRB1_TMPL_PRI_1 0x07060504 40 | #define VRB1_TMPL_PRI_2 0x0b0a0908 41 | #define VRB1_TMPL_PRI_3 0x0f0e0d0c 42 | #define VRB1_WORDS_IN_ARAM_SIZE (256 * 1024 / 4) 43 | #define VRB1_ARB_QDEPTH 2 44 | 45 | #define VRB1_SIG_UL_5G 0 46 | #define VRB1_SIG_UL_5G_LAST 4 47 | #define VRB1_SIG_DL_5G 10 48 | #define VRB1_SIG_DL_5G_LAST 11 49 | #define VRB1_SIG_UL_4G 12 50 | #define VRB1_SIG_UL_4G_LAST 16 51 | #define VRB1_SIG_DL_4G 21 52 | #define VRB1_SIG_DL_4G_LAST 23 53 | #define VRB1_SIG_FFT 24 54 | #define VRB1_SIG_FFT_LAST 24 55 | 56 | #define VRB1_NUM_ACCS 5 57 | #define VRB1_ACCMAP_0 0 58 | #define VRB1_ACCMAP_1 2 59 | #define VRB1_ACCMAP_2 1 60 | #define VRB1_ACCMAP_3 3 61 | #define VRB1_ACCMAP_4 4 62 | #define VRB1_PF_VAL 2 63 | 64 | /* VRB1 Configuration */ 65 | #define VRB1_FABRIC_MODE 0x8000103 66 | #define VRB1_CFG_DMA_ERROR 0x3DF 67 | #define VRB1_CFG_AXI_CACHE 0x22 68 | #define VRB1_CFG_QMGR_HI_P 0x0F0F 69 | #define VRB1_CLOCK_GATING_EN 0x30000 70 | #define VRB1_ENGINE_OFFSET 0x1000 71 | #define VRB1_MS_IN_US (1000) 72 | #define VRB1_FFT_CFG_0 0x2001 73 | #define VRB1_FFT_RAM_EN 0x80000000 74 | #define VRB1_FFT_RAM_DIS 0x0 75 | #define VRB1_FFT_RAM_SIZE 512 76 | #define VRB1_FFT_PAGE_SIZE 512 77 | #define VRB1_FFT_FIST_OFFSET 256 78 | #define VRB1_CLK_EN 0x00000881 79 | #define VRB1_CLK_DIS 0x01F00881 80 | #define VRB1_PG_MASK_0 0x1F 81 | #define VRB1_PG_MASK_1 0xF 82 | #define VRB1_PG_MASK_2 0x1 83 | #define VRB1_PG_MASK_3 0x0 84 | #define VRB1_PG_MASK_FFT 1 85 | #define VRB1_PG_MASK_4GUL 4 86 | #define VRB1_PG_MASK_5GUL 8 87 | #define VRB1_PROC_TIMEOUT 0x2000 /* 1ms */ 88 | #define VRB1_ARAM_CONTROL 0x30 89 | 90 | #define VRB1_LUT_SIZE (16*(16+32+64+128+256+512+1024)) 91 | #define VRB1_INFO_RING_NUM_ENTRIES 1024 92 | #define VRB1_PERMON_CTRL_REG_VF_OFFSET 256 93 | #define VRB1_FFT_FIRST_OFFSET 256 94 | #define VRB1_OCODE_REQ 0xFFFF0C0D 95 | 96 | /* Mask used to calculate an index in an Info Ring array (not a byte offset) */ 97 | #define VRB1_INFO_RING_MASK (VRB1_INFO_RING_NUM_ENTRIES-1) 98 | #define VRB1_INFO_RING_PTR_MASK ((VRB1_INFO_RING_NUM_ENTRIES*4)-1) 99 | 100 | #define INFO_RING_DET_INFO GENMASK(15, 0) 101 | #define INFO_RING_DET_INFO_AQ_ID GENMASK(3, 0) 102 | #define INFO_RING_DET_INFO_QG_ID GENMASK(7, 4) 103 | #define INFO_RING_DET_INFO_VF_ID GENMASK(13, 8) 104 | #define INFO_RING_DET_INFO_FEC_SLICE GENMASK(7, 0) 105 | #define INFO_RING_DET_INFO_VF GENMASK(13, 8) 106 | #define INFO_RING_INT_NB GENMASK(22, 16) 107 | #define INFO_RING_MSI_0 BIT(23) 108 | #define INFO_RING_VF2PF GENMASK(29, 24) 109 | #define INFO_RING_LOOP BIT(30) 110 | #define INFO_RING_VALID BIT(31) 111 | 112 | #define VRB1_5GUL_ENGS 5 113 | #define VRB1_5GDL_ENGS 2 114 | #define VRB1_FFT_ENGS 1 115 | #define VRB1_PMON_OFF_1 256 116 | #define VRB1_PMON_OFF_2 16 117 | 118 | #define VRB1_BUSMON_START 2 119 | #define VRB1_BUSMON_RESET 1 120 | #define VRB1_BUSMON_STOP 0 121 | 122 | /** 123 | * Structure to pass VRB1 configuration. 124 | * Note: all VF Bundles will have the same configuration. 125 | */ 126 | struct vrb1_conf { 127 | bool pf_mode_en; /**< 1 if PF is used for dataplane, 0 for VFs */ 128 | /** 1 if input '1' bit is represented by a positive LLR value, 0 if '1' 129 | * bit is represented by a negative value. 130 | */ 131 | bool input_pos_llr_1_bit; 132 | /** 1 if output '1' bit is represented by a positive value, 0 if '1' 133 | * bit is represented by a negative value. 134 | */ 135 | bool output_pos_llr_1_bit; 136 | uint16_t num_vf_bundles; /**< Number of VF bundles to setup */ 137 | struct q_topology_t q_ul_4g; /**< Uplink queues */ 138 | struct q_topology_t q_dl_4g; /**< Downlink queues */ 139 | struct q_topology_t q_ul_5g; /**< Uplink queues */ 140 | struct q_topology_t q_dl_5g; /**< Downlink queues */ 141 | struct q_topology_t q_fft; /**< FFT queues */ 142 | /** Uplink arbitration configuration */ 143 | struct arbitration_t arb_ul_4g[VRB1_NUM_VFS]; 144 | /** Downlink arbitration configuration */ 145 | struct arbitration_t arb_dl_4g[VRB1_NUM_VFS]; 146 | /** Uplink arbitration configuration */ 147 | struct arbitration_t arb_ul_5g[VRB1_NUM_VFS]; 148 | /** Downlink arbitration configuration */ 149 | struct arbitration_t arb_dl_5g[VRB1_NUM_VFS]; 150 | /** FFT arbitration configuration */ 151 | struct arbitration_t arb_fft[VRB1_NUM_VFS]; 152 | }; 153 | 154 | typedef struct { 155 | char *name; 156 | bool use_det_info; 157 | bool fatal; 158 | } vrb1_ir_int_type_info; 159 | 160 | #define VRB1_INFO_RING_SIZE (VRB1_INFO_RING_NUM_ENTRIES * \ 161 | sizeof(uint32_t)) 162 | 163 | /* 164 | * Configure VRB1 165 | */ 166 | 167 | extern int 168 | vrb1_parse_conf_file(const char *file_name, struct vrb1_conf *vrb1_conf); 169 | 170 | #endif /* _VRB1_CFG_APP_H_ */ 171 | -------------------------------------------------------------------------------- /vrb1/vrb1_config.cfg: -------------------------------------------------------------------------------- 1 | vrb1_config_16vf.cfg 2 | -------------------------------------------------------------------------------- /vrb1/vrb1_config_16vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 16 36 | aq_depth_log2 = 4 37 | -------------------------------------------------------------------------------- /vrb1/vrb1_config_pf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 1 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 2 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 2 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 16 36 | aq_depth_log2 = 4 37 | -------------------------------------------------------------------------------- /vrb1/vrb1_config_pf_4g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 1 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 4 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 4 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 0 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 0 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | 33 | [QFFT] 34 | num_qgroups = 0 35 | num_aqs_per_groups = 16 36 | aq_depth_log2 = 4 -------------------------------------------------------------------------------- /vrb1/vrb1_config_pf_5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 1 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 0 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 0 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 16 36 | aq_depth_log2 = 4 37 | -------------------------------------------------------------------------------- /vrb1/vrb1_config_vf_4g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 4 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 4 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 0 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 0 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | 33 | [QFFT] 34 | num_qgroups = 0 35 | num_aqs_per_groups = 16 36 | aq_depth_log2 = 4 37 | -------------------------------------------------------------------------------- /vrb1/vrb1_config_vf_5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2020 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 0 15 | num_aqs_per_groups = 16 16 | aq_depth_log2 = 4 17 | 18 | [QDL4G] 19 | num_qgroups = 0 20 | num_aqs_per_groups = 16 21 | aq_depth_log2 = 4 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 16 26 | aq_depth_log2 = 4 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 16 31 | aq_depth_log2 = 4 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 16 36 | aq_depth_log2 = 4 37 | -------------------------------------------------------------------------------- /vrb1/vrb1_fft_lut.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _VRB1_FFT_LUT_H_ 20 | #define _VRB1_FFT_LUT_H_ 21 | 22 | uint32_t fft_lut[VRB1_FFT_RAM_SIZE] = { 23 | 0x1FFFF, 0x1FFFF, 0x1FFFE, 0x1FFFA, 0x1FFF6, 0x1FFF1, 0x1FFEA, 0x1FFE2, 24 | 0x1FFD9, 0x1FFCE, 0x1FFC2, 0x1FFB5, 0x1FFA7, 0x1FF98, 0x1FF87, 0x1FF75, 25 | 0x1FF62, 0x1FF4E, 0x1FF38, 0x1FF21, 0x1FF09, 0x1FEF0, 0x1FED6, 0x1FEBA, 26 | 0x1FE9D, 0x1FE7F, 0x1FE5F, 0x1FE3F, 0x1FE1D, 0x1FDFA, 0x1FDD5, 0x1FDB0, 27 | 0x1FD89, 0x1FD61, 0x1FD38, 0x1FD0D, 0x1FCE1, 0x1FCB4, 0x1FC86, 0x1FC57, 28 | 0x1FC26, 0x1FBF4, 0x1FBC1, 0x1FB8D, 0x1FB58, 0x1FB21, 0x1FAE9, 0x1FAB0, 29 | 0x1FA75, 0x1FA3A, 0x1F9FD, 0x1F9BF, 0x1F980, 0x1F93F, 0x1F8FD, 0x1F8BA, 30 | 0x1F876, 0x1F831, 0x1F7EA, 0x1F7A3, 0x1F75A, 0x1F70F, 0x1F6C4, 0x1F677, 31 | 0x1F629, 0x1F5DA, 0x1F58A, 0x1F539, 0x1F4E6, 0x1F492, 0x1F43D, 0x1F3E7, 32 | 0x1F38F, 0x1F337, 0x1F2DD, 0x1F281, 0x1F225, 0x1F1C8, 0x1F169, 0x1F109, 33 | 0x1F0A8, 0x1F046, 0x1EFE2, 0x1EF7D, 0x1EF18, 0x1EEB0, 0x1EE48, 0x1EDDF, 34 | 0x1ED74, 0x1ED08, 0x1EC9B, 0x1EC2D, 0x1EBBE, 0x1EB4D, 0x1EADB, 0x1EA68, 35 | 0x1E9F4, 0x1E97F, 0x1E908, 0x1E891, 0x1E818, 0x1E79E, 0x1E722, 0x1E6A6, 36 | 0x1E629, 0x1E5AA, 0x1E52A, 0x1E4A9, 0x1E427, 0x1E3A3, 0x1E31F, 0x1E299, 37 | 0x1E212, 0x1E18A, 0x1E101, 0x1E076, 0x1DFEB, 0x1DF5E, 0x1DED0, 0x1DE41, 38 | 0x1DDB1, 0x1DD20, 0x1DC8D, 0x1DBFA, 0x1DB65, 0x1DACF, 0x1DA38, 0x1D9A0, 39 | 0x1D907, 0x1D86C, 0x1D7D1, 0x1D734, 0x1D696, 0x1D5F7, 0x1D557, 0x1D4B6, 40 | 0x1D413, 0x1D370, 0x1D2CB, 0x1D225, 0x1D17E, 0x1D0D6, 0x1D02D, 0x1CF83, 41 | 0x1CED8, 0x1CE2B, 0x1CD7E, 0x1CCCF, 0x1CC1F, 0x1CB6E, 0x1CABC, 0x1CA09, 42 | 0x1C955, 0x1C89F, 0x1C7E9, 0x1C731, 0x1C679, 0x1C5BF, 0x1C504, 0x1C448, 43 | 0x1C38B, 0x1C2CD, 0x1C20E, 0x1C14E, 0x1C08C, 0x1BFCA, 0x1BF06, 0x1BE42, 44 | 0x1BD7C, 0x1BCB5, 0x1BBED, 0x1BB25, 0x1BA5B, 0x1B990, 0x1B8C4, 0x1B7F6, 45 | 0x1B728, 0x1B659, 0x1B589, 0x1B4B7, 0x1B3E5, 0x1B311, 0x1B23D, 0x1B167, 46 | 0x1B091, 0x1AFB9, 0x1AEE0, 0x1AE07, 0x1AD2C, 0x1AC50, 0x1AB73, 0x1AA95, 47 | 0x1A9B6, 0x1A8D6, 0x1A7F6, 0x1A714, 0x1A631, 0x1A54D, 0x1A468, 0x1A382, 48 | 0x1A29A, 0x1A1B2, 0x1A0C9, 0x19FDF, 0x19EF4, 0x19E08, 0x19D1B, 0x19C2D, 49 | 0x19B3E, 0x19A4E, 0x1995D, 0x1986B, 0x19778, 0x19684, 0x1958F, 0x19499, 50 | 0x193A2, 0x192AA, 0x191B1, 0x190B8, 0x18FBD, 0x18EC1, 0x18DC4, 0x18CC7, 51 | 0x18BC8, 0x18AC8, 0x189C8, 0x188C6, 0x187C4, 0x186C1, 0x185BC, 0x184B7, 52 | 0x183B1, 0x182AA, 0x181A2, 0x18099, 0x17F8F, 0x17E84, 0x17D78, 0x17C6C, 53 | 0x17B5E, 0x17A4F, 0x17940, 0x17830, 0x1771E, 0x1760C, 0x174F9, 0x173E5, 54 | 0x172D1, 0x171BB, 0x170A4, 0x16F8D, 0x16E74, 0x16D5B, 0x16C41, 0x16B26, 55 | 0x16A0A, 0x168ED, 0x167CF, 0x166B1, 0x16592, 0x16471, 0x16350, 0x1622E, 56 | 0x1610B, 0x15FE8, 0x15EC3, 0x15D9E, 0x15C78, 0x15B51, 0x15A29, 0x15900, 57 | 0x157D7, 0x156AC, 0x15581, 0x15455, 0x15328, 0x151FB, 0x150CC, 0x14F9D, 58 | 0x14E6D, 0x14D3C, 0x14C0A, 0x14AD8, 0x149A4, 0x14870, 0x1473B, 0x14606, 59 | 0x144CF, 0x14398, 0x14260, 0x14127, 0x13FEE, 0x13EB3, 0x13D78, 0x13C3C, 60 | 0x13B00, 0x139C2, 0x13884, 0x13745, 0x13606, 0x134C5, 0x13384, 0x13242, 61 | 0x130FF, 0x12FBC, 0x12E78, 0x12D33, 0x12BEE, 0x12AA7, 0x12960, 0x12819, 62 | 0x126D0, 0x12587, 0x1243D, 0x122F3, 0x121A8, 0x1205C, 0x11F0F, 0x11DC2, 63 | 0x11C74, 0x11B25, 0x119D6, 0x11886, 0x11735, 0x115E3, 0x11491, 0x1133F, 64 | 0x111EB, 0x11097, 0x10F42, 0x10DED, 0x10C97, 0x10B40, 0x109E9, 0x10891, 65 | 0x10738, 0x105DF, 0x10485, 0x1032B, 0x101D0, 0x10074, 0x0FF18, 0x0FDBB, 66 | 0x0FC5D, 0x0FAFF, 0x0F9A0, 0x0F841, 0x0F6E1, 0x0F580, 0x0F41F, 0x0F2BD, 67 | 0x0F15B, 0x0EFF8, 0x0EE94, 0x0ED30, 0x0EBCC, 0x0EA67, 0x0E901, 0x0E79A, 68 | 0x0E633, 0x0E4CC, 0x0E364, 0x0E1FB, 0x0E092, 0x0DF29, 0x0DDBE, 0x0DC54, 69 | 0x0DAE9, 0x0D97D, 0x0D810, 0x0D6A4, 0x0D536, 0x0D3C8, 0x0D25A, 0x0D0EB, 70 | 0x0CF7C, 0x0CE0C, 0x0CC9C, 0x0CB2B, 0x0C9B9, 0x0C847, 0x0C6D5, 0x0C562, 71 | 0x0C3EF, 0x0C27B, 0x0C107, 0x0BF92, 0x0BE1D, 0x0BCA8, 0x0BB32, 0x0B9BB, 72 | 0x0B844, 0x0B6CD, 0x0B555, 0x0B3DD, 0x0B264, 0x0B0EB, 0x0AF71, 0x0ADF7, 73 | 0x0AC7D, 0x0AB02, 0x0A987, 0x0A80B, 0x0A68F, 0x0A513, 0x0A396, 0x0A219, 74 | 0x0A09B, 0x09F1D, 0x09D9E, 0x09C20, 0x09AA1, 0x09921, 0x097A1, 0x09621, 75 | 0x094A0, 0x0931F, 0x0919E, 0x0901C, 0x08E9A, 0x08D18, 0x08B95, 0x08A12, 76 | 0x0888F, 0x0870B, 0x08587, 0x08402, 0x0827E, 0x080F9, 0x07F73, 0x07DEE, 77 | 0x07C68, 0x07AE2, 0x0795B, 0x077D4, 0x0764D, 0x074C6, 0x0733E, 0x071B6, 78 | 0x0702E, 0x06EA6, 0x06D1D, 0x06B94, 0x06A0B, 0x06881, 0x066F7, 0x0656D, 79 | 0x063E3, 0x06258, 0x060CE, 0x05F43, 0x05DB7, 0x05C2C, 0x05AA0, 0x05914, 80 | 0x05788, 0x055FC, 0x0546F, 0x052E3, 0x05156, 0x04FC9, 0x04E3B, 0x04CAE, 81 | 0x04B20, 0x04992, 0x04804, 0x04676, 0x044E8, 0x04359, 0x041CB, 0x0403C, 82 | 0x03EAD, 0x03D1D, 0x03B8E, 0x039FF, 0x0386F, 0x036DF, 0x0354F, 0x033BF, 83 | 0x0322F, 0x0309F, 0x02F0F, 0x02D7E, 0x02BEE, 0x02A5D, 0x028CC, 0x0273B, 84 | 0x025AA, 0x02419, 0x02288, 0x020F7, 0x01F65, 0x01DD4, 0x01C43, 0x01AB1, 85 | 0x0191F, 0x0178E, 0x015FC, 0x0146A, 0x012D8, 0x01147, 0x00FB5, 0x00E23, 86 | 0x00C91, 0x00AFF, 0x0096D, 0x007DB, 0x00648, 0x004B6, 0x00324, 0x00192}; 87 | 88 | #endif /* _VRB1_FFT_LUT_H_ */ 89 | -------------------------------------------------------------------------------- /vrb2/srs_fft_windows_coefficient.txt: -------------------------------------------------------------------------------- 1 | Description of provided FFT windows LUT: 2 | ======================================== 3 | 4 | The windowing LUT is made of 16 windows indexes for each of the supported FFT size (from 32 to 2048) in binary format using int16_t (fixed point). 5 | Note that the stored window lengths are equal to half the FFT size (non-stored entries are assumed to be zero) => hence 65024 B total size. 6 | In term of layout the content of these windows is concatenated back to back starting from the smaller FFT: 7 | - first, 16 windows of size 16 x int16_t for the FFT size 32 8 | - then 16 windows of size 32 x int16_t for the FFT size 64 9 | - etc… 10 | 11 | Said otherwise the pointer for the start of the window `Widx` and FFT of index `Fidx` of window size ‘Wsize(Fidx)’ can be computed as: 12 | int16_t *offset(Fidx, Widx) = 16 x Sum(Wsize(i), 0 , Fidx-1) + Widx x Wsize(Fidx) 13 | 14 | A few examples of LUT are included in this directory and are described below. 15 | The tabular format below provides for each window index the start position and the width of each window. 16 | For instance in srs_fft_windows_coefficient_vrb2.bin, for FFT 2048 and window index 1, the window starts at sample -256 and is 388 samples wide. 17 | 18 | d588afc68165192a7155489c39a7a21c srs_fft_windows_coefficient_wide.bin 19 | Recommended windows for VRB1: square window with mix of size and offset 20 | FFT Size 32: (0, -3, 7), (1, -3, 4), (2, -2, 4), (3, -1, 4), (4, 0, 4), (5, -3, 3), (6, -2, 3), (7, -1, 3), (8, 0, 3), (9, 1, 3), (10, -3, 2), (11, -2, 2), (12, -1, 2), (13, 0, 2), (14, 1, 2), (15, 2, 2) 21 | FFT Size 64: (0, -5, 13), (1, -5, 9), (2, -4, 9), (3, -3, 9), (4, -2, 9), (5, -1, 9), (6, -5, 4), (7, -4, 4), (8, -3, 4), (9, -2, 4), (10, -1, 4), (11, 0, 4), (12, 1, 4), (13, 2, 4), (14, 3, 4), (15, 4, 4) 22 | FFT Size 128: (0, -10, 26), (1, -10, 14), (2, -7, 14), (3, -4, 14), (4, -1, 14), (5, 2, 14), (6, -10, 8), (7, -8, 8), (8, -6, 8), (9, -4, 8), (10, -2, 8), (11, 0, 8), (12, 2, 8), (13, 4, 8), (14, 6, 8), (15, 8, 8) 23 | FFT Size 256: (0, -20, 52), (1, -20, 28), (2, -14, 28), (3, -8, 28), (4, -2, 28), (5, 4, 28), (6, -20, 16), (7, -16, 16), (8, -12, 16), (9, -8, 16), (10, -4, 16), (11, 0, 16), (12, 4, 16), (13, 8, 16), (14, 12, 16), (15, 16, 16) 24 | FFT Size 512: (0, -40, 104), (1, -40, 52), (2, -27, 52), (3, -14, 52), (4, -1, 52), (5, 12, 52), (6, -40, 32), (7, -32, 32), (8, -24, 32), (9, -16, 32), (10, -8, 32), (11, 0, 32), (12, 8, 32), (13, 16, 32), (14, 24, 32), (15, 32, 32) 25 | FFT Size 1024: (0, -40, 168), (1, -40, 88), (2, -24, 88), (3, -8, 88), (4, 8, 88), (5, 24, 88), (6, 40, 88), (7, -40, 45), (8, -30, 45), (9, -20, 45), (10, -10, 45), (11, 0, 45), (12, 10, 45), (13, 20, 45), (14, 30, 45), (15, 40, 45) 26 | FFT Size 2048: (0, -40, 296), (1, -40, 160), (2, -24, 160), (3, -8, 160), (4, 8, 160), (5, 24, 160), (6, 40, 160), (7, -40, 80), (8, -30, 80), (9, -20, 80), (10, -10, 80), (11, 0, 80), (12, 10, 80), (13, 20, 80), (14, 30, 80), (15, 40, 80) 27 | 28 | e74a5c8212d5e436be35d446bca16989 srs_fft_windows_coefficient_vrb2.bin 29 | Recommended windows VRB2: square windows with different sizes. 30 | FFT Size 32: (0, -4, 8), (1, -4, 7), (2, -4, 6), (3, -4, 5), (4, -4, 4), (5, -4, 3), (6, -4, 2), (7, -4, 1), (8, 0, 1), (9, 0, 1), (10, 0, 1), (11, 0, 1), (12, 0, 1), (13, 0, 1), (14, 0, 1), (15, 0, 1) 31 | FFT Size 64: (0, -8, 16), (1, -8, 15), (2, -8, 14), (3, -8, 13), (4, -8, 12), (5, -8, 11), (6, -8, 10), (7, -8, 9), (8, -8, 8), (9, -8, 7), (10, -8, 6), (11, -8, 5), (12, -8, 4), (13, -8, 3), (14, -8, 2), (15, -8, 1) 32 | FFT Size 128: (0, -16, 32), (1, -16, 30), (2, -16, 28), (3, -16, 26), (4, -16, 24), (5, -16, 22), (6, -16, 20), (7, -16, 18), (8, -16, 16), (9, -16, 14), (10, -16, 12), (11, -16, 10), (12, -16, 8), (13, -16, 6), (14, -16, 4), (15, -16, 2) 33 | FFT Size 256: (0, -32, 64), (1, -32, 60), (2, -32, 56), (3, -32, 52), (4, -32, 48), (5, -32, 44), (6, -32, 40), (7, -32, 36), (8, -32, 32), (9, -32, 28), (10, -32, 24), (11, -32, 20), (12, -32, 16), (13, -32, 12), (14, -32, 8), (15, -32, 4) 34 | FFT Size 512: (0, -64, 128), (1, -64, 106), (2, -64, 88), (3, -64, 74), (4, -64, 61), (5, -64, 51), (6, -64, 42), (7, -64, 35), (8, -64, 29), (9, -64, 24), (10, -64, 20), (11, -64, 17), (12, -64, 14), (13, -64, 12), (14, -64, 10), (15, -64, 8) 35 | FFT Size 1024: (0, -128, 256), (1, -128, 203), (2, -128, 161), (3, -128, 128), (4, -128, 102), (5, -128, 81), (6, -128, 64), (7, -128, 51), (8, -128, 40), (9, -128, 32), (10, -128, 25), (11, -128, 20), (12, -128, 16), (13, -128, 13), (14, -128, 10), (15, -128, 8) 36 | FFT Size 2048: (0, -256, 512), (1, -256, 388), (2, -256, 294), (3, -256, 223), (4, -256, 169), (5, -256, 128), (6, -256, 97), (7, -256, 74), (8, -256, 56), (9, -256, 42), (10, -256, 32), (11, -256, 24), (12, -256, 18), (13, -256, 14), (14, -256, 11), (15, -256, 8) 37 | 38 | 568ebabc2835e5569fbb21f020b075fa srs_fft_windows_coefficient_legacy.bin 39 | Historical windows for initial vector genenration, for reference only. 40 | FFT Size 32: (0, 0, 3), (1, 0, 2), (2, 0, 4), (3, 0, 3), (4, 0, 2), (5, 0, 4), (6, -2, 3), (7, -1, 2), (8, -2, 4), (9, -2, 3), (10, -1, 2), (11, -2, 4), (12, -2, 3), (13, -1, 2), (14, -2, 4), (15, 0, 3) 41 | FFT Size 64: (0, 0, 6), (1, 0, 4), (2, 0, 8), (3, 0, 6), (4, 0, 4), (5, 0, 8), (6, -3, 6), (7, -2, 4), (8, -4, 8), (9, -3, 6), (10, -2, 4), (11, -4, 8), (12, -3, 6), (13, -2, 4), (14, -4, 8), (15, 0, 6) 42 | FFT Size 128: (0, 0, 12), (1, 0, 8), (2, 0, 16), (3, 0, 8), (4, 0, 8), (5, 0, 8), (6, -6, 12), (7, -4, 8), (8, -9, 16), (9, -6, 12), (10, -4, 8), (11, -8, 15), (12, -6, 12), (13, -4, 8), (14, -9, 16), (15, 0, 12) 43 | FFT Size 256: (0, 0, 24), (1, 0, 16), (2, 0, 32), (3, 0, 15), (4, 0, 8), (5, 0, 15), (6, -13, 24), (7, -9, 16), (8, -17, 32), (9, -8, 16), (10, -8, 15), (11, -8, 16), (12, -13, 24), (13, -9, 16), (14, -16, 31), (15, 0, 24) 44 | FFT Size 512: (0, 0, 48), (1, 0, 32), (2, 0, 64), (3, 0, 22), (4, 0, 15), (5, 0, 29), (6, -26, 48), (7, -17, 32), (8, -34, 64), (9, -24, 28), (10, -8, 16), (11, -34, 31), (12, -16, 32), (13, -16, 31), (14, -34, 33), (15, 0, 48) 45 | FFT Size 1024: (0, 0, 96), (1, 0, 64), (2, 0, 128), (3, 0, 43), (4, 0, 29), (5, 0, 57), (6, -51, 96), (7, -34, 64), (8, -68, 128), (9, -51, 46), (10, -34, 31), (11, -68, 61), (12, -48, 59), (13, -34, 33), (14, -68, 65), (15, 0, 96) 46 | FFT Size 2048: (0, 0, 192), (1, 0, 128), (2, 0, 256), (3, 0, 85), (4, 0, 57), (5, 0, 113), (6, -102, 192), (7, -68, 128), (8, -137, 256), (9, -102, 91), (10, -68, 61), (11, -136, 120), (12, -102, 97), (13, -68, 65), (14, -137, 130), (15, 0, 192) 47 | -------------------------------------------------------------------------------- /vrb2/srs_fft_windows_coefficient_legacy.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/pf-bb-config/812e032e229f1831998eeb3df36ddc57e2686df9/vrb2/srs_fft_windows_coefficient_legacy.bin -------------------------------------------------------------------------------- /vrb2/vrb2_cfg_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (c) 2022 Intel. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | *******************************************************************************/ 18 | 19 | #ifndef _VRB2_CFG_APP_H_ 20 | #define _VRB2_CFG_APP_H_ 21 | 22 | #include "acc100_cfg_app.h" 23 | 24 | #define VRB2_BYTES_IN_WORD 4 25 | 26 | #define VRB2_NUM_VFS 64 27 | #define VRB2_NUM_QGRPS 32 28 | #define VRB2_NUM_QGRPS_PER_WORD 8 29 | #define VRB2_NUM_AQS 64 30 | #define VRB2_MAX_QDEPTH 8 31 | #define VRB2_MAX_QGRPS_PER_OP 256 32 | #define MAX_ENQ_BATCH_SIZE 255 33 | #define VRB2_NUM_TMPL 32 34 | #define VRB2_AQ_REG_NUM 4 35 | #define VF_OFFSET_QOS 16 /* offset in Memory Space specific to QoS Mon */ 36 | #define VRB2_MON_OFFSET 0x10000 37 | #define VRB2_MON_NUMS 6 38 | #define VRB2_TMPL_PRI_0 0x03020100 39 | #define VRB2_TMPL_PRI_1 0x07060504 40 | #define VRB2_TMPL_PRI_2 0x0b0a0908 41 | #define VRB2_TMPL_PRI_3 0x0f0e0d0c 42 | #define VRB2_TMPL_PRI_4 0x13121110 43 | #define VRB2_TMPL_PRI_5 0x17161514 44 | #define VRB2_TMPL_PRI_6 0x1b1a1918 45 | #define VRB2_TMPL_PRI_7 0x1f1e1d1c 46 | #define VRB2_WORDS_IN_ARAM_SIZE (512 * 1024 / 4) 47 | 48 | #define VRB2_SIG_UL_5G 0 49 | #define VRB2_SIG_UL_5G_LAST 5 50 | #define VRB2_SIG_DL_5G 9 51 | #define VRB2_SIG_DL_5G_LAST 11 52 | #define VRB2_SIG_UL_4G 12 53 | #define VRB2_SIG_UL_4G_LAST 16 54 | #define VRB2_SIG_DL_4G 21 55 | #define VRB2_SIG_DL_4G_LAST 23 56 | #define VRB2_SIG_FFT 24 57 | #define VRB2_SIG_FFT_LAST 26 58 | #define VRB2_SIG_MLD 30 59 | #define VRB2_SIG_MLD_LAST 31 60 | #define VRB2_FFT_NUM 3 61 | 62 | #define VRB2_IDMAP_UL_5G 0 63 | #define VRB2_IDMAP_UL_5G_LAST 5 64 | #define VRB2_IDMAP_DL_5G 6 65 | #define VRB2_IDMAP_DL_5G_LAST 8 66 | #define VRB2_IDMAP_UL_4G 9 67 | #define VRB2_IDMAP_UL_4G_LAST 13 68 | #define VRB2_IDMAP_DL_4G 14 69 | #define VRB2_IDMAP_DL_4G_LAST 16 70 | #define VRB2_IDMAP_FFT 17 71 | #define VRB2_IDMAP_FFT_LAST 19 72 | #define VRB2_IDMAP_MLD 20 73 | #define VRB2_IDMAP_MLD_LAST 21 74 | 75 | #define VRB2_NUM_ACCS 6 76 | #define VRB2_ACCMAP_0 0 77 | #define VRB2_ACCMAP_1 2 78 | #define VRB2_ACCMAP_2 1 79 | #define VRB2_ACCMAP_3 3 80 | #define VRB2_ACCMAP_4 4 81 | #define VRB2_ACCMAP_5 5 82 | #define VRB2_PF_VAL 2 83 | 84 | /* VRB2 Configuration */ 85 | #define VRB2_FABRIC_MODE 0x8000103 86 | #define VRB2_CFG_DMA_ERROR 0x7DF 87 | #define VRB2_CFG_AXI_CACHE 0x22 88 | #define VRB2_CFG_QMGR_HI_P 0x0F0F 89 | #define VRB2_CLOCK_GATING_EN 0x30000 90 | #define VRB2_ENGINE_OFFSET 0x1000 91 | #define VRB2_MS_IN_US (1000) 92 | #define VRB2_QMGR_ECC 0x3 93 | #define VRB2_FABRIC_OFFSET 0x10 94 | 95 | #define VRB2_FFT_CFG_0 0x2002 96 | #define VRB2_CLK_EN 0x00030A01 97 | #define VRB2_CLK_DIS 0x03F30A01 98 | #define VRB2_FFT_ECC 0x180 99 | #define VRB2_FFT_CFG_0_A0 0x2001 100 | /* Cannot enable global clock gating on A0. */ 101 | #define VRB2_CLK_EN_A0 0x00030A00 102 | #define VRB2_CLK_DIS_A0 0x03F30A00 103 | #define VRB2_FFT_ECC_A0 0x60 104 | #define VRB2_FFT_RAM_EN 0x80000000 105 | #define VRB2_FFT_RAM_DIS 0x0 106 | #define VRB2_FFT_RAM_SIZE 512 107 | #define VRB2_FFT_PAGE_SIZE 512 108 | #define VRB2_FFT_FIST_OFFSET 256 109 | #define VRB2_PG_MASK_0 0x1F 110 | #define VRB2_PG_MASK_1 0xF 111 | #define VRB2_PG_MASK_2 0x1 112 | #define VRB2_PG_MASK_3 0x0 113 | #define VRB2_PG_MASK_FFT 1 114 | #define VRB2_PG_MASK_4GUL 4 115 | #define VRB2_PG_MASK_5GUL 8 116 | #define VRB2_QSTRIDE_MAP 0x1F07F0 117 | #define VRB2_PROC_TIMEOUT (0x2000 * 0x100) /* 1ms FIXME B0 x 0x100. */ 118 | #define VRB2_QMGR_TIMEOUT (0x100000 * 0x100) /* 1ms FIXME B0 x 0x100. */ 119 | #define VRB2_CLUST_TIMEOUT 0x100000 /* 1ms */ 120 | #define VRB2_QMGR_ARAM_TIMEOUT 0x800 /* 2k cycles */ 121 | #define VRB2_QMGR_AXI_TIMEOUT 0x800 /* 2k cycles */ 122 | #define VRB2_ARAM_CONTROL 0x30 123 | #define VRB2_ENG_TYPE_NUM 6 124 | #define VRB2_ERR_TYPE_PROC_TO 8 125 | #define VRB2_ERR_TYPE_OFFSET 10 126 | #define VRB2_HIERR_MASK 0xFFFFFFEF /* Remove proc time out */ 127 | #define VRB2_EXTERR_MASK 0xFFFDFFFF /* Remove proc time out */ 128 | #define VRB2_CHR_ENABLE 0x3 129 | #define VRB2_CHR_THOLD 0x186A0 130 | #define VRB2_DMA_ERROR_OR_CHR 18 131 | #define VRB2_NUM_QOS 6 132 | #define VRB2_BLOCK_ON_TX 0xC7478807 133 | #define VRB2_A0_VALUE 0x7 134 | #define VRB2_B0_VALUE 0xF 135 | #define VRB2_ARB_QDEPTH 2 136 | #define VRB2_UNUSED 9 137 | #define VRB2_UL_5G_ROUTER_SIZE 3 /* 2 KB */ 138 | #define VRB2_DEFAULT_ROUTER_SIZE 2 /* 1 KB */ 139 | #define VRB2_DMA_WEIGHT 0x1111 140 | #define VRB2_IB_THHOLD 0x20200208 141 | #define VRB2_STREAM_IB_THHOLD 0x00001008 142 | #define VRB2_DMA_SWITCH_DEFAULT 20 143 | #define VRB2_DMA_SWITCH_STREAM 4 144 | #define VRB2_N0_DEPTH_LOG2 5 145 | 146 | #define VRB2_LUT_SIZE (16*(16+32+64+128+256+512+1024)) 147 | 148 | #define VRB2_INFO_RING_NUM_ENTRIES 1024 149 | 150 | /* Mask used to calculate an index in an Info Ring array (not a byte offset) */ 151 | #define VRB2_INFO_RING_MASK (VRB2_INFO_RING_NUM_ENTRIES - 1) 152 | #define VRB2_INFO_RING_PTR_MASK ((VRB2_INFO_RING_NUM_ENTRIES * 4) - 1) 153 | 154 | #define INFO_RING_DET_INFO GENMASK(16, 0) 155 | #define INFO_RING_DET_INFO_AQ_ID GENMASK(5, 0) 156 | #define INFO_RING_DET_INFO_QG_ID GENMASK(10, 6) 157 | #define INFO_RING_DET_INFO_VF_ID GENMASK(16, 11) 158 | #define INFO_RING_DET_INFO_FEC_SLICE GENMASK(10, 0) 159 | #define INFO_RING_DET_INFO_SLAVE_ID GENMASK(1, 0) 160 | #define INFO_RING_DET_INFO_MASTER_ID GENMASK(3, 2) 161 | #define INFO_RING_DET_INFO_WRITE BIT(4) 162 | #define INFO_RING_DET_INFO_TRANS_ID GENMASK(9, 5) 163 | #define INFO_RING_INT_NB GENMASK(22, 17) 164 | #define INFO_RING_MSI_0 BIT(23) 165 | #define INFO_RING_VF2PF GENMASK(29, 24) 166 | #define INFO_RING_ERR_TYPE GENMASK(29, 24) 167 | #define INFO_RING_LOOP BIT(30) 168 | #define INFO_RING_VALID BIT(31) 169 | 170 | 171 | #define VRB2_5GUL_ENGS 6 172 | #define VRB2_5GDL_ENGS 3 173 | #define VRB2_4GUL_ENGS 5 174 | #define VRB2_4GDL_ENGS 3 175 | #define VRB2_FFT_ENGS 3 176 | #define VRB2_MLD_ENGS 1 177 | #define VRB2_PMON_OFF_1 256 178 | #define VRB2_PMON_OFF_2 16 179 | 180 | #define VRB2_BUSMON_START 2 181 | #define VRB2_BUSMON_RESET 1 182 | #define VRB2_BUSMON_STOP 0 183 | #define VRB2_CORE_DMA_ERROR 0x3 184 | #define VRB2_CORE_RECOVERY_FAILURE 0x4800 185 | 186 | /** 187 | * Structure to pass VRB2 configuration. 188 | * Note: all VF Bundles will have the same configuration. 189 | */ 190 | struct vrb2_conf { 191 | bool pf_mode_en; /**< 1 if PF is used for dataplane, 0 for VFs */ 192 | /** 1 if input '1' bit is represented by a positive LLR value, 0 if '1' 193 | * bit is represented by a negative value. 194 | */ 195 | bool input_pos_llr_1_bit; 196 | /** 1 if output '1' bit is represented by a positive value, 0 if '1' 197 | * bit is represented by a negative value. 198 | */ 199 | bool output_pos_llr_1_bit; 200 | uint16_t num_vf_bundles; /**< Number of VF bundles to setup */ 201 | struct q_topology_t q_ul_4g; /**< Uplink queues */ 202 | struct q_topology_t q_dl_4g; /**< Downlink queues */ 203 | struct q_topology_t q_ul_5g; /**< Uplink queues */ 204 | struct q_topology_t q_dl_5g; /**< Downlink queues */ 205 | struct q_topology_t q_fft; /**< FFT queues */ 206 | struct q_topology_t q_mld; /**< MLD queues */ 207 | /** Uplink arbitration configuration */ 208 | struct arbitration_t arb_ul_4g[VRB2_NUM_VFS]; 209 | /** Downlink arbitration configuration */ 210 | struct arbitration_t arb_dl_4g[VRB2_NUM_VFS]; 211 | /** Uplink arbitration configuration */ 212 | struct arbitration_t arb_ul_5g[VRB2_NUM_VFS]; 213 | /** Downlink arbitration configuration */ 214 | struct arbitration_t arb_dl_5g[VRB2_NUM_VFS]; 215 | /** FFT arbitration configuration */ 216 | struct arbitration_t arb_fft[VRB2_NUM_VFS]; 217 | /** MLD arbitration configuration */ 218 | struct arbitration_t arb_mld[VRB2_NUM_VFS]; 219 | }; 220 | 221 | typedef struct { 222 | char *name; 223 | bool use_det_info; 224 | bool fatal; 225 | } vrb2_ir_int_type_info; 226 | 227 | #define VRB2_INFO_RING_SIZE (VRB2_INFO_RING_NUM_ENTRIES * \ 228 | sizeof(uint32_t)) 229 | 230 | /* 231 | * Configure VRB2 232 | */ 233 | 234 | extern int 235 | vrb2_parse_conf_file(const char *file_name, struct vrb2_conf *vrb2_conf); 236 | 237 | #endif /* _VRB2_CFG_APP_H_ */ 238 | -------------------------------------------------------------------------------- /vrb2/vrb2_config_pf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 1 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 4 15 | num_aqs_per_groups = 64 16 | aq_depth_log2 = 5 17 | 18 | [QDL4G] 19 | num_qgroups = 4 20 | num_aqs_per_groups = 64 21 | aq_depth_log2 = 5 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 64 26 | aq_depth_log2 = 5 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 64 31 | aq_depth_log2 = 5 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 64 36 | aq_depth_log2 = 5 37 | 38 | [QMLD] 39 | num_qgroups = 4 40 | num_aqs_per_groups = 64 41 | aq_depth_log2 = 5 42 | -------------------------------------------------------------------------------- /vrb2/vrb2_config_vf.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 64 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 4 15 | num_aqs_per_groups = 64 16 | aq_depth_log2 = 5 17 | 18 | [QDL4G] 19 | num_qgroups = 4 20 | num_aqs_per_groups = 64 21 | aq_depth_log2 = 5 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 64 26 | aq_depth_log2 = 5 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 64 31 | aq_depth_log2 = 5 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 64 36 | aq_depth_log2 = 5 37 | 38 | [QMLD] 39 | num_qgroups = 4 40 | num_aqs_per_groups = 64 41 | aq_depth_log2 = 5 42 | -------------------------------------------------------------------------------- /vrb2/vrb2_config_vf_5g.cfg: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: Apache-2.0 2 | ; Copyright(c) 2022 Intel Corporation 3 | 4 | [MODE] 5 | pf_mode_en = 0 6 | 7 | [VFBUNDLES] 8 | num_vf_bundles = 16 9 | 10 | [MAXQSIZE] 11 | max_queue_size = 1024 12 | 13 | [QUL4G] 14 | num_qgroups = 0 15 | num_aqs_per_groups = 64 16 | aq_depth_log2 = 5 17 | 18 | [QDL4G] 19 | num_qgroups = 0 20 | num_aqs_per_groups = 64 21 | aq_depth_log2 = 5 22 | 23 | [QUL5G] 24 | num_qgroups = 4 25 | num_aqs_per_groups = 64 26 | aq_depth_log2 = 5 27 | 28 | [QDL5G] 29 | num_qgroups = 4 30 | num_aqs_per_groups = 64 31 | aq_depth_log2 = 5 32 | 33 | [QFFT] 34 | num_qgroups = 4 35 | num_aqs_per_groups = 64 36 | aq_depth_log2 = 5 37 | 38 | [QMLD] 39 | num_qgroups = 4 40 | num_aqs_per_groups = 64 41 | aq_depth_log2 = 5 --------------------------------------------------------------------------------