1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2020 Broadcom 3 * All rights reserved. 4 */ 5 6 #include "tf_device.h" 7 #include "tf_device_p4.h" 8 #include "tfp.h" 9 #include "tf_em.h" 10 11 struct tf; 12 13 /* Forward declarations */ 14 static int tf_dev_unbind_p4(struct tf *tfp); 15 16 /** 17 * Device specific bind function, WH+ 18 * 19 * [in] tfp 20 * Pointer to TF handle 21 * 22 * [in] shadow_copy 23 * Flag controlling shadow copy DB creation 24 * 25 * [in] resources 26 * Pointer to resource allocation information 27 * 28 * [out] dev_handle 29 * Device handle 30 * 31 * Returns 32 * - (0) if successful. 33 * - (-EINVAL) on parameter or internal failure. 34 */ 35 static int 36 tf_dev_bind_p4(struct tf *tfp, 37 bool shadow_copy, 38 struct tf_session_resources *resources, 39 struct tf_dev_info *dev_handle) 40 { 41 int rc; 42 int frc; 43 struct tf_ident_cfg_parms ident_cfg; 44 struct tf_tbl_cfg_parms tbl_cfg; 45 struct tf_tcam_cfg_parms tcam_cfg; 46 struct tf_em_cfg_parms em_cfg; 47 struct tf_if_tbl_cfg_parms if_tbl_cfg; 48 struct tf_global_cfg_cfg_parms global_cfg; 49 50 dev_handle->type = TF_DEVICE_TYPE_WH; 51 /* Initial function initialization */ 52 dev_handle->ops = &tf_dev_ops_p4_init; 53 54 /* Initialize the modules */ 55 56 ident_cfg.num_elements = TF_IDENT_TYPE_MAX; 57 ident_cfg.cfg = tf_ident_p4; 58 ident_cfg.shadow_copy = shadow_copy; 59 ident_cfg.resources = resources; 60 rc = tf_ident_bind(tfp, &ident_cfg); 61 if (rc) { 62 TFP_DRV_LOG(ERR, 63 "Identifier initialization failure\n"); 64 goto fail; 65 } 66 67 tbl_cfg.num_elements = TF_TBL_TYPE_MAX; 68 tbl_cfg.cfg = tf_tbl_p4; 69 tbl_cfg.shadow_copy = shadow_copy; 70 tbl_cfg.resources = resources; 71 rc = tf_tbl_bind(tfp, &tbl_cfg); 72 if (rc) { 73 TFP_DRV_LOG(ERR, 74 "Table initialization failure\n"); 75 goto fail; 76 } 77 78 tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX; 79 tcam_cfg.cfg = tf_tcam_p4; 80 tcam_cfg.shadow_copy = shadow_copy; 81 tcam_cfg.resources = resources; 82 rc = tf_tcam_bind(tfp, &tcam_cfg); 83 if (rc) { 84 TFP_DRV_LOG(ERR, 85 "TCAM initialization failure\n"); 86 goto fail; 87 } 88 89 /* 90 * EEM 91 */ 92 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; 93 em_cfg.cfg = tf_em_ext_p4; 94 em_cfg.resources = resources; 95 #ifdef TF_USE_SYSTEM_MEM 96 em_cfg.mem_type = TF_EEM_MEM_TYPE_SYSTEM; 97 #else 98 em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST; 99 #endif 100 rc = tf_em_ext_common_bind(tfp, &em_cfg); 101 if (rc) { 102 TFP_DRV_LOG(ERR, 103 "EEM initialization failure\n"); 104 goto fail; 105 } 106 107 /* 108 * EM 109 */ 110 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; 111 em_cfg.cfg = tf_em_int_p4; 112 em_cfg.resources = resources; 113 em_cfg.mem_type = 0; /* Not used by EM */ 114 115 rc = tf_em_int_bind(tfp, &em_cfg); 116 if (rc) { 117 TFP_DRV_LOG(ERR, 118 "EM initialization failure\n"); 119 goto fail; 120 } 121 122 /* 123 * IF_TBL 124 */ 125 if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX; 126 if_tbl_cfg.cfg = tf_if_tbl_p4; 127 if_tbl_cfg.shadow_copy = shadow_copy; 128 rc = tf_if_tbl_bind(tfp, &if_tbl_cfg); 129 if (rc) { 130 TFP_DRV_LOG(ERR, 131 "IF Table initialization failure\n"); 132 goto fail; 133 } 134 135 /* 136 * GLOBAL_CFG 137 */ 138 global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX; 139 global_cfg.cfg = tf_global_cfg_p4; 140 rc = tf_global_cfg_bind(tfp, &global_cfg); 141 if (rc) { 142 TFP_DRV_LOG(ERR, 143 "Global Cfg initialization failure\n"); 144 goto fail; 145 } 146 147 /* Final function initialization */ 148 dev_handle->ops = &tf_dev_ops_p4; 149 150 return 0; 151 152 fail: 153 /* Cleanup of already created modules */ 154 frc = tf_dev_unbind_p4(tfp); 155 if (frc) 156 return frc; 157 158 return rc; 159 } 160 161 /** 162 * Device specific unbind function, WH+ 163 * 164 * [in] tfp 165 * Pointer to TF handle 166 * 167 * Returns 168 * - (0) if successful. 169 * - (-EINVAL) on failure. 170 */ 171 static int 172 tf_dev_unbind_p4(struct tf *tfp) 173 { 174 int rc = 0; 175 bool fail = false; 176 177 /* Unbind all the support modules. As this is only done on 178 * close we only report errors as everything has to be cleaned 179 * up regardless. 180 * 181 * In case of residuals TCAMs are cleaned up first as to 182 * invalidate the pipeline in a clean manner. 183 */ 184 rc = tf_tcam_unbind(tfp); 185 if (rc) { 186 TFP_DRV_LOG(ERR, 187 "Device unbind failed, TCAM\n"); 188 fail = true; 189 } 190 191 rc = tf_ident_unbind(tfp); 192 if (rc) { 193 TFP_DRV_LOG(ERR, 194 "Device unbind failed, Identifier\n"); 195 fail = true; 196 } 197 198 rc = tf_tbl_unbind(tfp); 199 if (rc) { 200 TFP_DRV_LOG(ERR, 201 "Device unbind failed, Table Type\n"); 202 fail = true; 203 } 204 205 rc = tf_em_ext_common_unbind(tfp); 206 if (rc) { 207 TFP_DRV_LOG(ERR, 208 "Device unbind failed, EEM\n"); 209 fail = true; 210 } 211 212 rc = tf_em_int_unbind(tfp); 213 if (rc) { 214 TFP_DRV_LOG(ERR, 215 "Device unbind failed, EM\n"); 216 fail = true; 217 } 218 219 rc = tf_if_tbl_unbind(tfp); 220 if (rc) { 221 TFP_DRV_LOG(ERR, 222 "Device unbind failed, IF Table Type\n"); 223 fail = true; 224 } 225 226 rc = tf_global_cfg_unbind(tfp); 227 if (rc) { 228 TFP_DRV_LOG(ERR, 229 "Device unbind failed, Global Cfg Type\n"); 230 fail = true; 231 } 232 233 if (fail) 234 return -1; 235 236 return rc; 237 } 238 239 int 240 tf_dev_bind(struct tf *tfp __rte_unused, 241 enum tf_device_type type, 242 bool shadow_copy, 243 struct tf_session_resources *resources, 244 struct tf_dev_info *dev_handle) 245 { 246 switch (type) { 247 case TF_DEVICE_TYPE_WH: 248 return tf_dev_bind_p4(tfp, 249 shadow_copy, 250 resources, 251 dev_handle); 252 default: 253 TFP_DRV_LOG(ERR, 254 "No such device\n"); 255 return -ENODEV; 256 } 257 } 258 259 int 260 tf_dev_unbind(struct tf *tfp, 261 struct tf_dev_info *dev_handle) 262 { 263 switch (dev_handle->type) { 264 case TF_DEVICE_TYPE_WH: 265 return tf_dev_unbind_p4(tfp); 266 default: 267 TFP_DRV_LOG(ERR, 268 "No such device\n"); 269 return -ENODEV; 270 } 271 } 272