/*
 * DF-3640 — bnx(4) bnx_reset() acquires the NVRAM software-arbitration
 * lock and never releases it
 *
 * Trigger (HARDWARE REQUIRED — cannot run on the audit guest):
 *
 *   sys/dev/netif/bnx/if_bnx.c:
 *     2585:  CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1);
 *     2586:  for (i = 0; i < 8000; i++) {
 *     2587:          if (CSR_READ_4(sc, BGE_NVRAM_SWARB) &
 *                BGE_NVRAMSWARB_GNT1)
 *     2588:                  break;
 *     2589:          DELAY(20);
 *     2590:  }
 *     2591:  if (i == 8000)
 *     2592:          if_printf(..., "NVRAM lock timedout!\n");
 *
 *   ...and nowhere in if_bnx.c does BGE_NVRAMSWARB_CLR1 ever appear
 *   (grep -c NVRAMSWARB_CLR1 sys/dev/netif/bnx/if_bnx.c == 0).
 *
 *   bnx_reset() is called on every bnx_attach(), bnx_init() (ifconfig up,
 *   MTU change, watchdog reset, error recovery via bnx_handle_status) and
 *   bnx_stop().  Once granted, the host driver's NVRAM arbitration bit
 *   (SET1/GNT1) stays asserted for the lifetime of the driver — the
 *   on-chip NVRAM/flash arbiter is permanently held by the host.
 *
 *   Contrast with the code this driver was derived from:
 *     - bge(4) pairs acquire/release around every NVRAM access
 *       (sys/dev/netif/bge/if_bge.c:551-590: SET1 ... CLR1), and
 *     - upstream tg3/FreeBSD bge release the arbitration after chip
 *       reset ("Release NVRAM arbitration" in tg3_chip_reset /
 *       FreeBSD bge_reset), because the reset does NOT give back the
 *       grant.
 *   bce(4) had the same class of bug filed as DF-3605 (lock held on an
 *   error path).
 *
 *   Consequence: other agents of the NVRAM arbiter — principally the APE
 *   management firmware (NC-SI/DASH) that these chips run for
 *   out-of-band management — can never win arbitration while the host
 *   driver is loaded.  Management-plane NVRAM access (persistent
 *   configuration) breaks from boot until power cycle.  No kernel memory
 *   corruption; availability/interop impact on the management plane.
 *
 *   The audit QEMU guest has no Broadcom NIC (run.log:
 *   NO_BROADCOM_DEVICE), so bnx_reset() is unreachable there.
 */
#include <sys/types.h>
#include <stdio.h>

int
main(void)
{
	fprintf(stderr,
	    "DF-3640: requires bnx(4) hardware. On such a system, after the\n"
	    "driver loads, read BGE_NVRAM_SWARB (dev.bnx.0 regs via kgdb or\n"
	    "pciconf): the GNT1 grant bit stays set forever because bnx_reset\n"
	    "never writes BGE_NVRAMSWARB_CLR1 (grep: 0 occurrences in\n"
	    "if_bnx.c; bge releases at if_bge.c:588).\n");
	return 0;
}
