1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * Copyright(c) 2023 Napatech A/S 4 */ 5 6 #include <rte_thread.h> 7 8 #include "ntlog.h" 9 #include "nthw_fpga.h" 10 #include "ntnic_mod_reg.h" 11 12 /* 13 * Global variables shared by NT adapter types 14 */ 15 rte_thread_t monitor_tasks[NUM_ADAPTER_MAX]; 16 volatile int monitor_task_is_running[NUM_ADAPTER_MAX]; 17 18 /* 19 * Signal-handler to stop all monitor threads 20 */ 21 static void stop_monitor_tasks(int signum) 22 { 23 const size_t N = ARRAY_SIZE(monitor_task_is_running); 24 size_t i; 25 26 /* Stop all monitor tasks */ 27 for (i = 0; i < N; i++) { 28 const int is_running = monitor_task_is_running[i]; 29 monitor_task_is_running[i] = 0; 30 31 if (signum == -1 && is_running != 0) { 32 rte_thread_join(monitor_tasks[i], NULL); 33 memset(&monitor_tasks[i], 0, sizeof(monitor_tasks[0])); 34 } 35 } 36 } 37 38 static int nt4ga_adapter_show_info(struct adapter_info_s *p_adapter_info, FILE *pfh) 39 { 40 const char *const p_dev_name = p_adapter_info->p_dev_name; 41 const char *const p_adapter_id_str = p_adapter_info->mp_adapter_id_str; 42 fpga_info_t *p_fpga_info = &p_adapter_info->fpga_info; 43 hw_info_t *p_hw_info = &p_adapter_info->hw_info; 44 mcu_info_t *mcu_info = &p_adapter_info->fpga_info.mcu_info; 45 char a_pci_ident_str[32]; 46 47 snprintf(a_pci_ident_str, sizeof(a_pci_ident_str), PCIIDENT_PRINT_STR, 48 PCIIDENT_TO_DOMAIN(p_fpga_info->pciident), 49 PCIIDENT_TO_BUSNR(p_fpga_info->pciident), 50 PCIIDENT_TO_DEVNR(p_fpga_info->pciident), 51 PCIIDENT_TO_FUNCNR(p_fpga_info->pciident)); 52 53 fprintf(pfh, "%s: DeviceName: %s\n", p_adapter_id_str, (p_dev_name ? p_dev_name : "NA")); 54 fprintf(pfh, "%s: PCI Details:\n", p_adapter_id_str); 55 fprintf(pfh, "%s: %s: %08X: %04X:%04X %04X:%04X\n", p_adapter_id_str, a_pci_ident_str, 56 p_fpga_info->pciident, p_hw_info->pci_vendor_id, p_hw_info->pci_device_id, 57 p_hw_info->pci_sub_vendor_id, p_hw_info->pci_sub_device_id); 58 fprintf(pfh, "%s: FPGA Details:\n", p_adapter_id_str); 59 fprintf(pfh, "%s: %03d-%04d-%02d-%02d [%016" PRIX64 "] (%08X)\n", p_adapter_id_str, 60 p_fpga_info->n_fpga_type_id, p_fpga_info->n_fpga_prod_id, 61 p_fpga_info->n_fpga_ver_id, p_fpga_info->n_fpga_rev_id, p_fpga_info->n_fpga_ident, 62 p_fpga_info->n_fpga_build_time); 63 fprintf(pfh, "%s: FpgaDebugMode=0x%x\n", p_adapter_id_str, p_fpga_info->n_fpga_debug_mode); 64 fprintf(pfh, "%s: Nims=%d PhyPorts=%d PhyQuads=%d RxPorts=%d TxPorts=%d\n", 65 p_adapter_id_str, p_fpga_info->n_nims, p_fpga_info->n_phy_ports, 66 p_fpga_info->n_phy_quads, p_fpga_info->n_rx_ports, p_fpga_info->n_tx_ports); 67 fprintf(pfh, "%s: Hw=0x%02X_rev%d: %s\n", p_adapter_id_str, p_hw_info->hw_platform_id, 68 p_fpga_info->nthw_hw_info.hw_id, p_fpga_info->nthw_hw_info.hw_plat_id_str); 69 fprintf(pfh, "%s: MCU Details:\n", p_adapter_id_str); 70 fprintf(pfh, "%s: HasMcu=%d McuType=%d McuDramSize=%d\n", p_adapter_id_str, 71 mcu_info->mb_has_mcu, mcu_info->mn_mcu_type, mcu_info->mn_mcu_dram_size); 72 73 return 0; 74 } 75 76 static int nt4ga_adapter_init(struct adapter_info_s *p_adapter_info) 77 { 78 const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops(); 79 80 if (flow_filter_ops == NULL) 81 NT_LOG(ERR, NTNIC, "%s: flow_filter module uninitialized", __func__); 82 83 char *const p_dev_name = malloc(24); 84 char *const p_adapter_id_str = malloc(24); 85 fpga_info_t *fpga_info = &p_adapter_info->fpga_info; 86 hw_info_t *p_hw_info = &p_adapter_info->hw_info; 87 88 /* 89 * IMPORTANT: Most variables cannot be determined before nthw fpga model is instantiated 90 * (nthw_fpga_init()) 91 */ 92 int n_phy_ports = -1; 93 int n_nim_ports = -1; 94 int res = -1; 95 nthw_fpga_t *p_fpga = NULL; 96 97 p_hw_info->n_nthw_adapter_id = nthw_platform_get_nthw_adapter_id(p_hw_info->pci_device_id); 98 99 fpga_info->n_nthw_adapter_id = p_hw_info->n_nthw_adapter_id; 100 /* ref: DN-0060 section 9 */ 101 p_hw_info->hw_product_type = p_hw_info->pci_device_id & 0x000f; 102 /* ref: DN-0060 section 9 */ 103 p_hw_info->hw_platform_id = (p_hw_info->pci_device_id >> 4) & 0x00ff; 104 /* ref: DN-0060 section 9 */ 105 p_hw_info->hw_reserved1 = (p_hw_info->pci_device_id >> 12) & 0x000f; 106 107 p_adapter_info->p_dev_name = p_dev_name; 108 109 if (p_dev_name) { 110 snprintf(p_dev_name, 24, PCIIDENT_PRINT_STR, 111 PCIIDENT_TO_DOMAIN(p_adapter_info->fpga_info.pciident), 112 PCIIDENT_TO_BUSNR(p_adapter_info->fpga_info.pciident), 113 PCIIDENT_TO_DEVNR(p_adapter_info->fpga_info.pciident), 114 PCIIDENT_TO_FUNCNR(p_adapter_info->fpga_info.pciident)); 115 NT_LOG(DBG, NTNIC, "%s: (0x%08X)", p_dev_name, 116 p_adapter_info->fpga_info.pciident); 117 } 118 119 p_adapter_info->mp_adapter_id_str = p_adapter_id_str; 120 121 p_adapter_info->fpga_info.mp_adapter_id_str = p_adapter_id_str; 122 123 if (p_adapter_id_str) { 124 snprintf(p_adapter_id_str, 24, "PCI:" PCIIDENT_PRINT_STR, 125 PCIIDENT_TO_DOMAIN(p_adapter_info->fpga_info.pciident), 126 PCIIDENT_TO_BUSNR(p_adapter_info->fpga_info.pciident), 127 PCIIDENT_TO_DEVNR(p_adapter_info->fpga_info.pciident), 128 PCIIDENT_TO_FUNCNR(p_adapter_info->fpga_info.pciident)); 129 NT_LOG(DBG, NTNIC, "%s: %s", p_adapter_id_str, p_dev_name); 130 } 131 132 { 133 int i; 134 135 for (i = 0; i < (int)ARRAY_SIZE(p_adapter_info->mp_port_id_str); i++) { 136 char *p = malloc(32); 137 138 if (p) { 139 snprintf(p, 32, "%s:intf_%d", 140 (p_adapter_id_str ? p_adapter_id_str : "NA"), i); 141 } 142 143 p_adapter_info->mp_port_id_str[i] = p; 144 } 145 } 146 147 res = nthw_fpga_init(&p_adapter_info->fpga_info); 148 149 if (res) { 150 NT_LOG_DBGX(ERR, NTNIC, "%s: %s: FPGA=%04d res=x%08X", p_adapter_id_str, 151 p_dev_name, fpga_info->n_fpga_prod_id, res); 152 return res; 153 } 154 155 assert(fpga_info); 156 p_fpga = fpga_info->mp_fpga; 157 assert(p_fpga); 158 n_phy_ports = fpga_info->n_phy_ports; 159 assert(n_phy_ports >= 1); 160 n_nim_ports = fpga_info->n_nims; 161 assert(n_nim_ports >= 1); 162 163 /* Nt4ga Init Filter */ 164 nt4ga_filter_t *p_filter = &p_adapter_info->nt4ga_filter; 165 166 if (flow_filter_ops != NULL) { 167 res = flow_filter_ops->flow_filter_init(p_fpga, &p_filter->mp_flow_device, 168 p_adapter_info->adapter_no); 169 170 if (res != 0) { 171 NT_LOG(ERR, NTNIC, "%s: Cannot initialize filter", p_adapter_id_str); 172 return res; 173 } 174 } 175 176 { 177 int i; 178 const struct link_ops_s *link_ops = NULL; 179 assert(fpga_info->n_fpga_prod_id > 0); 180 181 for (i = 0; i < NUM_ADAPTER_PORTS_MAX; i++) { 182 /* Disable all ports. Must be enabled later */ 183 p_adapter_info->nt4ga_link.port_action[i].port_disable = true; 184 } 185 186 switch (fpga_info->n_fpga_prod_id) { 187 /* NT200A01: 2x100G (Xilinx) */ 188 case 9563: /* NT200A02 (Cap) */ 189 link_ops = get_100g_link_ops(); 190 191 if (link_ops == NULL) { 192 NT_LOG(ERR, NTNIC, "NT200A02 100G link module uninitialized"); 193 res = -1; 194 break; 195 } 196 197 res = link_ops->link_init(p_adapter_info, p_fpga); 198 break; 199 200 default: 201 NT_LOG(ERR, NTNIC, "Unsupported FPGA product: %04d", 202 fpga_info->n_fpga_prod_id); 203 res = -1; 204 break; 205 } 206 207 if (res) { 208 NT_LOG_DBGX(ERR, NTNIC, "%s: %s: FPGA=%04d res=x%08X", 209 p_adapter_id_str, p_dev_name, 210 fpga_info->n_fpga_prod_id, res); 211 return res; 212 } 213 } 214 215 const struct nt4ga_stat_ops *nt4ga_stat_ops = get_nt4ga_stat_ops(); 216 217 if (nt4ga_stat_ops != NULL) { 218 /* Nt4ga Stat init/setup */ 219 res = nt4ga_stat_ops->nt4ga_stat_init(p_adapter_info); 220 221 if (res != 0) { 222 NT_LOG(ERR, NTNIC, "%s: Cannot initialize the statistics module", 223 p_adapter_id_str); 224 return res; 225 } 226 227 res = nt4ga_stat_ops->nt4ga_stat_setup(p_adapter_info); 228 229 if (res != 0) { 230 NT_LOG(ERR, NTNIC, "%s: Cannot setup the statistics module", 231 p_adapter_id_str); 232 return res; 233 } 234 } 235 236 return 0; 237 } 238 239 static int nt4ga_adapter_deinit(struct adapter_info_s *p_adapter_info) 240 { 241 const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops(); 242 243 if (flow_filter_ops == NULL) 244 NT_LOG(ERR, NTNIC, "%s: flow_filter module uninitialized", __func__); 245 246 fpga_info_t *fpga_info = &p_adapter_info->fpga_info; 247 int i; 248 int res = -1; 249 250 stop_monitor_tasks(-1); 251 252 /* Nt4ga Deinit Filter */ 253 nt4ga_filter_t *p_filter = &p_adapter_info->nt4ga_filter; 254 255 if (flow_filter_ops != NULL) { 256 res = flow_filter_ops->flow_filter_done(p_filter->mp_flow_device); 257 258 if (res != 0) { 259 NT_LOG(ERR, NTNIC, "Cannot deinitialize filter"); 260 return res; 261 } 262 } 263 264 nthw_fpga_shutdown(&p_adapter_info->fpga_info); 265 266 /* Rac rab reset flip flop */ 267 res = nthw_rac_rab_reset(fpga_info->mp_nthw_rac); 268 269 /* Free adapter port ident strings */ 270 for (i = 0; i < fpga_info->n_phy_ports; i++) { 271 if (p_adapter_info->mp_port_id_str[i]) { 272 free(p_adapter_info->mp_port_id_str[i]); 273 p_adapter_info->mp_port_id_str[i] = NULL; 274 } 275 } 276 277 /* Free adapter ident string */ 278 if (p_adapter_info->mp_adapter_id_str) { 279 free(p_adapter_info->mp_adapter_id_str); 280 p_adapter_info->mp_adapter_id_str = NULL; 281 } 282 283 /* Free devname ident string */ 284 if (p_adapter_info->p_dev_name) { 285 free(p_adapter_info->p_dev_name); 286 p_adapter_info->p_dev_name = NULL; 287 } 288 289 return res; 290 } 291 292 static const struct adapter_ops ops = { 293 .init = nt4ga_adapter_init, 294 .deinit = nt4ga_adapter_deinit, 295 296 .show_info = nt4ga_adapter_show_info, 297 }; 298 299 void adapter_init(void) 300 { 301 register_adapter_ops(&ops); 302 } 303