alpm_hit.c (17472B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 * 6 * File: alpm_hit.c 7 * Purpose: ALPM Distributed HITBIT (device independent implementation). 8 * Requires: 9 */ 10 11 /* Implementation notes: 12 */ 13 #include <shared/bsl.h> 14 15 #include <soc/mem.h> 16 #include <soc/drv.h> 17 #include <soc/debug.h> 18 #include <soc/error.h> 19 #include <soc/lpm.h> 20 #include <soc/trident2.h> 21 #include <soc/tomahawk.h> 22 #include <shared/bsl.h> 23 24 #include <shared/util.h> 25 #include <shared/l3.h> 26 27 #if defined(ALPM_ENABLE) 28 29 #include <bcm/l3.h> 30 31 #include <bcm_int/esw/l3.h> 32 #include <bcm_int/esw/firebolt.h> 33 #include <bcm_int/esw/alpm.h> 34 #include <bcm_int/esw/alpm_util.h> 35 36 _alpm_dist_hitbit_t *alpm_dist_hitbit[SOC_MAX_NUM_DEVICES]; 37 38 /* Find the mem Hw location in upper CB bucket (upr_bkt_node->ent_idx) 39 * for a pivot in current CB 40 */ 41 int 42 alpm_pvt_ent_idx_get(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node, 43 int *ent_idx) 44 { 45 int rv = BCM_E_NONE; 46 _bcm_defip_cfg_t lpm_cfg; 47 _alpm_pvt_node_t *upr_pvt_node = NULL; 48 _alpm_bkt_node_t *upr_bkt_node = NULL; 49 50 if (ACB_HAS_TCAM(acb)) { /* skip top CB */ 51 return BCM_E_INTERNAL; 52 } 53 54 sal_memset(&lpm_cfg, 0, sizeof(lpm_cfg)); 55 56 /* defip_flags */ 57 if (PVT_BKT_TRIE(pvt_node) && 58 PVT_BKT_TRIE(pvt_node)->v6_key) { 59 lpm_cfg.defip_flags |= BCM_L3_IP6; 60 } 61 62 /* Key & Length (lpm_cfg.user_data will be used in _alpm_find()) */ 63 alpm_trie_pfx_to_cfg(u, pvt_node->key, pvt_node->key_len, &lpm_cfg); 64 sal_memcpy(lpm_cfg.user_data, pvt_node->key, sizeof(pvt_node->key)); 65 lpm_cfg.defip_vrf = ALPM_VRF_ID_TO_VRF(u, PVT_BKT_VRF(pvt_node)); 66 67 /* Find corresponding upper CB pivot and bucket */ 68 rv = alpm_cb_find(u, ACB_UPR(u, acb), &lpm_cfg, 69 &upr_pvt_node, &upr_bkt_node); 70 71 if (BCM_SUCCESS(rv)) { 72 *ent_idx = (int)upr_bkt_node->ent_idx; 73 } 74 75 return rv; 76 } 77 78 /* 79 * Function: 80 * alpm_rte_hit_get 81 * Purpose: 82 * Get ALPM route hitbit status via hitbit cache sync with Hw 83 * and gathering pivot hitbit status whose BPM is the route. 84 * Parameters: 85 * u - Device unit #. 86 * vrf_id - VRF ID for logic hit table PID in Parallel/Mixed Mode 87 * idx - ALPM route bucket level table index 88 * ent - Route entry ID (0-15) 89 * Returns: 90 * Route hit bit (0 or 1) 91 */ 92 int 93 alpm_rte_hit_get(int u, int vrf_id, _alpm_tbl_t tbl, int idx, int ent) 94 { 95 int rv = BCM_E_UNAVAIL; 96 rv = ALPM_DRV(u)->alpm_bkt_hit_get(u, vrf_id, ACB_VRF_BTM(u, vrf_id), 97 tbl, idx, ent); 98 return rv; 99 } 100 101 /* Get bucket entry hitbit status from cached Hit table in ent_idx */ 102 int 103 alpm_bkt_hit_get(int u, int vrf_id, _alpm_cb_t *acb, _alpm_tbl_t tbl, int ent_idx) 104 { 105 int rv = BCM_E_UNAVAIL; 106 int idx, ent; 107 108 ent = ALPM_IDX_TO_ENT(ent_idx); 109 idx = ALPM_TAB_IDX_GET(ent_idx); 110 111 rv = ALPM_DRV(u)->alpm_bkt_hit_get(u, vrf_id, acb, tbl, idx, ent); 112 return rv; 113 } 114 115 /* Set ALPM route hitbit=1 via cached Hit table by idx and ent */ 116 int 117 alpm_rte_hit_set(int u, int vrf_id, _alpm_tbl_t tbl, int idx, int ent) 118 { 119 int rv = BCM_E_UNAVAIL; 120 rv = ALPM_DRV(u)->alpm_bkt_hit_set(u, vrf_id, ACB_VRF_BTM(u, vrf_id), 121 tbl, idx, ent, 1); 122 return rv; 123 } 124 125 /* Set ALPM bucket entry hitbit status to cached Hit table 126 in ent_idx with hit_val */ 127 int 128 alpm_bkt_hit_set(int u, int vrf_id, _alpm_cb_t *acb, 129 _alpm_tbl_t tbl, int ent_idx, int hit_val) 130 { 131 int rv = BCM_E_UNAVAIL; 132 int idx, ent; 133 134 ent = ALPM_IDX_TO_ENT(ent_idx); 135 idx = ALPM_TAB_IDX_GET(ent_idx); 136 137 rv = ALPM_DRV(u)->alpm_bkt_hit_set(u, vrf_id, acb, tbl, idx, ent, hit_val); 138 139 return rv; 140 } 141 142 /* Set ALPM bucket entry hitbit status to hitbit table cache 143 and write to Hw (by setting Entry Move & Mask to trigger write to Hw 144 in next Dist Hitbit thread clycle). */ 145 int 146 alpm_bkt_hit_write_hw(int u, int vrf_id, _alpm_cb_t *acb, 147 _alpm_tbl_t tbl, int ent_idx, int hit_val) 148 { 149 int rv = BCM_E_UNAVAIL; 150 rv = ALPM_DRV(u)->alpm_bkt_hit_write(u, vrf_id, acb, tbl, ent_idx, hit_val); 151 return rv; 152 } 153 154 /* Get ALPM pivot hitbit status from cached Hit table */ 155 int 156 alpm_pvt_hit_get(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node) 157 { 158 int rv = BCM_E_NONE; 159 int tcam_idx, ent_idx, vrf_id; 160 _alpm_tbl_t tbl = alpmTblInvalid; 161 162 if (ACB_HAS_TCAM(acb)) { /* TCAM pre-pivot cb=0 */ 163 int pkm, ipt = PVT_BKT_IPT(pvt_node); 164 tcam_idx = PVT_IDX(pvt_node); 165 pkm = ALPM_PKM_RECOVER(u, ipt); 166 rv = tcam_cache_hit_get(u, pkm, tcam_idx); 167 168 } else { /* Pivot cb=1 */ 169 vrf_id = PVT_BKT_VRF(pvt_node); 170 /* Get upper CB bucket ent_idx for the pivot */ 171 ALPM_IER(alpm_pvt_ent_idx_get(u, acb, pvt_node, &ent_idx)); 172 rv = alpm_bkt_hit_get(u, vrf_id, ACB_UPR(u, acb), tbl, ent_idx); 173 } 174 175 return rv; 176 } 177 178 /* ALPM pivot dist hitbit gathering to BPM route */ 179 int 180 alpm_pvt_hit_cb(int u, _alpm_cb_t *acb, 181 _alpm_pvt_node_t *pvt_node, void *user_data) 182 { 183 int rv = BCM_E_NONE; 184 int idx, ent; 185 int vrf_id = PVT_BKT_VRF(pvt_node); 186 _alpm_bkt_node_t *def_node = PVT_BKT_DEF(pvt_node); 187 _alpm_tbl_t tbl = alpmTblInvalid; 188 189 if (def_node != NULL) { /* pivot BPM route exists */ 190 ent = ALPM_IDX_TO_ENT(def_node->ent_idx); 191 idx = ALPM_TAB_IDX_GET(def_node->ent_idx); 192 193 rv = alpm_rte_hit_get(u, vrf_id, tbl, idx, ent); 194 if (rv) { /* continue if route hit=0 */ 195 return rv; 196 } 197 198 rv = alpm_pvt_hit_get(u, acb, pvt_node); 199 if (rv <= 0) { /* continue if pivot hit=1 */ 200 return rv; 201 } 202 203 /* Set route hit to 1 if BPM pivot hit=1 */ 204 rv = alpm_rte_hit_set(u, vrf_id, tbl, idx, ent); 205 } 206 207 return BCM_E_NONE; 208 } 209 210 /* Walk pivot tries and gather hitbit to BPM route */ 211 int 212 alpm_hitbit_gather(int u) 213 { 214 int i, vrf_id, ipt; 215 int rv = BCM_E_NONE; 216 _alpm_cb_t *acb; 217 218 for (i = 0; i < ACB_CNT(u); i++) { 219 acb = ACB(u, i); 220 for (vrf_id = 0; vrf_id <= ALPM_VRF_ID_MAX(u); vrf_id++) { 221 for (ipt = 0; ipt < ALPM_IPT_CNT; ipt++) { 222 if (!ACB_VRF_INITED(u, acb, vrf_id, ipt)) { 223 continue; 224 } 225 rv = bcm_esw_alpm_pvt_traverse(u, i, vrf_id, ipt, 226 alpm_pvt_hit_cb, NULL); 227 } 228 } 229 } 230 231 return rv; 232 } 233 234 /* Sync ALPM non-TCAM level (i:0/1 for level 2/3) hitbit cache with Hw */ 235 int 236 alpm_hitbit_sync_cache(int u, int i, int pid) 237 { 238 int rv = BCM_E_UNAVAIL; 239 rv = ALPM_DRV(u)->alpm_hit_cache_sync(u, i, pid); 240 241 return rv; 242 } 243 244 /* Write ALPM non-TCAM level (i:0/1 for level 2/3) hitbit cache to Hw */ 245 int 246 alpm_hitbit_write_hw(int u, int i, int pid) 247 { 248 int rv = BCM_E_UNAVAIL; 249 rv = ALPM_DRV(u)->alpm_hit_hw_write(u, i, pid); 250 251 return rv; 252 } 253 254 /* Update hitbit for entry move on level i by 255 * hit_cache = (hit_cache & ~hit_move_mask) | (hit_move & hit_move_mask) 256 */ 257 int 258 alpm_hitbit_ent_move_update(int u, int i, int pid) 259 { 260 int rv = BCM_E_UNAVAIL; 261 rv = ALPM_DRV(u)->alpm_hit_move_update(u, i, pid); 262 263 return rv; 264 } 265 266 /* Reset hitbit ent move, move mask and moved flag 267 * for next cycle of dist hitbit thread 268 */ 269 int 270 alpm_hitbit_ent_move_reset(int u, int i, int pid) 271 { 272 int alloc_sz = ALPM_HTBL_SIZE(u, i, pid); 273 274 sal_memset(ALPM_HTBL_MOVE(u, i, pid), 0, alloc_sz); 275 sal_memset(ALPM_HTBL_MOVE_MASK(u, i, pid), 0, alloc_sz); 276 277 ALPM_HTBL_ENT_MOVED(u, i, pid) = FALSE; 278 ALPM_HTBL_ENT_MOVED_CNT(u, i, pid) = 0; 279 return BCM_E_NONE; 280 } 281 282 /* Get TCAM hitbit status from a TCAM entry */ 283 int 284 tcam_entry_hit_get(int u, int pkm, void *e, int sub_idx) 285 { 286 int rv = BCM_E_UNAVAIL; 287 288 rv = ALPM_DRV(u)->tcam_entry_hit_get(u, pkm, e, sub_idx); 289 290 return rv; 291 } 292 293 /* Get TCAM cached entry hitbit status from pivot's tcam_idx */ 294 int 295 tcam_cache_hit_get(int u, int pkm, int tcam_idx) 296 { 297 int rv = BCM_E_UNAVAIL; 298 299 rv = ALPM_DRV(u)->tcam_cache_hit_get(u, pkm, tcam_idx); 300 301 return rv; 302 } 303 304 /* Sync TCAM hitbit cache with Hw */ 305 int 306 tcam_hitbit_sync_cache(int u) 307 { 308 int rv = BCM_E_UNAVAIL; 309 310 rv = ALPM_DRV(u)->tcam_hit_cache_sync(u); 311 312 return rv; 313 } 314 315 /* 316 * Function: 317 * bcm_esw_alpm_clear_hit 318 * Purpose: 319 * Clear ALPM route hit bit from found lpm_cfg->bkt_node->ent_idx. 320 * Parameters: 321 * u - (IN)SOC unit number. 322 * lpm_cfg - (IN)Found lpm defip_cfg info 323 * Returns: 324 * BCM_E_XXX 325 */ 326 int 327 bcm_esw_alpm_clear_hit(int u, _bcm_defip_cfg_t *lpm_cfg) 328 { 329 int rv = BCM_E_NONE; 330 331 _alpm_pvt_node_t *pvt_node = (_alpm_pvt_node_t *)lpm_cfg->pvt_node; 332 _alpm_bkt_node_t *bkt_node = (_alpm_bkt_node_t *)lpm_cfg->bkt_node; 333 _alpm_cb_t *acb; 334 int vrf_id; 335 _alpm_tbl_t tbl; 336 337 vrf_id = PVT_BKT_VRF(pvt_node); 338 acb = ACB_VRF_BTM(u, vrf_id); 339 tbl = BPC_BKT_TBL(ACB_BKT_VRF_POOL(acb, vrf_id)); 340 341 if (ALPM_HIT_SKIP(u)) { 342 return rv; 343 } 344 345 if (pvt_node && bkt_node) { 346 rv = alpm_bkt_hit_write_hw(u, vrf_id, acb, tbl, bkt_node->ent_idx, 0); 347 } else { 348 rv = BCM_E_NOT_FOUND; 349 } 350 351 return rv; 352 } 353 354 /* 355 * Function: 356 * alpm_dist_hitbit_thread 357 * Purpose: 358 * ALPM distributed hitbit thread running periodically 359 * to sync hitbit cache with Hw, gathering pivot hitbit status 360 * to BPM route, and write hitbit entry move to Hw. 361 * Parameters: 362 * u - Device unit #. 363 * Returns: 364 * Nothing 365 */ 366 STATIC void 367 alpm_dist_hitbit_thread(int u) 368 { 369 int i, pid; 370 _alpm_cb_t *acb; 371 sal_usecs_t t0, t1, t2, t3, t4, t5; 372 373 ALPM_INFO(("thread starting on unit %d\n", u)); 374 ALPMDH(u)->thread = sal_thread_self(); 375 376 while (ALPMDH(u)->interval != 0) { 377 ALPM_HIT_LOCK(u); 378 t0 = sal_time_usecs(); 379 if (soc_feature(u, soc_feature_distributed_hit_bits)) { 380 /* Sync TCAM hitbit cache with Hw */ 381 tcam_hitbit_sync_cache(u); 382 } 383 384 t1 = sal_time_usecs(); 385 /* Sync Bucket level hitbit caches with Hw */ 386 for (i = 0; i < ACB_CNT(u); i++) { 387 acb = ACB(u, i); 388 for (pid = 0; pid < ACB_PID_CNT(acb); pid++) { 389 alpm_hitbit_sync_cache(u, i, pid); 390 } 391 } 392 393 t2 = sal_time_usecs(); 394 /* Entry move hitbits handling for bucket levels. 395 TCAM entry move writes hitbit in combined view 396 directly to cache/Hw by soc_mem_write() */ 397 for (i = 0; i < ACB_CNT(u); i++) { 398 acb = ACB(u, i); 399 for (pid = 0; pid < ACB_PID_CNT(acb); pid++) { 400 alpm_hitbit_ent_move_update(u, i, pid); 401 } 402 } 403 404 t3 = sal_time_usecs(); 405 if (soc_feature(u, soc_feature_distributed_hit_bits)) { 406 alpm_hitbit_gather(u); 407 } 408 t4 = sal_time_usecs(); 409 /* Wtite to Hw if moved and reset ent move and move mask */ 410 for (i = 0; i < ACB_CNT(u); i++) { 411 acb = ACB(u, i); 412 for (pid = 0; pid < ACB_PID_CNT(acb); pid++) { 413 if (ALPM_HTBL_ENT_MOVED(u, i, pid)) { 414 if (ALPMC(u)->_alpm_dbg_info_bmp & _ALPM_DBG_INFO_HIT) { 415 LOG_CLI(("Writes to L%d PID %d hit table: %d (entries)\n", 416 i+2, pid, ALPM_HTBL_ENT_MOVED_CNT(u, i, pid))); 417 } 418 t5 = sal_time_usecs(); 419 alpm_hitbit_write_hw(u, i, pid); 420 if (ALPMC(u)->_alpm_dbg_info_bmp & _ALPM_DBG_INFO_HIT) { 421 LOG_CLI(("Hit table L%d PID %d write latency: %u (us).\n", i+2, pid, 422 sal_time_usecs() - t5)); 423 } 424 } 425 alpm_hitbit_ent_move_reset(u, i, pid); 426 } 427 } 428 429 if (ALPMC(u)->_alpm_dbg_info_bmp & _ALPM_DBG_INFO_HIT) { 430 t5 = sal_time_usecs(); 431 ALPM_INFO(("\nTime: %lu (sec), latency: %d %d %d %d %d (us)\n", 432 sal_time(), t1-t0, t2-t1, t3-t2, t4-t3, t5-t4)); 433 } 434 ALPM_HIT_UNLOCK(u); 435 /* wait for next cycle after interval time */ 436 (void)sal_sem_take(ALPMDH(u)->sema, ALPMDH(u)->interval); 437 } 438 439 ALPM_INFO(("thread exiting on unit %d\n", u)); 440 441 ALPMDH(u)->thread = NULL; 442 sal_thread_exit(0); 443 } 444 445 /* 446 * Function: 447 * alpm_dist_hitbit_enable_set 448 * Purpose: 449 * Enable or disable the ALPM distributed hitbits 450 * background thread feature. 451 * Parameters: 452 * u - Device unit #. 453 * us - Specifies the software polling interval in micro-seconds; 454 * the value 0 disables Dist hitbits thread. 455 * Returns: 456 * BCM_E_XXX 457 */ 458 459 int 460 alpm_dist_hitbit_enable_set(int u, int us) 461 { 462 int rv = BCM_E_NONE; 463 soc_timeout_t to; 464 sal_usecs_t wait_usec; 465 466 /* Time to wait for thread to start/end (longer for BCMSIM) */ 467 wait_usec = (SAL_BOOT_BCMSIM || SAL_BOOT_QUICKTURN) ? 30000000 : 10000000; 468 469 if (ALPMDH(u) == NULL) { /* No error to disable if not inited */ 470 return(BCM_E_NONE); 471 } 472 473 sal_snprintf(ALPMDH(u)->taskname, sizeof(ALPMDH(u)->taskname), 474 "bcmALPMDH.%d", u); 475 476 if (us) { 477 ALPMDH(u)->interval = us; 478 479 if (ALPMDH(u)->thread != NULL) { 480 /* Dist hit thread is already running; just update the period */ 481 sal_sem_give(ALPMDH(u)->sema); 482 return BCM_E_NONE; 483 } 484 485 if (sal_thread_create(ALPMDH(u)->taskname, 486 SAL_THREAD_STKSZ, 487 ALPMDH(u)->priority, 488 (void (*)(void*))alpm_dist_hitbit_thread, 489 INT_TO_PTR(u)) == SAL_THREAD_ERROR) { 490 ALPM_ERR(("%s: Thread create error\n", ALPMDH(u)->taskname)); 491 ALPMDH(u)->interval = 0; 492 rv = BCM_E_MEMORY; 493 } else { 494 soc_timeout_init(&to, wait_usec, 0); 495 496 while (ALPMDH(u)->thread == NULL) { 497 if (soc_timeout_check(&to)) { 498 ALPM_ERR(("%s: Thread did not start\n", 499 ALPMDH(u)->taskname)); 500 ALPMDH(u)->interval = 0; 501 rv = BCM_E_INTERNAL; 502 break; 503 } 504 } 505 506 if (BCM_SUCCESS(rv)) { 507 LOG_CLI(("ALPM Distributed HITBIT thread enabled (interval %d us)\n", us)); 508 } 509 } 510 } else if (ALPMDH(u)->thread != NULL) { 511 ALPMDH(u)->interval = 0; 512 513 sal_sem_give(ALPMDH(u)->sema); 514 soc_timeout_init(&to, 5 * wait_usec, 0); 515 516 while (ALPMDH(u)->thread != NULL) { 517 if (soc_timeout_check(&to)) { 518 ALPM_ERR(("%s: Thread did not exit\n", ALPMDH(u)->taskname)); 519 rv = BCM_E_INTERNAL; 520 break; 521 } 522 } 523 524 if (BCM_SUCCESS(rv)) { 525 LOG_CLI(("ALPM Distributed HITBIT thread disabled\n")); 526 } 527 } 528 529 return rv; 530 } 531 532 int 533 alpm_dist_hitbit_interval_get(int u) 534 { 535 if (ALPMDH(u)) { 536 return ALPMDH(u)->interval; 537 } else { 538 return 0; 539 } 540 } 541 542 /* Deinit ALPM distributed hitbit */ 543 int 544 bcm_esw_alpm_hit_deinit(int u) 545 { 546 int rv = BCM_E_NONE; 547 548 if (ALPM_HIT_SKIP(u)) { 549 return rv; 550 } 551 552 if (ALPMDH(u) != NULL) { 553 ALPM_INFO(("ALPM distributed hitbits thread end\n")); 554 rv = alpm_dist_hitbit_enable_set(u, 0); 555 556 if (ALPMDH(u)->sema != NULL) { 557 sal_sem_destroy(ALPMDH(u)->sema); 558 ALPMDH(u)->sema = NULL; 559 } 560 561 ALPM_DRV(u)->alpm_hit_deinit(u); 562 563 alpm_util_free(ALPMDH(u)); 564 ALPMDH(u) = NULL; 565 } 566 567 return rv; 568 } 569 570 /* Initialize ALPM distributed hitbit */ 571 int 572 bcm_esw_alpm_hit_init(int u) 573 { 574 int rv = BCM_E_NONE; 575 sal_usecs_t usec, def; 576 577 if (ALPM_HIT_SKIP(u)) { 578 return rv; 579 } 580 581 if (ALPMDH(u) != NULL) { 582 bcm_esw_alpm_hit_deinit(u); 583 } 584 585 ALPM_ALLOC_EG(ALPMDH(u), sizeof(_alpm_dist_hitbit_t), "ALPMDH"); 586 587 ALPM_IEG(ALPM_DRV(u)->alpm_hit_init(u)); 588 589 /* Initialize ALPM dist hitbit thread */ 590 591 def = (SAL_BOOT_BCMSIM || SAL_BOOT_QUICKTURN) ? 30000000 : ALPM_HIT_INTERVAL_DEF; 592 usec = soc_property_get(u, "alpm_dist_hit_interval_us", def); 593 /* Set usec=0 to disable thread */ 594 if ((usec < ALPM_HIT_INTERVAL_MIN) && (usec > 0)) { 595 usec = ALPM_HIT_INTERVAL_MIN; 596 } 597 if (usec > ALPM_HIT_INTERVAL_MAX) { 598 usec = ALPM_HIT_INTERVAL_MAX; 599 } 600 ALPMDH(u)->priority = soc_property_get(u, "alpm_dist_hit_priority", 601 ALPM_HIT_PRIORITY_DEF); 602 ALPMDH(u)->sema = sal_sem_create("bcmHit_SLEEP", sal_sem_BINARY, 0); 603 if (ALPMDH(u)->sema == NULL) { 604 ALPM_IEG(BCM_E_MEMORY); 605 } 606 607 ALPM_IEG(alpm_dist_hitbit_enable_set(u, usec)); 608 609 return rv; 610 611 bad: 612 bcm_esw_alpm_hit_deinit(u); 613 return rv; 614 } 615 616 /* 617 * Function: 618 * alpm_dist_hitbit_thread_stop 619 * Purpose: 620 * Stop the ALPM distributed hitbits thread 621 * Parameters: 622 * u - Device unit #. 623 * Returns: 624 * BCM_E_XXX 625 */ 626 int 627 alpm_dist_hitbit_thread_stop(int unit) 628 { 629 int rv = BCM_E_NONE; 630 if (ALPMC(unit) && !ALPM_HIT_SKIP(unit)) { 631 rv = alpm_dist_hitbit_enable_set(unit, 0); 632 } 633 return rv; 634 } 635 636 #endif /* ALPM_ENABLE */ 637