/* * 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; }
/* * 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 {
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]); } }
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; }
/* * 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; }