// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright Gavin Shan, IBM Corporation 2016.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>

#include <net/ncsi.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/genetlink.h>

#include "internal.h"
#include "ncsi-pkt.h"

static const int padding_bytes = 26;

u32 ncsi_calculate_checksum(unsigned char *data, int len)
{
	u32 checksum = 0;
	int i;

	for (i = 0; i < len; i += 2)
		checksum += (((u32)data[i] << 8) | data[i + 1]);

	checksum = (~checksum + 1);
	return checksum;
}

/* This function should be called after the data area has been
 * populated completely.
 */
static void ncsi_cmd_build_header(struct ncsi_pkt_hdr *h,
				  struct ncsi_cmd_arg *nca)
{
	u32 checksum;
	__be32 *pchecksum;

	h->mc_id        = 0;
	h->revision     = NCSI_PKT_REVISION;
	h->reserved     = 0;
	h->id           = nca->id;
	h->type         = nca->type;
	h->channel      = NCSI_TO_CHANNEL(nca->package,
					  nca->channel);
	h->length       = htons(nca->payload);
	h->reserved1[0] = 0;
	h->reserved1[1] = 0;

	/* Fill with calculated checksum */
	checksum = ncsi_calculate_checksum((unsigned char *)h,
					   sizeof(*h) + nca->payload);
	pchecksum = (__be32 *)((void *)h + sizeof(struct ncsi_pkt_hdr) +
		    ALIGN(nca->payload, 4));
	*pchecksum = htonl(checksum);
}

static int ncsi_cmd_handler_default(struct sk_buff *skb,
				    struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_sp(struct sk_buff *skb,
			       struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_sp_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->hw_arbitration = nca->bytes[0];
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_dc(struct sk_buff *skb,
			       struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_dc_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->ald = nca->bytes[0];
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_rc(struct sk_buff *skb,
			       struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_rc_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_ae(struct sk_buff *skb,
			       struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_ae_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->mc_id = nca->bytes[0];
	cmd->mode = htonl(nca->dwords[1]);
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_sl(struct sk_buff *skb,
			       struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_sl_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->mode = htonl(nca->dwords[0]);
	cmd->oem_mode = htonl(nca->dwords[1]);
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_svf(struct sk_buff *skb,
				struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_svf_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->vlan = htons(nca->words[1]);
	cmd->index = nca->bytes[6];
	cmd->enable = nca->bytes[7];
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_ev(struct sk_buff *skb,
			       struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_ev_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->mode = nca->bytes[3];
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_sma(struct sk_buff *skb,
				struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_sma_pkt *cmd;
	int i;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	for (i = 0; i < 6; i++)
		cmd->mac[i] = nca->bytes[i];
	cmd->index = nca->bytes[6];
	cmd->at_e = nca->bytes[7];
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_ebf(struct sk_buff *skb,
				struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_ebf_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->mode = htonl(nca->dwords[0]);
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_egmf(struct sk_buff *skb,
				 struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_egmf_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->mode = htonl(nca->dwords[0]);
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_snfc(struct sk_buff *skb,
				 struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_snfc_pkt *cmd;

	cmd = skb_put_zero(skb, sizeof(*cmd));
	cmd->mode = nca->bytes[0];
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static int ncsi_cmd_handler_oem(struct sk_buff *skb,
				struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_oem_pkt *cmd;
	unsigned int len;
	int payload;
	/* NC-SI spec DSP_0222_1.2.0, section 8.2.2.2
	 * requires payload to be padded with 0 to
	 * 32-bit boundary before the checksum field.
	 * Ensure the padding bytes are accounted for in
	 * skb allocation
	 */

	payload = ALIGN(nca->payload, 4);
	len = sizeof(struct ncsi_cmd_pkt_hdr) + 4;
	len += max(payload, padding_bytes);

	cmd = skb_put_zero(skb, len);
	unsafe_memcpy(&cmd->mfr_id, nca->data, nca->payload,
		      /* skb allocated with enough to load the payload */);
	ncsi_cmd_build_header(&cmd->cmd.common, nca);

	return 0;
}

static struct ncsi_cmd_handler {
	unsigned char type;
	int           payload;
	int           (*handler)(struct sk_buff *skb,
				 struct ncsi_cmd_arg *nca);
} ncsi_cmd_handlers[] = {
	{ NCSI_PKT_CMD_CIS,    0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_SP,     4, ncsi_cmd_handler_sp      },
	{ NCSI_PKT_CMD_DP,     0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_EC,     0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_DC,     4, ncsi_cmd_handler_dc      },
	{ NCSI_PKT_CMD_RC,     4, ncsi_cmd_handler_rc      },
	{ NCSI_PKT_CMD_ECNT,   0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_DCNT,   0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_AE,     8, ncsi_cmd_handler_ae      },
	{ NCSI_PKT_CMD_SL,     8, ncsi_cmd_handler_sl      },
	{ NCSI_PKT_CMD_GLS,    0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_SVF,    8, ncsi_cmd_handler_svf     },
	{ NCSI_PKT_CMD_EV,     4, ncsi_cmd_handler_ev      },
	{ NCSI_PKT_CMD_DV,     0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_SMA,    8, ncsi_cmd_handler_sma     },
	{ NCSI_PKT_CMD_EBF,    4, ncsi_cmd_handler_ebf     },
	{ NCSI_PKT_CMD_DBF,    0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_EGMF,   4, ncsi_cmd_handler_egmf    },
	{ NCSI_PKT_CMD_DGMF,   0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_SNFC,   4, ncsi_cmd_handler_snfc    },
	{ NCSI_PKT_CMD_GVI,    0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_GC,     0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_GP,     0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_GCPS,   0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_GNS,    0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_GNPTS,  0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_GPS,    0, ncsi_cmd_handler_default },
	{ NCSI_PKT_CMD_OEM,   -1, ncsi_cmd_handler_oem     },
	{ NCSI_PKT_CMD_PLDM,   0, NULL                     },
	{ NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }
};

static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca)
{
	struct ncsi_dev_priv *ndp = nca->ndp;
	struct ncsi_dev *nd = &ndp->ndev;
	struct net_device *dev = nd->dev;
	int hlen = LL_RESERVED_SPACE(dev);
	int tlen = dev->needed_tailroom;
	int payload;
	int len = hlen + tlen;
	struct sk_buff *skb;
	struct ncsi_request *nr;

	nr = ncsi_alloc_request(ndp, nca->req_flags);
	if (!nr)
		return NULL;

	/* NCSI command packet has 16-bytes header, payload, 4 bytes checksum.
	 * Payload needs padding so that the checksum field following payload is
	 * aligned to 32-bit boundary.
	 * The packet needs padding if its payload is less than 26 bytes to
	 * meet 64 bytes minimal ethernet frame length.
	 */
	len += sizeof(struct ncsi_cmd_pkt_hdr) + 4;
	payload = ALIGN(nca->payload, 4);
	len += max(payload, padding_bytes);

	/* Allocate skb */
	skb = alloc_skb(len, GFP_ATOMIC);
	if (!skb) {
		ncsi_free_request(nr);
		return NULL;
	}

	nr->cmd = skb;
	skb_reserve(skb, hlen);
	skb_reset_network_header(skb);

	skb->dev = dev;
	skb->protocol = htons(ETH_P_NCSI);

	return nr;
}

int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
{
	struct ncsi_cmd_handler *nch = NULL;
	struct ncsi_request *nr;
	unsigned char type;
	struct ethhdr *eh;
	int i, ret;

	/* Use OEM generic handler for Netlink request */
	if (nca->req_flags == NCSI_REQ_FLAG_NETLINK_DRIVEN)
		type = NCSI_PKT_CMD_OEM;
	else
		type = nca->type;

	/* Search for the handler */
	for (i = 0; i < ARRAY_SIZE(ncsi_cmd_handlers); i++) {
		if (ncsi_cmd_handlers[i].type == type) {
			if (ncsi_cmd_handlers[i].handler)
				nch = &ncsi_cmd_handlers[i];
			else
				nch = NULL;

			break;
		}
	}

	if (!nch) {
		netdev_err(nca->ndp->ndev.dev,
			   "Cannot send packet with type 0x%02x\n", nca->type);
		return -ENOENT;
	}

	/* Get packet payload length and allocate the request
	 * It is expected that if length set as negative in
	 * handler structure means caller is initializing it
	 * and setting length in nca before calling xmit function
	 */
	if (nch->payload >= 0)
		nca->payload = nch->payload;
	nr = ncsi_alloc_command(nca);
	if (!nr)
		return -ENOMEM;

	/* track netlink information */
	if (nca->req_flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
		nr->snd_seq = nca->info->snd_seq;
		nr->snd_portid = nca->info->snd_portid;
		nr->nlhdr = *nca->info->nlhdr;
	}

	/* Prepare the packet */
	nca->id = nr->id;
	ret = nch->handler(nr->cmd, nca);
	if (ret) {
		ncsi_free_request(nr);
		return ret;
	}

	/* Fill the ethernet header */
	eh = skb_push(nr->cmd, sizeof(*eh));
	eh->h_proto = htons(ETH_P_NCSI);
	eth_broadcast_addr(eh->h_dest);

	/* If mac address received from device then use it for
	 * source address as unicast address else use broadcast
	 * address as source address
	 */
	if (nca->ndp->gma_flag == 1)
		memcpy(eh->h_source, nca->ndp->ndev.dev->dev_addr, ETH_ALEN);
	else
		eth_broadcast_addr(eh->h_source);

	/* Start the timer for the request that might not have
	 * corresponding response. Given NCSI is an internal
	 * connection a 1 second delay should be sufficient.
	 */
	nr->enabled = true;
	mod_timer(&nr->timer, jiffies + 1 * HZ);

	/* Send NCSI packet */
	skb_get(nr->cmd);
	ret = dev_queue_xmit(nr->cmd);
	if (ret < 0) {
		ncsi_free_request(nr);
		return ret;
	}

	return 0;
}
