1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * Copyright(c) 2023 Napatech A/S 4 */ 5 6 #include "ntlog.h" 7 8 #include "nthw_drv.h" 9 #include "nthw_register.h" 10 11 #include "nthw_fpga.h" 12 13 #include "nthw_fpga_instances.h" 14 #include "nthw_fpga_mod_str_map.h" 15 16 #include <arpa/inet.h> 17 18 int nthw_fpga_get_param_info(struct fpga_info_s *p_fpga_info, nthw_fpga_t *p_fpga) 19 { 20 mcu_info_t *p_mcu_info = &p_fpga_info->mcu_info; 21 22 const int n_phy_ports = nthw_fpga_get_product_param(p_fpga, NT_PHY_PORTS, -1); 23 const int n_phy_quads = nthw_fpga_get_product_param(p_fpga, NT_PHY_QUADS, -1); 24 const int n_rx_ports = nthw_fpga_get_product_param(p_fpga, NT_RX_PORTS, -1); 25 const int n_tx_ports = nthw_fpga_get_product_param(p_fpga, NT_TX_PORTS, -1); 26 const int n_vf_offset = nthw_fpga_get_product_param(p_fpga, NT_HIF_VF_OFFSET, 4); 27 28 p_fpga_info->n_phy_ports = n_phy_ports; 29 p_fpga_info->n_phy_quads = n_phy_quads; 30 p_fpga_info->n_rx_ports = n_rx_ports; 31 p_fpga_info->n_tx_ports = n_tx_ports; 32 p_fpga_info->n_vf_offset = n_vf_offset; 33 p_fpga_info->profile = FPGA_INFO_PROFILE_UNKNOWN; 34 35 /* Check for MCU */ 36 if (nthw_fpga_get_product_param(p_fpga, NT_MCU_PRESENT, 0) != 0) { 37 p_mcu_info->mb_has_mcu = true; 38 /* Check MCU Type */ 39 p_mcu_info->mn_mcu_type = nthw_fpga_get_product_param(p_fpga, NT_MCU_TYPE, -1); 40 /* MCU DRAM size */ 41 p_mcu_info->mn_mcu_dram_size = 42 nthw_fpga_get_product_param(p_fpga, NT_MCU_DRAM_SIZE, -1); 43 44 } else { 45 p_mcu_info->mb_has_mcu = false; 46 p_mcu_info->mn_mcu_type = -1; 47 p_mcu_info->mn_mcu_dram_size = -1; 48 } 49 50 /* Check for VSWITCH FPGA */ 51 if (nthw_fpga_get_product_param(p_fpga, NT_NFV_OVS_PRODUCT, 0) != 0) { 52 p_fpga_info->profile = FPGA_INFO_PROFILE_VSWITCH; 53 54 } else if (nthw_fpga_get_product_param(p_fpga, NT_IOA_PRESENT, 0) != 0) { 55 /* Check for VSWITCH FPGA - legacy */ 56 p_fpga_info->profile = FPGA_INFO_PROFILE_VSWITCH; 57 58 } else if (nthw_fpga_get_product_param(p_fpga, NT_QM_PRESENT, 0) != 0) { 59 p_fpga_info->profile = FPGA_INFO_PROFILE_CAPTURE; 60 61 } else { 62 p_fpga_info->profile = FPGA_INFO_PROFILE_INLINE; 63 } 64 65 return 0; 66 } 67 68 int nthw_fpga_init(struct fpga_info_s *p_fpga_info) 69 { 70 const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str; 71 72 nthw_hif_t *p_nthw_hif = NULL; 73 nthw_pcie3_t *p_nthw_pcie3 = NULL; 74 nthw_rac_t *p_nthw_rac = NULL; 75 76 mcu_info_t *p_mcu_info = &p_fpga_info->mcu_info; 77 uint64_t n_fpga_ident = 0; 78 nthw_fpga_mgr_t *p_fpga_mgr = NULL; 79 nthw_fpga_t *p_fpga = NULL; 80 81 char s_fpga_prod_ver_rev_str[32] = { 0 }; 82 83 int res = 0; 84 85 assert(p_fpga_info); 86 87 { 88 const uint64_t n_fpga_ident = nthw_fpga_read_ident(p_fpga_info); 89 const uint32_t n_fpga_build_time = nthw_fpga_read_buildtime(p_fpga_info); 90 const int n_fpga_type_id = nthw_fpga_extract_type_id(n_fpga_ident); 91 const int n_fpga_prod_id = nthw_fpga_extract_prod_id(n_fpga_ident); 92 const int n_fpga_ver_id = nthw_fpga_extract_ver_id(n_fpga_ident); 93 const int n_fpga_rev_id = nthw_fpga_extract_rev_id(n_fpga_ident); 94 95 p_fpga_info->n_fpga_ident = n_fpga_ident; 96 p_fpga_info->n_fpga_type_id = n_fpga_type_id; 97 p_fpga_info->n_fpga_prod_id = n_fpga_prod_id; 98 p_fpga_info->n_fpga_ver_id = n_fpga_ver_id; 99 p_fpga_info->n_fpga_rev_id = n_fpga_rev_id; 100 p_fpga_info->n_fpga_build_time = n_fpga_build_time; 101 102 snprintf(s_fpga_prod_ver_rev_str, sizeof(s_fpga_prod_ver_rev_str), 103 "%04d-%04d-%02d-%02d", n_fpga_type_id, n_fpga_prod_id, n_fpga_ver_id, 104 n_fpga_rev_id); 105 106 NT_LOG(INF, NTHW, "%s: FPGA %s (%" PRIX64 ") [%08X]\n", p_adapter_id_str, 107 s_fpga_prod_ver_rev_str, n_fpga_ident, n_fpga_build_time); 108 } 109 110 n_fpga_ident = p_fpga_info->n_fpga_ident; 111 112 p_fpga_mgr = nthw_fpga_mgr_new(); 113 nthw_fpga_mgr_init(p_fpga_mgr, nthw_fpga_instances, 114 (const void *)sa_nthw_fpga_mod_str_map); 115 nthw_fpga_mgr_log_dump(p_fpga_mgr); 116 p_fpga = nthw_fpga_mgr_query_fpga(p_fpga_mgr, n_fpga_ident, p_fpga_info); 117 p_fpga_info->mp_fpga = p_fpga; 118 119 if (p_fpga == NULL) { 120 NT_LOG(ERR, NTHW, "%s: Unsupported FPGA: %s (%08X)\n", p_adapter_id_str, 121 s_fpga_prod_ver_rev_str, p_fpga_info->n_fpga_build_time); 122 return -1; 123 } 124 125 if (p_fpga_mgr) { 126 nthw_fpga_mgr_delete(p_fpga_mgr); 127 p_fpga_mgr = NULL; 128 } 129 130 /* Read Fpga param info */ 131 nthw_fpga_get_param_info(p_fpga_info, p_fpga); 132 133 /* debug: report params */ 134 NT_LOG(DBG, NTHW, "%s: NT_PHY_PORTS=%d\n", p_adapter_id_str, p_fpga_info->n_phy_ports); 135 NT_LOG(DBG, NTHW, "%s: NT_PHY_QUADS=%d\n", p_adapter_id_str, p_fpga_info->n_phy_quads); 136 NT_LOG(DBG, NTHW, "%s: NT_RX_PORTS=%d\n", p_adapter_id_str, p_fpga_info->n_rx_ports); 137 NT_LOG(DBG, NTHW, "%s: NT_TX_PORTS=%d\n", p_adapter_id_str, p_fpga_info->n_tx_ports); 138 NT_LOG(DBG, NTHW, "%s: nProfile=%d\n", p_adapter_id_str, (int)p_fpga_info->profile); 139 NT_LOG(DBG, NTHW, "%s: bHasMcu=%d\n", p_adapter_id_str, p_mcu_info->mb_has_mcu); 140 NT_LOG(DBG, NTHW, "%s: McuType=%d\n", p_adapter_id_str, p_mcu_info->mn_mcu_type); 141 NT_LOG(DBG, NTHW, "%s: McuDramSize=%d\n", p_adapter_id_str, p_mcu_info->mn_mcu_dram_size); 142 143 p_nthw_rac = nthw_rac_new(); 144 145 if (p_nthw_rac == NULL) { 146 NT_LOG(ERR, NTHW, "%s: Unsupported FPGA: RAC is not found: %s (%08X)\n", 147 p_adapter_id_str, s_fpga_prod_ver_rev_str, p_fpga_info->n_fpga_build_time); 148 return -1; 149 } 150 151 nthw_rac_init(p_nthw_rac, p_fpga, p_fpga_info); 152 nthw_rac_rab_flush(p_nthw_rac); 153 p_fpga_info->mp_nthw_rac = p_nthw_rac; 154 155 switch (p_fpga_info->n_nthw_adapter_id) { 156 default: 157 NT_LOG(ERR, NTHW, "%s: Unsupported HW product id: %d\n", p_adapter_id_str, 158 p_fpga_info->n_nthw_adapter_id); 159 res = -1; 160 break; 161 } 162 163 if (res) { 164 NT_LOG(ERR, NTHW, "%s: status: 0x%08X\n", p_adapter_id_str, res); 165 return res; 166 } 167 168 res = nthw_pcie3_init(NULL, p_fpga, 0); /* Probe for module */ 169 170 if (res == 0) { 171 p_nthw_pcie3 = nthw_pcie3_new(); 172 173 if (p_nthw_pcie3) { 174 res = nthw_pcie3_init(p_nthw_pcie3, p_fpga, 0); 175 176 if (res == 0) { 177 NT_LOG(DBG, NTHW, "%s: Pcie3 module found\n", p_adapter_id_str); 178 nthw_pcie3_trigger_sample_time(p_nthw_pcie3); 179 180 } else { 181 nthw_pcie3_delete(p_nthw_pcie3); 182 p_nthw_pcie3 = NULL; 183 } 184 } 185 186 p_fpga_info->mp_nthw_pcie3 = p_nthw_pcie3; 187 } 188 189 if (p_nthw_pcie3 == NULL) { 190 p_nthw_hif = nthw_hif_new(); 191 192 if (p_nthw_hif) { 193 res = nthw_hif_init(p_nthw_hif, p_fpga, 0); 194 195 if (res == 0) { 196 NT_LOG(DBG, NTHW, "%s: Hif module found\n", p_adapter_id_str); 197 nthw_hif_trigger_sample_time(p_nthw_hif); 198 199 } else { 200 nthw_hif_delete(p_nthw_hif); 201 p_nthw_hif = NULL; 202 } 203 } 204 } 205 206 p_fpga_info->mp_nthw_hif = p_nthw_hif; 207 208 209 return res; 210 } 211 212 int nthw_fpga_shutdown(struct fpga_info_s *p_fpga_info) 213 { 214 int res = -1; 215 216 if (p_fpga_info) { 217 if (p_fpga_info && p_fpga_info->mp_nthw_rac) 218 res = nthw_rac_rab_reset(p_fpga_info->mp_nthw_rac); 219 } 220 221 return res; 222 } 223