// SPDX-License-Identifier: GPL-2.0
/*
 * ISM driver for s390.
 *
 * Copyright IBM Corp. 2018
 */
#define KMSG_COMPONENT "ism"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/export.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/processor.h>

#include "ism.h"

MODULE_DESCRIPTION("ISM driver for s390");
MODULE_LICENSE("GPL");

#define DRV_NAME "ism"

static const struct pci_device_id ism_device_table[] = {
	{ PCI_VDEVICE(IBM, PCI_DEVICE_ID_IBM_ISM), 0 },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, ism_device_table);

static debug_info_t *ism_debug_info;

static int ism_cmd(struct ism_dev *ism, void *cmd)
{
	struct ism_req_hdr *req = cmd;
	struct ism_resp_hdr *resp = cmd;

	spin_lock(&ism->cmd_lock);
	__ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req));
	__ism_write_cmd(ism, req, 0, sizeof(*req));

	WRITE_ONCE(resp->ret, ISM_ERROR);

	__ism_read_cmd(ism, resp, 0, sizeof(*resp));
	if (resp->ret) {
		debug_text_event(ism_debug_info, 0, "cmd failure");
		debug_event(ism_debug_info, 0, resp, sizeof(*resp));
		goto out;
	}
	__ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp));
out:
	spin_unlock(&ism->cmd_lock);
	return resp->ret;
}

static int ism_cmd_simple(struct ism_dev *ism, u32 cmd_code)
{
	union ism_cmd_simple cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = cmd_code;
	cmd.request.hdr.len = sizeof(cmd.request);

	return ism_cmd(ism, &cmd);
}

static int query_info(struct ism_dev *ism)
{
	union ism_qi cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_QUERY_INFO;
	cmd.request.hdr.len = sizeof(cmd.request);

	if (ism_cmd(ism, &cmd))
		goto out;

	debug_text_event(ism_debug_info, 3, "query info");
	debug_event(ism_debug_info, 3, &cmd.response, sizeof(cmd.response));
out:
	return 0;
}

static int register_sba(struct ism_dev *ism)
{
	union ism_reg_sba cmd;
	dma_addr_t dma_handle;
	struct ism_sba *sba;

	sba = dma_alloc_coherent(&ism->pdev->dev, PAGE_SIZE, &dma_handle,
				 GFP_KERNEL);
	if (!sba)
		return -ENOMEM;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_REG_SBA;
	cmd.request.hdr.len = sizeof(cmd.request);
	cmd.request.sba = dma_handle;

	if (ism_cmd(ism, &cmd)) {
		dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, sba, dma_handle);
		return -EIO;
	}

	ism->sba = sba;
	ism->sba_dma_addr = dma_handle;

	return 0;
}

static int register_ieq(struct ism_dev *ism)
{
	union ism_reg_ieq cmd;
	dma_addr_t dma_handle;
	struct ism_eq *ieq;

	ieq = dma_alloc_coherent(&ism->pdev->dev, PAGE_SIZE, &dma_handle,
				 GFP_KERNEL);
	if (!ieq)
		return -ENOMEM;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_REG_IEQ;
	cmd.request.hdr.len = sizeof(cmd.request);
	cmd.request.ieq = dma_handle;
	cmd.request.len = sizeof(*ieq);

	if (ism_cmd(ism, &cmd)) {
		dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, ieq, dma_handle);
		return -EIO;
	}

	ism->ieq = ieq;
	ism->ieq_idx = -1;
	ism->ieq_dma_addr = dma_handle;

	return 0;
}

static int unregister_sba(struct ism_dev *ism)
{
	int ret;

	if (!ism->sba)
		return 0;

	ret = ism_cmd_simple(ism, ISM_UNREG_SBA);
	if (ret && ret != ISM_ERROR)
		return -EIO;

	dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
			  ism->sba, ism->sba_dma_addr);

	ism->sba = NULL;
	ism->sba_dma_addr = 0;

	return 0;
}

static int unregister_ieq(struct ism_dev *ism)
{
	int ret;

	if (!ism->ieq)
		return 0;

	ret = ism_cmd_simple(ism, ISM_UNREG_IEQ);
	if (ret && ret != ISM_ERROR)
		return -EIO;

	dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
			  ism->ieq, ism->ieq_dma_addr);

	ism->ieq = NULL;
	ism->ieq_dma_addr = 0;

	return 0;
}

static int ism_read_local_gid(struct dibs_dev *dibs)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_read_gid cmd;
	int ret;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_READ_GID;
	cmd.request.hdr.len = sizeof(cmd.request);

	ret = ism_cmd(ism, &cmd);
	if (ret)
		goto out;

	memset(&dibs->gid, 0, sizeof(dibs->gid));
	memcpy(&dibs->gid, &cmd.response.gid, sizeof(cmd.response.gid));
out:
	return ret;
}

static int ism_query_rgid(struct dibs_dev *dibs, const uuid_t *rgid,
			  u32 vid_valid, u32 vid)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_query_rgid cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_QUERY_RGID;
	cmd.request.hdr.len = sizeof(cmd.request);

	memcpy(&cmd.request.rgid, rgid, sizeof(cmd.request.rgid));
	cmd.request.vlan_valid = vid_valid;
	cmd.request.vlan_id = vid;

	return ism_cmd(ism, &cmd);
}

static int ism_max_dmbs(void)
{
	return ISM_NR_DMBS;
}

static void ism_free_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
{
	clear_bit(dmb->idx, ism->sba_bitmap);
	dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len,
		       DMA_FROM_DEVICE);
	folio_put(virt_to_folio(dmb->cpu_addr));
}

static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
{
	struct folio *folio;
	unsigned long bit;
	int rc;

	if (PAGE_ALIGN(dmb->dmb_len) > dma_get_max_seg_size(&ism->pdev->dev))
		return -EINVAL;

	if (!dmb->idx) {
		bit = find_next_zero_bit(ism->sba_bitmap, ISM_NR_DMBS,
					 ISM_DMB_BIT_OFFSET);
		if (bit == ISM_NR_DMBS)
			return -ENOSPC;

		dmb->idx = bit;
	}
	if (dmb->idx < ISM_DMB_BIT_OFFSET ||
	    test_and_set_bit(dmb->idx, ism->sba_bitmap))
		return -EINVAL;

	folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC |
			    __GFP_NORETRY, get_order(dmb->dmb_len));

	if (!folio) {
		rc = -ENOMEM;
		goto out_bit;
	}

	dmb->cpu_addr = folio_address(folio);
	dmb->dma_addr = dma_map_page(&ism->pdev->dev,
				     virt_to_page(dmb->cpu_addr), 0,
				     dmb->dmb_len, DMA_FROM_DEVICE);
	if (dma_mapping_error(&ism->pdev->dev, dmb->dma_addr)) {
		rc = -ENOMEM;
		goto out_free;
	}

	return 0;

out_free:
	kfree(dmb->cpu_addr);
out_bit:
	clear_bit(dmb->idx, ism->sba_bitmap);
	return rc;
}

static int ism_register_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb,
			    struct dibs_client *client)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_reg_dmb cmd;
	unsigned long flags;
	int ret;

	ret = ism_alloc_dmb(ism, dmb);
	if (ret)
		goto out;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_REG_DMB;
	cmd.request.hdr.len = sizeof(cmd.request);

	cmd.request.dmb = dmb->dma_addr;
	cmd.request.dmb_len = dmb->dmb_len;
	cmd.request.sba_idx = dmb->idx;
	cmd.request.vlan_valid = dmb->vlan_valid;
	cmd.request.vlan_id = dmb->vlan_id;
	memcpy(&cmd.request.rgid, &dmb->rgid, sizeof(u64));

	ret = ism_cmd(ism, &cmd);
	if (ret) {
		ism_free_dmb(ism, dmb);
		goto out;
	}
	dmb->dmb_tok = cmd.response.dmb_tok;
	spin_lock_irqsave(&dibs->lock, flags);
	dibs->dmb_clientid_arr[dmb->idx - ISM_DMB_BIT_OFFSET] = client->id;
	spin_unlock_irqrestore(&dibs->lock, flags);
out:
	return ret;
}

static int ism_unregister_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_unreg_dmb cmd;
	unsigned long flags;
	int ret;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_UNREG_DMB;
	cmd.request.hdr.len = sizeof(cmd.request);

	cmd.request.dmb_tok = dmb->dmb_tok;

	spin_lock_irqsave(&dibs->lock, flags);
	dibs->dmb_clientid_arr[dmb->idx - ISM_DMB_BIT_OFFSET] = NO_DIBS_CLIENT;
	spin_unlock_irqrestore(&dibs->lock, flags);

	ret = ism_cmd(ism, &cmd);
	if (ret && ret != ISM_ERROR)
		goto out;

	ism_free_dmb(ism, dmb);
out:
	return ret;
}

static int ism_add_vlan_id(struct dibs_dev *dibs, u64 vlan_id)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_set_vlan_id cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_ADD_VLAN_ID;
	cmd.request.hdr.len = sizeof(cmd.request);

	cmd.request.vlan_id = vlan_id;

	return ism_cmd(ism, &cmd);
}

static int ism_del_vlan_id(struct dibs_dev *dibs, u64 vlan_id)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_set_vlan_id cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_DEL_VLAN_ID;
	cmd.request.hdr.len = sizeof(cmd.request);

	cmd.request.vlan_id = vlan_id;

	return ism_cmd(ism, &cmd);
}

static int ism_signal_ieq(struct dibs_dev *dibs, const uuid_t *rgid,
			  u32 trigger_irq, u32 event_code, u64 info)
{
	struct ism_dev *ism = dibs->drv_priv;
	union ism_sig_ieq cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.request.hdr.cmd = ISM_SIGNAL_IEQ;
	cmd.request.hdr.len = sizeof(cmd.request);

	memcpy(&cmd.request.rgid, rgid, sizeof(cmd.request.rgid));
	cmd.request.trigger_irq = trigger_irq;
	cmd.request.event_code = event_code;
	cmd.request.info = info;

	return ism_cmd(ism, &cmd);
}

static unsigned int max_bytes(unsigned int start, unsigned int len,
			      unsigned int boundary)
{
	return min(boundary - (start & (boundary - 1)), len);
}

static int ism_move(struct dibs_dev *dibs, u64 dmb_tok, unsigned int idx,
		    bool sf, unsigned int offset, void *data,
		    unsigned int size)
{
	struct ism_dev *ism = dibs->drv_priv;
	unsigned int bytes;
	u64 dmb_req;
	int ret;

	while (size) {
		bytes = max_bytes(offset, size, PAGE_SIZE);
		dmb_req = ISM_CREATE_REQ(dmb_tok, idx, size == bytes ? sf : 0,
					 offset);

		ret = __ism_move(ism, dmb_req, data, bytes);
		if (ret)
			return ret;

		size -= bytes;
		data += bytes;
		offset += bytes;
	}

	return 0;
}

static u16 ism_get_chid(struct dibs_dev *dibs)
{
	struct ism_dev *ism = dibs->drv_priv;

	if (!ism || !ism->pdev)
		return 0;

	return to_zpci(ism->pdev)->pchid;
}

static int ism_match_event_type(u32 s390_event_type)
{
	switch (s390_event_type) {
	case ISM_EVENT_BUF:
		return DIBS_BUF_EVENT;
	case ISM_EVENT_DEV:
		return DIBS_DEV_EVENT;
	case ISM_EVENT_SWR:
		return DIBS_SW_EVENT;
	default:
		return DIBS_OTHER_TYPE;
	}
}

static int ism_match_event_subtype(u32 s390_event_subtype)
{
	switch (s390_event_subtype) {
	case ISM_BUF_DMB_UNREGISTERED:
		return DIBS_BUF_UNREGISTERED;
	case ISM_DEV_GID_DISABLED:
		return DIBS_DEV_DISABLED;
	case ISM_DEV_GID_ERR_STATE:
		return DIBS_DEV_ERR_STATE;
	default:
		return DIBS_OTHER_SUBTYPE;
	}
}

static void ism_handle_event(struct ism_dev *ism)
{
	struct dibs_dev *dibs = ism->dibs;
	struct dibs_event event;
	struct ism_event *entry;
	struct dibs_client *clt;
	int i;

	while ((ism->ieq_idx + 1) != READ_ONCE(ism->ieq->header.idx)) {
		if (++ism->ieq_idx == ARRAY_SIZE(ism->ieq->entry))
			ism->ieq_idx = 0;

		entry = &ism->ieq->entry[ism->ieq_idx];
		debug_event(ism_debug_info, 2, entry, sizeof(*entry));
		__memset(&event, 0, sizeof(event));
		event.type = ism_match_event_type(entry->type);
		if (event.type == DIBS_SW_EVENT)
			event.subtype = entry->code;
		else
			event.subtype = ism_match_event_subtype(entry->code);
		event.time = entry->time;
		event.data = entry->info;
		switch (event.type) {
		case DIBS_BUF_EVENT:
			event.buffer_tok = entry->tok;
			break;
		case DIBS_DEV_EVENT:
		case DIBS_SW_EVENT:
			memcpy(&event.gid, &entry->tok, sizeof(u64));
		}
		for (i = 0; i < MAX_DIBS_CLIENTS; ++i) {
			clt = dibs->subs[i];
			if (clt)
				clt->ops->handle_event(dibs, &event);
		}
	}
}

static irqreturn_t ism_handle_irq(int irq, void *data)
{
	struct ism_dev *ism = data;
	unsigned long bit, end;
	struct dibs_dev *dibs;
	unsigned long *bv;
	u16 dmbemask;
	u8 client_id;

	dibs = ism->dibs;

	bv = (void *) &ism->sba->dmb_bits[ISM_DMB_WORD_OFFSET];
	end = sizeof(ism->sba->dmb_bits) * BITS_PER_BYTE - ISM_DMB_BIT_OFFSET;

	spin_lock(&dibs->lock);
	ism->sba->s = 0;
	barrier();
	for (bit = 0;;) {
		bit = find_next_bit_inv(bv, end, bit);
		if (bit >= end)
			break;

		clear_bit_inv(bit, bv);
		dmbemask = ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET];
		ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0;
		barrier();
		client_id = dibs->dmb_clientid_arr[bit];
		if (unlikely(client_id == NO_DIBS_CLIENT ||
			     !dibs->subs[client_id]))
			continue;
		dibs->subs[client_id]->ops->handle_irq(dibs,
						       bit + ISM_DMB_BIT_OFFSET,
						       dmbemask);
	}

	if (ism->sba->e) {
		ism->sba->e = 0;
		barrier();
		ism_handle_event(ism);
	}
	spin_unlock(&dibs->lock);
	return IRQ_HANDLED;
}

static const struct dibs_dev_ops ism_ops = {
	.get_fabric_id = ism_get_chid,
	.query_remote_gid = ism_query_rgid,
	.max_dmbs = ism_max_dmbs,
	.register_dmb = ism_register_dmb,
	.unregister_dmb = ism_unregister_dmb,
	.move_data = ism_move,
	.add_vlan_id = ism_add_vlan_id,
	.del_vlan_id = ism_del_vlan_id,
	.signal_event = ism_signal_ieq,
};

static int ism_dev_init(struct ism_dev *ism)
{
	struct pci_dev *pdev = ism->pdev;
	int ret;

	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
	if (ret <= 0)
		goto out;

	ret = request_irq(pci_irq_vector(pdev, 0), ism_handle_irq, 0,
			  pci_name(pdev), ism);
	if (ret)
		goto free_vectors;

	ret = register_sba(ism);
	if (ret)
		goto free_irq;

	ret = register_ieq(ism);
	if (ret)
		goto unreg_sba;

	query_info(ism);
	return 0;

unreg_sba:
	unregister_sba(ism);
free_irq:
	free_irq(pci_irq_vector(pdev, 0), ism);
free_vectors:
	pci_free_irq_vectors(pdev);
out:
	return ret;
}

static void ism_dev_exit(struct ism_dev *ism)
{
	struct pci_dev *pdev = ism->pdev;

	unregister_ieq(ism);
	unregister_sba(ism);
	free_irq(pci_irq_vector(pdev, 0), ism);
	pci_free_irq_vectors(pdev);
}

static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct dibs_dev *dibs;
	struct zpci_dev *zdev;
	struct ism_dev *ism;
	int ret;

	ism = kzalloc(sizeof(*ism), GFP_KERNEL);
	if (!ism)
		return -ENOMEM;

	spin_lock_init(&ism->cmd_lock);
	dev_set_drvdata(&pdev->dev, ism);
	ism->pdev = pdev;

	ret = pci_enable_device_mem(pdev);
	if (ret)
		goto err_dev;

	ret = pci_request_mem_regions(pdev, DRV_NAME);
	if (ret)
		goto err_disable;

	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (ret)
		goto err_resource;

	dma_set_seg_boundary(&pdev->dev, SZ_1M - 1);
	dma_set_max_seg_size(&pdev->dev, SZ_1M);
	pci_set_master(pdev);

	dibs = dibs_dev_alloc();
	if (!dibs) {
		ret = -ENOMEM;
		goto err_resource;
	}
	/* set this up before we enable interrupts */
	ism->dibs = dibs;
	dibs->drv_priv = ism;
	dibs->ops = &ism_ops;

	/* enable ism device, but any interrupts and events will be ignored
	 * before dibs_dev_add() adds it to any clients.
	 */
	ret = ism_dev_init(ism);
	if (ret)
		goto err_dibs;

	/* after ism_dev_init() we can call ism function to set gid */
	ret = ism_read_local_gid(dibs);
	if (ret)
		goto err_ism;

	dibs->dev.parent = &pdev->dev;

	zdev = to_zpci(pdev);
	dev_set_name(&dibs->dev, "ism%x", zdev->uid ? zdev->uid : zdev->fid);

	ret = dibs_dev_add(dibs);
	if (ret)
		goto err_ism;

	return 0;

err_ism:
	ism_dev_exit(ism);
err_dibs:
	/* pairs with dibs_dev_alloc() */
	put_device(&dibs->dev);
err_resource:
	pci_release_mem_regions(pdev);
err_disable:
	pci_disable_device(pdev);
err_dev:
	dev_set_drvdata(&pdev->dev, NULL);
	kfree(ism);

	return ret;
}

static void ism_remove(struct pci_dev *pdev)
{
	struct ism_dev *ism = dev_get_drvdata(&pdev->dev);
	struct dibs_dev *dibs = ism->dibs;

	dibs_dev_del(dibs);
	ism_dev_exit(ism);
	/* pairs with dibs_dev_alloc() */
	put_device(&dibs->dev);

	pci_release_mem_regions(pdev);
	pci_disable_device(pdev);
	dev_set_drvdata(&pdev->dev, NULL);
	kfree(ism);
}

static struct pci_driver ism_driver = {
	.name	  = DRV_NAME,
	.id_table = ism_device_table,
	.probe	  = ism_probe,
	.remove	  = ism_remove,
};

static int __init ism_init(void)
{
	int ret;

	ism_debug_info = debug_register("ism", 2, 1, 16);
	if (!ism_debug_info)
		return -ENODEV;

	debug_register_view(ism_debug_info, &debug_hex_ascii_view);
	ret = pci_register_driver(&ism_driver);
	if (ret)
		debug_unregister(ism_debug_info);

	return ret;
}

static void __exit ism_exit(void)
{
	pci_unregister_driver(&ism_driver);
	debug_unregister(ism_debug_info);
}

module_init(ism_init);
module_exit(ism_exit);
