1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2021 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 /* Initial function initialization */ 51 dev_handle->ops = &tf_dev_ops_p4_init; 52 53 /* Initialize the modules */ 54 55 ident_cfg.num_elements = TF_IDENT_TYPE_MAX; 56 ident_cfg.cfg = tf_ident_p4; 57 ident_cfg.shadow_copy = shadow_copy; 58 ident_cfg.resources = resources; 59 rc = tf_ident_bind(tfp, &ident_cfg); 60 if (rc) { 61 TFP_DRV_LOG(ERR, 62 "Identifier initialization failure\n"); 63 goto fail; 64 } 65 66 tbl_cfg.num_elements = TF_TBL_TYPE_MAX; 67 tbl_cfg.cfg = tf_tbl_p4; 68 tbl_cfg.shadow_copy = shadow_copy; 69 tbl_cfg.resources = resources; 70 rc = tf_tbl_bind(tfp, &tbl_cfg); 71 if (rc) { 72 TFP_DRV_LOG(ERR, 73 "Table initialization failure\n"); 74 goto fail; 75 } 76 77 tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX; 78 tcam_cfg.cfg = tf_tcam_p4; 79 tcam_cfg.shadow_copy = shadow_copy; 80 tcam_cfg.resources = resources; 81 rc = tf_tcam_bind(tfp, &tcam_cfg); 82 if (rc) { 83 TFP_DRV_LOG(ERR, 84 "TCAM initialization failure\n"); 85 goto fail; 86 } 87 88 /* 89 * EEM 90 */ 91 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; 92 if (dev_handle->type == TF_DEVICE_TYPE_WH) 93 em_cfg.cfg = tf_em_ext_p4; 94 else 95 em_cfg.cfg = tf_em_ext_p45; 96 em_cfg.resources = resources; 97 em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST; 98 rc = tf_em_ext_common_bind(tfp, &em_cfg); 99 if (rc) { 100 TFP_DRV_LOG(ERR, 101 "EEM initialization failure\n"); 102 goto fail; 103 } 104 105 /* 106 * EM 107 */ 108 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; 109 em_cfg.cfg = tf_em_int_p4; 110 em_cfg.resources = resources; 111 em_cfg.mem_type = 0; /* Not used by EM */ 112 113 rc = tf_em_int_bind(tfp, &em_cfg); 114 if (rc) { 115 TFP_DRV_LOG(ERR, 116 "EM initialization failure\n"); 117 goto fail; 118 } 119 120 /* 121 * IF_TBL 122 */ 123 if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX; 124 if_tbl_cfg.cfg = tf_if_tbl_p4; 125 if_tbl_cfg.shadow_copy = shadow_copy; 126 rc = tf_if_tbl_bind(tfp, &if_tbl_cfg); 127 if (rc) { 128 TFP_DRV_LOG(ERR, 129 "IF Table initialization failure\n"); 130 goto fail; 131 } 132 133 /* 134 * GLOBAL_CFG 135 */ 136 global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX; 137 global_cfg.cfg = tf_global_cfg_p4; 138 rc = tf_global_cfg_bind(tfp, &global_cfg); 139 if (rc) { 140 TFP_DRV_LOG(ERR, 141 "Global Cfg initialization failure\n"); 142 goto fail; 143 } 144 145 /* Final function initialization */ 146 dev_handle->ops = &tf_dev_ops_p4; 147 148 return 0; 149 150 fail: 151 /* Cleanup of already created modules */ 152 frc = tf_dev_unbind_p4(tfp); 153 if (frc) 154 return frc; 155 156 return rc; 157 } 158 159 /** 160 * Device specific unbind function, WH+ 161 * 162 * [in] tfp 163 * Pointer to TF handle 164 * 165 * Returns 166 * - (0) if successful. 167 * - (-EINVAL) on failure. 168 */ 169 static int 170 tf_dev_unbind_p4(struct tf *tfp) 171 { 172 int rc = 0; 173 bool fail = false; 174 175 /* Unbind all the support modules. As this is only done on 176 * close we only report errors as everything has to be cleaned 177 * up regardless. 178 * 179 * In case of residuals TCAMs are cleaned up first as to 180 * invalidate the pipeline in a clean manner. 181 */ 182 rc = tf_tcam_unbind(tfp); 183 if (rc) { 184 TFP_DRV_LOG(ERR, 185 "Device unbind failed, TCAM\n"); 186 fail = true; 187 } 188 189 rc = tf_ident_unbind(tfp); 190 if (rc) { 191 TFP_DRV_LOG(ERR, 192 "Device unbind failed, Identifier\n"); 193 fail = true; 194 } 195 196 rc = tf_tbl_unbind(tfp); 197 if (rc) { 198 TFP_DRV_LOG(ERR, 199 "Device unbind failed, Table Type\n"); 200 fail = true; 201 } 202 203 rc = tf_em_ext_common_unbind(tfp); 204 if (rc) { 205 TFP_DRV_LOG(ERR, 206 "Device unbind failed, EEM\n"); 207 fail = true; 208 } 209 210 rc = tf_em_int_unbind(tfp); 211 if (rc) { 212 TFP_DRV_LOG(ERR, 213 "Device unbind failed, EM\n"); 214 fail = true; 215 } 216 217 rc = tf_if_tbl_unbind(tfp); 218 if (rc) { 219 TFP_DRV_LOG(ERR, 220 "Device unbind failed, IF Table Type\n"); 221 fail = true; 222 } 223 224 rc = tf_global_cfg_unbind(tfp); 225 if (rc) { 226 TFP_DRV_LOG(ERR, 227 "Device unbind failed, Global Cfg Type\n"); 228 fail = true; 229 } 230 231 if (fail) 232 return -1; 233 234 return rc; 235 } 236 237 int 238 tf_dev_bind(struct tf *tfp __rte_unused, 239 enum tf_device_type type, 240 bool shadow_copy, 241 struct tf_session_resources *resources, 242 struct tf_dev_info *dev_handle) 243 { 244 switch (type) { 245 case TF_DEVICE_TYPE_WH: 246 case TF_DEVICE_TYPE_SR: 247 dev_handle->type = type; 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 case TF_DEVICE_TYPE_SR: 266 return tf_dev_unbind_p4(tfp); 267 default: 268 TFP_DRV_LOG(ERR, 269 "No such device\n"); 270 return -ENODEV; 271 } 272 } 273