/* * If credit checking is enabled for this window, poll for the return * of window credits (i.e for NX engines to process any outstanding CRBs). * Since NX-842 waits for the CRBs to be processed before closing the * window, we should not have to wait for too long. * * TODO: We retry in 10ms intervals now. We could/should probably peek at * the VAS_LRFIFO_PUSH_OFFSET register to get an estimate of pending * CRBs on the FIFO and compute the delay dynamically on each retry. * But that is not really needed until we support NX-GZIP access from * user space. (NX-842 driver waits for CSB and Fast thread-wakeup * doesn't use credit checking). */ static void poll_window_credits(struct vas_window *window) { u64 val; int creds, mode; val = read_hvwc_reg(window, VREG(WINCTL)); if (window->tx_win) mode = GET_FIELD(VAS_WINCTL_TX_WCRED_MODE, val); else mode = GET_FIELD(VAS_WINCTL_RX_WCRED_MODE, val); if (!mode) return; retry: if (window->tx_win) { val = read_hvwc_reg(window, VREG(TX_WCRED)); creds = GET_FIELD(VAS_TX_WCRED, val); } else { val = read_hvwc_reg(window, VREG(LRX_WCRED)); creds = GET_FIELD(VAS_LRX_WCRED, val); } if (creds < window->wcreds_max) { val = 0; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(10)); goto retry; } }
/* * Unpin and close a window so no new requests are accepted and the * hardware can evict this window from cache if necessary. */ static void unpin_close_window(struct vas_window *window) { u64 val; val = read_hvwc_reg(window, VREG(WINCTL)); val = SET_FIELD(VAS_WINCTL_PIN, val, 0); val = SET_FIELD(VAS_WINCTL_OPEN, val, 0); write_hvwc_reg(window, VREG(WINCTL), val); }
/* * Wait for the window to go to "not-busy" state. It should only take a * short time to queue a CRB, so window should not be busy for too long. * Trying 5ms intervals. */ static void poll_window_busy_state(struct vas_window *window) { int busy; u64 val; retry: val = read_hvwc_reg(window, VREG(WIN_STATUS)); busy = GET_FIELD(VAS_WIN_BUSY, val); if (busy) { val = 0; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(5)); goto retry; } }
int vas_paste_crb(struct vas_window *txwin, int offset, bool re) { int rc; void *addr; uint64_t val; trace_vas_paste_crb(current, txwin); /* * Only NX windows are supported for now and hardware assumes * report-enable flag is set for NX windows. Ensure software * complies too. */ WARN_ON_ONCE(txwin->nx_win && !re); addr = txwin->paste_kaddr; if (re) { /* * Set the REPORT_ENABLE bit (equivalent to writing * to 1K offset of the paste address) */ val = SET_FIELD(RMA_LSMP_REPORT_ENABLE, 0ULL, 1); addr += val; } /* * Map the raw CR value from vas_paste() to an error code (there * is just pass or fail for now though). */ rc = vas_paste(addr, offset); if (rc == 2) rc = 0; else rc = -EINVAL; pr_debug("Txwin #%d: Msg count %llu\n", txwin->winid, read_hvwc_reg(txwin, VREG(LRFIFO_PUSH))); return rc; }