/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Channel Subsystem tests library
 *
 * Copyright (c) 2020 IBM Corp
 *
 * Authors:
 *  Pierre Morel <pmorel@linux.ibm.com>
 */
#include <libcflat.h>
#include <alloc_phys.h>
#include <asm/page.h>
#include <string.h>
#include <interrupt.h>
#include <asm/arch_def.h>
#include <asm/time.h>
#include <asm/arch_def.h>
#include <alloc_page.h>
#include <malloc_io.h>
#include <css.h>

struct schib schib;
struct chsc_scsc *chsc_scsc;

static const char * const chsc_rsp_description[] = {
	"CHSC unknown error",
	"Command executed",
	"Invalid command",
	"Request-block error",
	"Command not installed",
	"Data not available",
	"Absolute address of channel-subsystem communication block exceeds 2G - 1.",
	"Invalid command format",
	"Invalid channel-subsystem identification (CSSID)",
	"The command-request block specified an invalid format for the command response block.",
	"Invalid subchannel-set identification (SSID)",
	"A busy condition precludes execution.",
};

static bool check_response(void *p)
{
	struct chsc_header *h = p;

	if (h->code == CHSC_RSP_OK)
		return true;

	if (h->code > CHSC_RSP_MAX)
		h->code = 0;

	report_abort("Response code %04x: %s", h->code,
		      chsc_rsp_description[h->code]);
	return false;
}

bool chsc(void *p, uint16_t code, uint16_t len)
{
	struct chsc_header *h = p;

	h->code = code;
	h->len = len;

	switch (_chsc(p)) {
	case 3:
		report_abort("Subchannel invalid or not enabled.");
		break;
	case 2:
		report_abort("CHSC subchannel busy.");
		break;
	case 1:
		report_abort("Subchannel invalid or not enabled.");
		break;
	case 0:
		return check_response(p + len);
	}
	return false;
}

bool get_chsc_scsc(void)
{
	int i, n;
	char buffer[510];
	char *p;

	if (chsc_scsc) /* chsc_scsc already initialized */
		return true;

	chsc_scsc = alloc_page();
	if (!chsc_scsc) {
		report_abort("could not allocate chsc_scsc page!");
		return false;
	}

	if (!chsc(chsc_scsc, CHSC_SCSC, CHSC_SCSC_LEN))
		return false;

	for (i = 0, p = buffer; i < CSS_GENERAL_FEAT_BITLEN; i++) {
		if (css_test_general_feature(i)) {
			n = snprintf(p, sizeof(buffer), "%d,", i);
			p += n;
		}
	}
	report_info("General features: %s", buffer);

	for (i = 0, p = buffer; i < CSS_CHSC_FEAT_BITLEN; i++) {
		if (css_test_chsc_feature(i)) {
			n = snprintf(p, sizeof(buffer), "%d,", i);
			p += n;
		}
	}
	report_info("CHSC features: %s", buffer);

	return true;
}

/*
 * css_enumerate:
 * On success return the first subchannel ID found.
 * On error return an invalid subchannel ID containing cc
 */
int css_enumerate(void)
{
	struct pmcw *pmcw = &schib.pmcw;
	int scn_found = 0;
	int dev_found = 0;
	int schid = 0;
	int cc;
	int scn;

	for (scn = 0; scn < 0xffff; scn++) {
		cc = stsch(scn | SCHID_ONE, &schib);
		switch (cc) {
		case 0:		/* 0 means SCHIB stored */
			break;
		case 3:		/* 3 means no more channels */
			goto out;
		default:	/* 1 or 2 should never happen for STSCH */
			report_abort("Unexpected error %d on subchannel %08x",
				     cc, scn | SCHID_ONE);
			return cc;
		}

		/* We currently only support type 0, a.k.a. I/O channels */
		if (PMCW_CHANNEL_TYPE(pmcw) != 0)
			continue;

		/* We ignore I/O channels without valid devices */
		scn_found++;
		if (!(pmcw->flags & PMCW_DNV))
			continue;

		/* We keep track of the first device as our test device */
		if (!schid)
			schid = scn | SCHID_ONE;
		report_info("Found subchannel %08x", scn | SCHID_ONE);
		dev_found++;
	}

out:
	report_info("Tested subchannels: %d, I/O subchannels: %d, I/O devices: %d",
		    scn, scn_found, dev_found);
	return schid;
}

/*
 * css_enabled: report if the subchannel is enabled
 * @schid: Subchannel Identifier
 * Return value:
 *   true if the subchannel is enabled
 *   false otherwise
 */
bool css_enabled(int schid)
{
	struct pmcw *pmcw = &schib.pmcw;
	int cc;

	cc = stsch(schid, &schib);
	if (cc) {
		report_info("stsch: updating sch %08x failed with cc=%d",
			    schid, cc);
		return false;
	}

	if (!(pmcw->flags & PMCW_ENABLE)) {
		report_info("stsch: sch %08x not enabled", schid);
		return false;
	}
	return true;
}
/*
 * css_enable: enable the subchannel with the specified ISC
 * @schid: Subchannel Identifier
 * @isc  : number of the interruption subclass to use
 * Return value:
 *   On success: 0
 *   On error the CC of the faulty instruction
 *      or -1 if the retry count is exceeded.
 */
int css_enable(int schid, int isc)
{
	struct pmcw *pmcw = &schib.pmcw;
	int retry_count = 0;
	uint16_t flags;
	int cc;

	/* Read the SCHIB for this subchannel */
	cc = stsch(schid, &schib);
	if (cc) {
		report_info("stsch: sch %08x failed with cc=%d", schid, cc);
		return cc;
	}

	flags = PMCW_ENABLE | (isc << PMCW_ISC_SHIFT);
	if ((pmcw->flags & (PMCW_ISC_MASK | PMCW_ENABLE)) == flags) {
		report_info("stsch: sch %08x already enabled", schid);
		return 0;
	}

retry:
	/* Update the SCHIB to enable the channel and set the ISC */
	pmcw->flags &= ~PMCW_ISC_MASK;
	pmcw->flags |= flags;

	/* Tell the CSS we want to modify the subchannel */
	cc = msch(schid, &schib);
	if (cc) {
		/*
		 * If the subchannel is status pending or
		 * if a function is in progress,
		 * we consider both cases as errors.
		 */
		report_info("msch: sch %08x failed with cc=%d", schid, cc);
		return cc;
	}

	/*
	 * Read the SCHIB again to verify the enablement
	 */
	if (css_enabled(schid))
		return 0;

	if (retry_count++ < MAX_ENABLE_RETRIES) {
		mdelay(10); /* the hardware was not ready, give it some time */
		goto retry;
	}

	report_info("msch: modifying sch %08x failed after %d retries. pmcw flags: %04x",
		    schid, retry_count, pmcw->flags);
	return -1;
}

/*
 * schib_update_mb: update the subchannel Measurement Block
 * @schid: Subchannel Identifier
 * @mb   : 64bit address of the measurement block
 * @mbi : the measurement block offset
 * @flags : PMCW_MBUE to enable measurement block update
 *	    PMCW_DCTME to enable device connect time
 *	    0 to disable measurement
 * @format1: set if format 1 is to be used
 */
static bool schib_update_mb(int schid, uint64_t mb, uint16_t mbi,
			    uint16_t flags, bool format1)
{
	struct pmcw *pmcw = &schib.pmcw;
	int cc;

	/* Read the SCHIB for this subchannel */
	cc = stsch(schid, &schib);
	if (cc) {
		report_info("stsch: sch %08x failed with cc=%d", schid, cc);
		return false;
	}

	/* Update the SCHIB to enable the measurement block */
	if (flags) {
		pmcw->flags |= flags;

		if (format1)
			pmcw->flags2 |= PMCW_MBF1;
		else
			pmcw->flags2 &= ~PMCW_MBF1;

		pmcw->mbi = mbi;
		schib.mbo = mb & ~0x3f;
	} else {
		pmcw->flags &= ~(PMCW_MBUE | PMCW_DCTME);
	}

	/* Tell the CSS we want to modify the subchannel */
	cc = msch(schid, &schib);
	if (cc) {
		/*
		 * If the subchannel is status pending or
		 * if a function is in progress,
		 * we consider both cases as errors.
		 */
		report_info("msch: sch %08x failed with cc=%d", schid, cc);
		return false;
	}

	/*
	 * Read the SCHIB again
	 */
	cc = stsch(schid, &schib);
	if (cc) {
		report_info("stsch: updating sch %08x failed with cc=%d",
			    schid, cc);
		return false;
	}

	return true;
}

/*
 * css_enable_mb: enable the subchannel Measurement Block
 * @schid: Subchannel Identifier
 * @mb   : 64bit address of the measurement block
 * @format1: set if format 1 is to be used
 * @mbi : the measurement block offset
 * @flags : PMCW_MBUE to enable measurement block update
 *	    PMCW_DCTME to enable device connect time
 */
bool css_enable_mb(int schid, uint64_t mb, uint16_t mbi, uint16_t flags,
		   bool format1)
{
	int retry_count = MAX_ENABLE_RETRIES;
	struct pmcw *pmcw = &schib.pmcw;

	while (retry_count-- &&
	       !schib_update_mb(schid, mb, mbi, flags, format1))
		mdelay(10); /* the hardware was not ready, give it some time */

	return schib.mbo == mb && pmcw->mbi == mbi;
}

/*
 * css_disable_mb: disable the subchannel Measurement Block
 * @schid: Subchannel Identifier
 */
bool css_disable_mb(int schid)
{
	int retry_count = MAX_ENABLE_RETRIES;

	while (retry_count-- &&
	       !schib_update_mb(schid, 0, 0, 0, 0))
		mdelay(10); /* the hardware was not ready, give it some time */

	return retry_count > 0;
}

static struct irb irb;

void css_irq_io(void)
{
	int ret = 0;
	char *flags;
	int sid;

	report_prefix_push("Interrupt");
	sid = lowcore.subsys_id_word;
	/* Lowlevel set the SID as interrupt parameter. */
	if (lowcore.io_int_param != sid) {
		report_fail("io_int_param: %x differs from subsys_id_word: %x",
			    lowcore.io_int_param, sid);
		goto pop;
	}
	report_prefix_pop();

	report_prefix_push("tsch");
	ret = tsch(sid, &irb);
	switch (ret) {
	case 1:
		dump_irb(&irb);
		flags = dump_scsw_flags(irb.scsw.ctrl);
		report_fail("I/O interrupt, but tsch returns CC 1 for subchannel %08x.SCSW flags: %s",
			    sid, flags);
		break;
	case 2:
		report_fail("tsch returns unexpected CC 2");
		break;
	case 3:
		report_fail("tsch reporting sch %08x as not operational", sid);
		break;
	case 0:
		/* Stay humble on success */
		break;
	}
pop:
	report_prefix_pop();
	lowcore.io_old_psw.mask &= ~PSW_MASK_WAIT;
}

int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw)
{
	struct orb orb = {
		.intparm = sid,
		.ctrl = ORB_CTRL_ISIC|ORB_CTRL_FMT|ORB_LPM_DFLT,
		.cpa = (unsigned int) (unsigned long)ccw,
	};

	return ssch(sid, &orb);
}

struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags)
{
	struct ccw1 *ccw;

	ccw = alloc_io_mem(sizeof(*ccw), 0);
	if (!ccw)
		return NULL;

	ccw->code = code;
	ccw->flags = flags;
	ccw->count = count;
	ccw->data_address = (int)(unsigned long)data;

	return ccw;
}

/* wait_and_check_io_completion:
 * @schid: the subchannel ID
 *
 * Makes the most common check to validate a successful I/O
 * completion.
 * Only report failures.
 */
int wait_and_check_io_completion(int schid)
{
	int ret = 0;

	wait_for_interrupt(PSW_MASK_IO);

	report_prefix_push("check I/O completion");

	if (lowcore.io_int_param != schid) {
		report_fail("interrupt parameter: expected %08x got %08x",
			    schid, lowcore.io_int_param);
		ret = -1;
		goto end;
	}

	/* Verify that device status is valid */
	if (!(irb.scsw.ctrl & SCSW_SC_PENDING)) {
		report_fail("No status pending after interrupt. Subch Ctrl: %08x",
			    irb.scsw.ctrl);
		ret = -1;
		goto end;
	}

	if (!(irb.scsw.ctrl & (SCSW_SC_SECONDARY | SCSW_SC_PRIMARY))) {
		report_fail("Primary or secondary status missing. Subch Ctrl: %08x",
			    irb.scsw.ctrl);
		ret = -1;
		goto end;
	}

	if (!(irb.scsw.dev_stat & (SCSW_DEVS_DEV_END | SCSW_DEVS_SCH_END))) {
		report_fail("No device end or sch end. Dev. status: %02x",
			    irb.scsw.dev_stat);
		ret = -1;
		goto end;
	}

	if (irb.scsw.sch_stat & ~SCSW_SCHS_IL) {
		report_info("Unexpected Subch. status %02x", irb.scsw.sch_stat);
		ret = -1;
		goto end;
	}

end:
	report_prefix_pop();
	return ret;
}

/*
 * css_residual_count
 * Return the residual count, if it is valid.
 *
 * Return value:
 * Success: the residual count
 * Not meaningful: -1 (-1 can not be a valid count)
 */
int css_residual_count(unsigned int schid)
{

	if (!(irb.scsw.ctrl & (SCSW_SC_PENDING | SCSW_SC_PRIMARY)))
		return -1;

	if (irb.scsw.dev_stat)
		if (irb.scsw.sch_stat & ~(SCSW_SCHS_PCI | SCSW_SCHS_IL))
			return -1;

	return irb.scsw.count;
}

/*
 * enable_io_isc: setup ISC in Control Register 6
 * @isc: The interruption Sub Class as a bitfield
 */
void enable_io_isc(uint8_t isc)
{
	uint64_t value;

	value = (uint64_t)isc << 24;
	lctlg(6, value);
}

static int is_path_installed(struct schib *schib, int chp_idx)
{
	return schib->pmcw.pim & BIT(7 - chp_idx);
}

/*
 * css_find_installed_chpid: find any installed CHPID
 * @sid: subsystem-identification word
 * @chpid_out: store the found chpid here, left alone if none found
 *
 * returns 0 on success, -1 if no chpid found any other value
 * indicates the condition code of a failing STSCH instruction
 */
int css_find_installed_chpid(int sid, uint8_t *chpid_out)
{
	int cc;

	cc = stsch(sid, &schib);
	if (cc) {
		report_fail("%s: sch %08x failed with cc=%d", __func__, sid, cc);
		return cc;
	}

	for (int i = 0; i < ARRAY_SIZE(schib.pmcw.chpid); i++) {
		if (is_path_installed(&schib, i)) {
			*chpid_out = schib.pmcw.chpid[i];
			return 0;
		}
	}

	return -1;
}

/*
 * css_generate_crw: Generate a CRW by issuing RCHP on any channel path
 * @sid: subsystem-identification word
 *
 * returns 0 when a CRW was generated, -1 if no chpid found.
 */
int css_generate_crw(int sid)
{
	int ret, cc;
	uint8_t chpid;

	report_prefix_push("Generate CRW");

	ret = css_find_installed_chpid(sid, &chpid);
	if (ret) {
		report_fail("No CHPID found: ret=%d", ret);
		return -1;
	}

	cc = rchp(chpid);
	report(!cc, "rhcp cc != 0");

	report_prefix_pop();

	return 0;
}
