preemption_cnt.c (11817B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 */ 7 #include <shared/bsl.h> 8 #include <soc/drv.h> 9 #include <bcm/port.h> 10 #include <bcm/error.h> 11 #include <bcm/types.h> 12 #include <bcm_int/esw/preemption_cnt.h> 13 #if defined(BCM_GREYHOUND2_SUPPORT) 14 #include <bcm_int/esw/greyhound2.h> 15 #endif 16 17 #if defined(BCM_PREEMPTION_SUPPORT) 18 /* preemption counter control data for each device */ 19 typedef struct bcmi_preemption_counter_control_s { 20 sal_mutex_t counter_mutex; 21 bcmi_preemption_counte_func_t dev_func; 22 } bcmi_preemption_counter_control_t; 23 STATIC bcmi_preemption_counter_control_t *preemption_counter_control 24 [SOC_MAX_NUM_DEVICES]; 25 26 /* lock/uplock helper function */ 27 #define PREEMPTION_COUNTER_LOCK(_pc_) \ 28 sal_mutex_take((_pc_)->counter_mutex, sal_mutex_FOREVER); 29 #define PREEMPTION_COUNTER_UNLOCK(_pc_) \ 30 sal_mutex_give((_pc_)->counter_mutex); 31 32 /* 33 * Function: 34 * bcmi_esw_preemption_counter_multi_get32 35 * Purpose: 36 * Get 32-bit counter value for multiple port statistic types. 37 * Parameters: 38 * unit - (IN) Unit number. 39 * sync_mode - (IN) hwcount is to be synced to sw count 40 * local_port - (IN) GPORT ID 41 * nstat - (IN) Number of elements in stat array 42 * stat_arr - (IN) New statistics descriptors array 43 * value_arr - (OUT)New counters values 44 * Returns: 45 * BCM_E_XXX 46 * Notes: 47 */ 48 int 49 bcmi_esw_preemption_counter_multi_get32(int unit, int sync_mode, 50 bcm_port_t local_port, int nstat, 51 bcm_port_stat_t *stat_arr, 52 uint32 *value_arr) 53 { 54 int i; 55 56 if (NULL == stat_arr || NULL == value_arr) { 57 return BCM_E_PARAM; 58 } 59 for (i = 0; i < nstat; i++) { 60 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_get32(unit, sync_mode, 61 local_port, 62 stat_arr[i], 63 &(value_arr[i]))); 64 } 65 return BCM_E_NONE; 66 } 67 68 /* 69 * Function: 70 * bcmi_esw_preemption_counter_multi_set32 71 * Purpose: 72 * Set 32-bit counter value for multiple port statistic types. 73 * Parameters: 74 * unit - (IN) Unit number. 75 * local_port - (IN) GPORT ID 76 * nstat - (IN) Number of elements in stat array 77 * stat_arr - (IN) New statistics descriptors array 78 * value_arr - (IN) New counters values 79 * Returns: 80 * BCM_E_XXX 81 * Notes: 82 */ 83 int 84 bcmi_esw_preemption_counter_multi_set32(int unit, 85 bcm_port_t local_port, int nstat, 86 bcm_port_stat_t *stat_arr, 87 uint32 *value_arr) 88 { 89 int i; 90 91 if (NULL == stat_arr || NULL == value_arr) { 92 return BCM_E_PARAM; 93 } 94 for (i = 0; i < nstat; i++) { 95 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_set32(unit, 96 local_port, 97 stat_arr[i], 98 value_arr[i])); 99 } 100 return BCM_E_NONE; 101 } 102 103 /* 104 * Function: 105 * bcmi_esw_preemption_counter_multi_get 106 * Purpose: 107 * Get 64-bit counter value for multiple port statistic types. 108 * Parameters: 109 * unit - (IN) Unit number. 110 * sync_mode - (IN) hwcount is to be synced to sw count 111 * local_port - (IN) GPORT ID 112 * nstat - (IN) Number of elements in stat array 113 * stat_arr - (IN) New statistics descriptors array 114 * value_arr - (OUT)New counters values 115 * Returns: 116 * BCM_E_XXX 117 * Notes: 118 */ 119 int 120 bcmi_esw_preemption_counter_multi_get(int unit, int sync_mode, 121 bcm_port_t local_port, int nstat, 122 bcm_port_stat_t *stat_arr, 123 uint64 *value_arr) 124 { 125 int i; 126 127 if (NULL == stat_arr || NULL == value_arr) { 128 return BCM_E_PARAM; 129 } 130 for (i = 0; i < nstat; i++) { 131 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_get(unit, sync_mode, 132 local_port, 133 stat_arr[i], 134 &(value_arr[i]))); 135 } 136 return BCM_E_NONE; 137 } 138 139 /* 140 * Function: 141 * bcmi_esw_preemption_counter_multi_set 142 * Purpose: 143 * Set 64-bit counter value for multiple port statistic types. 144 * Parameters: 145 * unit - (IN) Unit number. 146 * local_port - (IN) GPORT ID 147 * nstat - (IN) Number of elements in stat array 148 * stat_arr - (IN) New statistics descriptors array 149 * value_arr - (IN) New counters values 150 * Returns: 151 * BCM_E_XXX 152 * Notes: 153 */ 154 int 155 bcmi_esw_preemption_counter_multi_set(int unit, 156 bcm_port_t local_port, int nstat, 157 bcm_port_stat_t *stat_arr, 158 uint64 *value_arr) 159 { 160 int i; 161 162 if (NULL == stat_arr || NULL == value_arr) { 163 return BCM_E_PARAM; 164 } 165 for (i = 0; i < nstat; i++) { 166 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_set(unit, 167 local_port, 168 stat_arr[i], 169 value_arr[i])); 170 } 171 return BCM_E_NONE; 172 } 173 174 /* 175 * Function: 176 * bcmi_esw_preemption_counter_get32 177 * Purpose: 178 * Get lower 32-bit counter value for specified port statistic 179 * type. 180 * if sync_mode is set, sync the sw accumulated count 181 * with hw count value first, else return sw count. 182 * Parameters: 183 * unit - (IN) Unit number. 184 * sync_mode - (IN) hwcount is to be synced to sw count 185 * local_port - (IN) GPORT ID 186 * stat - (IN) Type of the counter to retrieve. 187 * val - (OUT) Pointer to a counter value. 188 * Returns: 189 * BCM_E_XXX 190 * Notes: 191 */ 192 int 193 bcmi_esw_preemption_counter_get32(int unit, int sync_mode, bcm_port_t local_port, 194 bcm_port_stat_t stat, uint32 *val) 195 { 196 uint64 val64; 197 198 if (NULL == val) { 199 return BCM_E_PARAM; 200 } 201 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_get(unit, sync_mode, 202 local_port, 203 stat, &val64)); 204 *val = COMPILER_64_LO(val64); 205 return BCM_E_NONE; 206 } 207 208 /* 209 * Function: 210 * bcmi_esw_preemption_counter_set32 211 * Purpose: 212 * Set lower 32-bit counter value for specified port statistic 213 * type. 214 * Parameters: 215 * unit - (IN) Unit number. 216 * local_port - (IN) GPORT ID 217 * stat - (IN) Type of the counter to retrieve. 218 * val - (OUT) Pointer to a counter value. 219 * Returns: 220 * BCM_E_XXX 221 * Notes: 222 */ 223 int 224 bcmi_esw_preemption_counter_set32(int unit, bcm_port_t local_port, 225 bcm_port_stat_t stat, uint32 val) 226 { 227 uint64 val64; 228 229 COMPILER_64_SET(val64, 0, val); 230 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_set(unit, local_port, 231 stat, val64)); 232 return BCM_E_NONE; 233 } 234 235 /* 236 * Function: 237 * bcmi_esw_preemption_counter_get 238 * Purpose: 239 * Get 64-bit counter value for specified port statistic type. 240 * if sync_mode is set, sync the sw accumulated count 241 * with hw count value first, else return sw count. 242 * Parameters: 243 * unit - (IN) Unit number. 244 * sync_mode - (IN) hwcount is to be synced to sw count 245 * local_port - (IN) GPORT ID 246 * stat - (IN) Type of the counter to retrieve. 247 * val - (OUT) Pointer to a counter value. 248 * Returns: 249 * BCM_E_XXX 250 * Notes: 251 */ 252 int 253 bcmi_esw_preemption_counter_get(int unit, int sync_mode, bcm_port_t local_port, 254 bcm_port_stat_t stat, uint64 *val) 255 { 256 bcmi_preemption_counter_control_t *pc = preemption_counter_control[unit]; 257 int rv; 258 259 if (NULL == pc) { 260 return BCM_E_INIT; 261 } 262 263 PREEMPTION_COUNTER_LOCK(pc); 264 rv = pc->dev_func.preemption_counter_get(unit, sync_mode, local_port, 265 stat, val); 266 PREEMPTION_COUNTER_UNLOCK(pc); 267 268 return rv; 269 } 270 271 /* 272 * Function: 273 * bcmi_esw_preemption_counter_set32 274 * Purpose: 275 * Set 64-bit counter value for specified port statistic type. 276 * Parameters: 277 * unit - (IN) Unit number. 278 * local_port - (IN) GPORT ID 279 * stat - (IN) Type of the counter to retrieve. 280 * val - (OUT) Pointer to a counter value. 281 * Returns: 282 * BCM_E_XXX 283 * Notes: 284 */ 285 int 286 bcmi_esw_preemption_counter_set(int unit, bcm_port_t local_port, 287 bcm_port_stat_t stat, uint64 val) 288 { 289 bcmi_preemption_counter_control_t *pc = preemption_counter_control[unit]; 290 int rv; 291 292 if (NULL == pc) { 293 return BCM_E_INIT; 294 } 295 296 PREEMPTION_COUNTER_LOCK(pc); 297 rv = pc->dev_func.preemption_counter_set(unit, local_port, stat, val); 298 PREEMPTION_COUNTER_UNLOCK(pc); 299 300 return rv; 301 } 302 303 /* 304 * Function: 305 * bcmi_esw_preemption_counter_cleanup 306 * Purpose: 307 * cleanup resource after detach 308 * Parameters: 309 * unit - (IN) Unit number. 310 * Returns: 311 * BCM_E_XXX 312 * Notes: 313 */ 314 int 315 bcmi_esw_preemption_counter_cleanup(int unit) 316 { 317 if (NULL != preemption_counter_control[unit]) { 318 preemption_counter_control[unit]->dev_func.preemption_counter_clean(unit); 319 if (NULL != preemption_counter_control[unit]->counter_mutex) { 320 sal_mutex_destroy(preemption_counter_control[unit]->counter_mutex); 321 preemption_counter_control[unit]->counter_mutex = NULL; 322 } 323 sal_free(preemption_counter_control[unit]); 324 preemption_counter_control[unit] = NULL; 325 } 326 return BCM_E_NONE; 327 } 328 329 /* 330 * Function: 331 * bcmi_esw_preemption_counter_init 332 * Purpose: 333 * init premption counter module 334 * Parameters: 335 * unit - (IN) Unit number. 336 * Returns: 337 * BCM_E_XXX 338 * Notes: 339 */ 340 int 341 bcmi_esw_preemption_counter_init(int unit) 342 { 343 bcmi_preemption_counter_control_t *pc = NULL; 344 int rv; 345 346 if (NULL != preemption_counter_control[unit]) { 347 bcmi_esw_preemption_counter_cleanup(unit); 348 } 349 preemption_counter_control[unit] = 350 sal_alloc(sizeof(bcmi_preemption_counter_control_t), 351 "preemption counter control"); 352 pc = preemption_counter_control[unit]; 353 if (NULL == pc) { 354 return BCM_E_MEMORY; 355 } 356 sal_memset(pc, 0, sizeof(bcmi_preemption_counter_control_t)); 357 pc->counter_mutex = sal_mutex_create("counter_mutex"); 358 if (NULL == pc->counter_mutex) { 359 bcmi_esw_preemption_counter_cleanup(unit); 360 return BCM_E_INTERNAL; 361 } 362 363 /* init chip-specific func */ 364 rv = BCM_E_UNAVAIL; 365 #if defined(BCM_GREYHOUND2_SUPPORT) 366 if (SOC_IS_GREYHOUND2(unit)) { 367 rv = bcmi_gh2_preemption_counter_dev_func_init(&(pc->dev_func)); 368 } 369 #endif 370 if (BCM_FAILURE(rv)) { 371 bcmi_esw_preemption_counter_cleanup(unit); 372 return rv; 373 } 374 375 rv = pc->dev_func.preemption_counter_init(unit); 376 if (BCM_FAILURE(rv)) { 377 bcmi_esw_preemption_counter_cleanup(unit); 378 return rv; 379 } 380 381 return BCM_E_NONE; 382 } 383 #endif /* BCM_PREEMPTION_SUPPORT */