Beispiel #1
0
/*
 * Print FIRs only if they have changed. Always collect them.
 */
static int afu_check_mfirs(struct mdev_ctx *mctx)
{
	int i;
	uint64_t data;
	uint32_t offs;
	bool changed = false;
	bool dead = false;
	long cr_device = 0;
	time_t t;
	int rc;

	for (i = 0; i < MMIO_FIR_REGS_NUM; i++) {
		offs = MMIO_FIR_REGS_BASE + i * 8;
		mmio_read(mctx->afu_h, MMIO_MASTER_CTX_NUMBER, offs, &data);
		if (data != mctx->fir[i])
			changed = true;
		if (data == -1ull)
			dead = true;

		mctx->fir[i] = data;
	}
	if (changed) {
		t = time(NULL);
		VERBOSE0("%s", ctime(&t));

		/* Always print this ... */
		cxl_get_cr_device(mctx->afu_h, 0, &cr_device);
		VERBOSE0("  cr_device: 0x%04lx\n", (unsigned long)cr_device);

		if (mctx->errinfo) {
			rc = cxl_errinfo_read(mctx->afu_h, mctx->errinfo, 0,
					      mctx->errinfo_size);
			if (rc != (int)mctx->errinfo_size) {
				VERBOSE0("  cxl_err_info_read returned %d!\n",
					 rc);
			}
			afu_dump_mfirs(mctx);
		}

		if (dead) {
			t = time(NULL);
			VERBOSE0("%s  AFU[%d] card is dead.\n",
				 ctime(&t), mctx->card);
		}
	}

	return mctx->dt;
}
Beispiel #2
0
/*
 * Q.2931:Reset-Start 1/2
 */
static void
start_t316(struct uni *uni)
{
	if (uni->glob_start != UNI_CALLSTATE_REST1) {
		VERBOSE0(uni, UNI_FAC_ERR, "T316 in state %d",
		    uni->glob_start);
		return;
	}

	if (++uni->cnt316 == uni->init316) {
		struct uni_msg *app;
		struct uniapi_reset_error_indication *resp;

		VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start error");

		resp = ALLOC_API(struct uniapi_reset_error_indication, app);
		if (resp != NULL) {
			resp->source = 0;
			resp->reason = UNIAPI_RESET_ERROR_NO_RESPONSE,

			uni->funcs->uni_output(uni, uni->arg,
			    UNIAPI_RESET_ERROR_indication, 0, app);
		}

		uni->glob_start = UNI_CALLSTATE_REST0;
		VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start state := 0");
	} else {
Beispiel #3
0
static void afu_dump_mfirs(struct mdev_ctx *mctx)
{
	unsigned int i;
	struct cgzip_afu_fir *fir;

	if (verbose > 3) {
		ddcb_hexdump(fd_out, mctx->errinfo, mctx->errinfo_size);
		return;
	}

	for (i = 0, fir = (struct cgzip_afu_fir *)mctx->errinfo;
	     i < MMIO_FIR_REGS_NUM; i++) {

		VERBOSE0("  AFU[%d] FIR: %d: 0x%08x addr: 0x%08x "
			 "mmio: 0x%016llx\n",
			 mctx->card, i,
			 be32toh(fir[i].fir_val),
			 be32toh(fir[i].fir_addr),
			 (long long)mctx->fir[i]);
	}
}
Beispiel #4
0
static int afu_check_stime(struct mdev_ctx *mctx)
{
	int	gsel, bsel = 0, ctx = 0;
	uint64_t gmask = 0, qstat_reg, err_reg, mstat_reg;
	uint64_t wtime;
	uint64_t cid_reg;
	int	n_act = 0;
	uint64_t s_time = 0;
	char s[32];

	for (gsel = 0; gsel < MMIO_CASV_REG_NUM; gsel++) {
		mmio_read(mctx->afu_h, MMIO_MASTER_CTX_NUMBER,
			MMIO_CASV_REG + (gsel*8), &gmask);
		if (0 == gmask)
			continue;	/* No bit set, Skip */

		for (bsel = 0; bsel < MMIO_CASV_REG_CTX; bsel++) {
			if (0 == (gmask & (1ull << bsel)))
				continue;	/* Skip */

			ctx = (gsel * MMIO_CASV_REG_CTX) + bsel;	/* Active */

			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_STATUS_REG, &qstat_reg);
			if (0 == (qstat_reg & 0xffffffff00000000ull)) {
				VERBOSE3("AFU[%d:%03d] master skip\n",
					mctx->card, ctx);
				continue;	/* Skip Master */
			}
			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_WT_REG, &wtime);
			wtime = wtime / 250; /* makes time in usec */

			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_CID_REG, &cid_reg);
			uint16_t cur_cid = (uint16_t)(cid_reg >> 16);	/* Currect Context id */
			uint16_t my_cid = (uint16_t)(cid_reg & 0xffff);	/* My Context id */

			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_DMAE_REG, &err_reg);

			uint16_t cseq = (uint16_t)(qstat_reg >> 48ull);	/* Currect sequence */
			uint16_t lseq = (uint16_t)(qstat_reg >> 32ull);	/* Last sequence */
			uint8_t qidx = (uint8_t)(qstat_reg >> 24);	/* Q Index */
			uint16_t qnfe = (uint16_t)(qstat_reg >> 8);	/* Context Non Fatal Error Bits */
			uint8_t qstat = (uint8_t)(qstat_reg & 0xff);	/* Context Status */

			/* Generate W for Waiting, I for Idle and R for Running */
			char flag = 'W';		/* Default Context is Waiting to get executed */
			if ((lseq + 1 ) == cseq)
				flag = 'I';		/* Context is Idle, nothing to do */
			else if (0x30 == qstat)		/* if Bits 4 + 5 on ? */
					flag = 'R';	/* Context is Running */

			if (qnfe) {
				VERBOSE0("AFU[%d:%03d] ERR: CurrentCtx: %03d MyCtx: %03d CS: %04X LS: %04X ",
					mctx->card, ctx, cur_cid, my_cid, cseq, lseq);
				VERBOSE0("[%c] IDX: %02d QNFE: %04x QSTAT: %02x Time: %lld usec",
					flag, qidx, qnfe, qstat, (long long)wtime);
				if (0 != err_reg)
					VERBOSE0("DMA Err: 0x%016llx", (long long)err_reg);
				VERBOSE0("\n");
			} else {
				VERBOSE0("AFU[%d:%03d] CurrentCtx: %03d MyCtx: %03d CS: %04X LS: %04X ",
					mctx->card, ctx, cur_cid, my_cid, cseq, lseq);
				VERBOSE0("[%c] IDX: %02d QNFE: %04x QSTAT: %02x Time: %lld usec",
					flag, qidx, qnfe, qstat, (long long)wtime);
				if (0 != err_reg)
					VERBOSE0("DMA Err: 0x%016llx", (long long)err_reg);
				VERBOSE0("\n");
			}
			n_act++;
			s_time += wtime;
		}
	}
	if (n_act) {
		time_t result = time(NULL);
		struct tm * p = localtime(&result);
		strftime(s, 32, "%T", p);

		VERBOSE0("AFU[%d:XXX] at %s Running %d Active Contexts total %lld msec",
			 mctx->card,  s, n_act, (long long)s_time/1000);
		mmio_read(mctx->afu_h, MMIO_MASTER_CTX_NUMBER,
			MMIO_AFU_STATUS_REG, &mstat_reg);
		if (0 != mstat_reg)
			VERBOSE0(" Status: 0x%016llx", (long long)mstat_reg);
		VERBOSE0("\n");
	}
	return mctx->dt;
}
Beispiel #5
0
/*
 * Open AFU Master Device
 */
static int afu_m_open(struct mdev_ctx *mctx)
{
	int rc = 0;
	char device[64];
	long api_version, cr_device, cr_vendor;

	sprintf(device, "/dev/cxl/afu%d.0m", mctx->card);
	VERBOSE3("[%s] Enter, Open Device: %s\n", __func__, device);
	mctx->afu_h = cxl_afu_open_dev(device);
	if (NULL == mctx->afu_h) {
		VERBOSE0("[%s] Exit, Card Open error rc: %d\n", __func__, rc);
		return -1;
	}

	/* Check if the compiled in API version is compatible with the
	   one reported by the kernel driver */
	rc = cxl_get_api_version_compatible(mctx->afu_h, &api_version);
	if ((rc != 0) || (api_version != CXL_KERNEL_API_VERSION)) {
		VERBOSE0(" [%s] ERR: incompatible API version: %ld/%d rc=%d\n",
			 __func__, api_version, CXL_KERNEL_API_VERSION, rc);
		rc = -2;
		goto err_afu_free;
	}

	/* Check vendor id */
	rc = cxl_get_cr_vendor(mctx->afu_h, 0, &cr_vendor);
	if ((rc != 0) || (cr_vendor != CGZIP_CR_VENDOR)) {
		VERBOSE0(" [%s] ERR: vendor_id: %ld/%d rc=%d\n",
			 __func__, (unsigned long)cr_vendor,
			 CGZIP_CR_VENDOR, rc);
		rc = -3;
		goto err_afu_free;
	}

	/* Check device id */
	rc = cxl_get_cr_device(mctx->afu_h, 0, &cr_device);
	if ((rc != 0) || (cr_device != CGZIP_CR_DEVICE)) {
		VERBOSE0(" [%s] ERR: device_id: %ld/%d rc=%d\n",
			 __func__, (unsigned long)cr_device,
			 CGZIP_CR_VENDOR, rc);
		rc = -4;
		goto err_afu_free;
	}

	/* If we cannot get it, continue with warning ... */
	mctx->errinfo = NULL;
	rc = cxl_errinfo_size(mctx->afu_h, &mctx->errinfo_size);
	if (0 == rc) {
		mctx->errinfo = malloc(mctx->errinfo_size);
		if (mctx->errinfo == NULL) {
			rc = -5;
			goto err_afu_free;
		}
	} else
		VERBOSE0(" [%s] WARN: Cannot retrieve errinfo size rc=%d\n",
			 __func__, rc);

	rc = cxl_afu_attach(mctx->afu_h, (__u64)(unsigned long)
			    (void *)mctx->wed);
	if (0 != rc) {
		rc = -6;
		goto err_free_errinfo;
	}

	rc = cxl_mmio_map(mctx->afu_h, CXL_MMIO_BIG_ENDIAN);
	if (rc != 0) {
		rc = -7;
		goto err_free_errinfo;
	}

	return 0;

 err_free_errinfo:
	if (mctx->errinfo)
		free(mctx->errinfo);
	mctx->errinfo = NULL;
 err_afu_free:
	cxl_afu_free(mctx->afu_h);
	mctx->afu_h = NULL;
	VERBOSE3("[%s] Exit rc=%d\n", __func__, rc);
	return rc;
}