// SPDX-License-Identifier: GPL-2.0+
/*
 * NC-SI protocol configuration
 *
 * Copyright (C) 2019, IBM Corporation.
 */

#include <common.h>
#include <log.h>
#include <malloc.h>
#include <phy.h>
#include <net/ncsi.h>
#include <net/ncsi-pkt.h>
#include <asm/unaligned.h>

#define NCSI_PACKAGE_MAX 8
#define NCSI_CHANNEL_MAX 31

#define NCSI_PACKAGE_SHIFT      5
#define NCSI_PACKAGE_INDEX(c)   (((c) >> NCSI_PACKAGE_SHIFT) & 0x7)
#define NCSI_RESERVED_CHANNEL   0x1f
#define NCSI_CHANNEL_INDEX(c)   ((c) & ((1 << NCSI_PACKAGE_SHIFT) - 1))
#define NCSI_TO_CHANNEL(p, c)   (((p) << NCSI_PACKAGE_SHIFT) | (c))

#define NCSI_PKT_REVISION       0x01

#define NCSI_CAP_GENERIC_MASK	0x7f
#define NCSI_CAP_BC_MASK	0x0f
#define NCSI_CAP_MC_MASK	0x3f
#define NCSI_CAP_AEN_MASK	0x07
#define NCSI_CAP_VLAN_MASK	0x07

static void ncsi_send_ebf(unsigned int np, unsigned int nc);
static void ncsi_send_ae(unsigned int np, unsigned int nc);
static void ncsi_send_gls(unsigned int np, unsigned int nc);
static int ncsi_send_command(unsigned int np, unsigned int nc, unsigned int cmd,
			     uchar *payload, int len, bool wait);

struct ncsi_channel {
	unsigned int	id;
	bool		has_link;

	/* capabilities */
	u32 cap_generic;
	u32 cap_bc;
	u32 cap_mc;
	u32 cap_buffer;
	u32 cap_aen;
	u32 cap_vlan;

	/* version information */
	struct {
		u32 version;            /* Supported BCD encoded NCSI version */
		u32 alpha2;             /* Supported BCD encoded NCSI version */
		u8  fw_name[12];        /* Firmware name string               */
		u32 fw_version;         /* Firmware version                   */
		u16 pci_ids[4];         /* PCI identification                 */
		u32 mf_id;              /* Manufacture ID                     */
	} version;

};

struct ncsi_package {
	unsigned int		id;
	unsigned int		n_channels;
	struct ncsi_channel	*channels;
};

struct ncsi {
	enum {
		NCSI_PROBE_PACKAGE_SP,
		NCSI_PROBE_PACKAGE_DP,
		NCSI_PROBE_CHANNEL_SP,
		NCSI_PROBE_CHANNEL,
		NCSI_CONFIG,
	} state;

	unsigned int	pending_requests;
	unsigned int	requests[256];
	unsigned int	last_request;

	unsigned int	current_package;
	unsigned int	current_channel;

	unsigned int		n_packages;
	struct ncsi_package	*packages;
};

struct ncsi *ncsi_priv;

bool ncsi_active(void)
{
	unsigned int np, nc;

	if (!ncsi_priv)
		return false;

	np = ncsi_priv->current_package;
	nc = ncsi_priv->current_channel;

	if (ncsi_priv->state != NCSI_CONFIG)
		return false;

	return np < NCSI_PACKAGE_MAX && nc < NCSI_CHANNEL_MAX &&
		ncsi_priv->packages[np].channels[nc].has_link;
}

static unsigned int cmd_payload(int cmd)
{
	switch (cmd) {
	case NCSI_PKT_CMD_CIS:
		return 0;
	case NCSI_PKT_CMD_SP:
		return 4;
	case NCSI_PKT_CMD_DP:
		return 0;
	case NCSI_PKT_CMD_EC:
		return 0;
	case NCSI_PKT_CMD_DC:
		return 4;
	case NCSI_PKT_CMD_RC:
		return 4;
	case NCSI_PKT_CMD_ECNT:
		return 0;
	case NCSI_PKT_CMD_DCNT:
		return 0;
	case NCSI_PKT_CMD_AE:
		return 8;
	case NCSI_PKT_CMD_SL:
		return 8;
	case NCSI_PKT_CMD_GLS:
		return 0;
	case NCSI_PKT_CMD_SVF:
		return 8;
	case NCSI_PKT_CMD_EV:
		return 4;
	case NCSI_PKT_CMD_DV:
		return 0;
	case NCSI_PKT_CMD_SMA:
		return 8;
	case NCSI_PKT_CMD_EBF:
		return 4;
	case NCSI_PKT_CMD_DBF:
		return 0;
	case NCSI_PKT_CMD_EGMF:
		return 4;
	case NCSI_PKT_CMD_DGMF:
		return 0;
	case NCSI_PKT_CMD_SNFC:
		return 4;
	case NCSI_PKT_CMD_GVI:
		return 0;
	case NCSI_PKT_CMD_GC:
		return 0;
	case NCSI_PKT_CMD_GP:
		return 0;
	case NCSI_PKT_CMD_GCPS:
		return 0;
	case NCSI_PKT_CMD_GNS:
		return 0;
	case NCSI_PKT_CMD_GNPTS:
		return 0;
	case NCSI_PKT_CMD_GPS:
		return 0;
	default:
		printf("NCSI: Unknown command 0x%02x\n", cmd);
		return 0;
	}
}

static 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;
}

static int ncsi_validate_rsp(struct ncsi_rsp_pkt *pkt, int payload)
{
	struct ncsi_rsp_pkt_hdr *hdr = &pkt->rsp;
	u32 checksum, c_offset;
	__be32 pchecksum;

	if (hdr->common.revision != 1) {
		printf("NCSI: 0x%02x response has unsupported revision 0x%x\n",
		       hdr->common.type, hdr->common.revision);
		return -1;
	}

	if (hdr->code != 0) {
		printf("NCSI: 0x%02x response returns error %d\n",
		       hdr->common.type, __be16_to_cpu(hdr->code));
		if (ntohs(hdr->reason) == 0x05)
			printf("(Invalid command length)\n");
		return -1;
	}

	if (ntohs(hdr->common.length) != payload) {
		printf("NCSI: 0x%02x response has incorrect length %d\n",
		       hdr->common.type, hdr->common.length);
		return -1;
	}

	c_offset = sizeof(struct ncsi_rsp_pkt_hdr) + payload - sizeof(checksum);
	pchecksum = get_unaligned_be32((void *)hdr + c_offset);
	if (pchecksum != 0) {
		checksum = ncsi_calculate_checksum((unsigned char *)hdr,
						   c_offset);
		if (pchecksum != checksum) {
			printf("NCSI: 0x%02x response has invalid checksum\n",
			       hdr->common.type);
			return -1;
		}
	}

	return 0;
}

static void ncsi_rsp_ec(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&pkt->rsp;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	if (ncsi_priv->packages[np].channels[nc].cap_aen != 0)
		ncsi_send_ae(np, nc);
	/* else, done */
}

static void ncsi_rsp_ecnt(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&pkt->rsp;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	ncsi_send_command(np, nc, NCSI_PKT_CMD_EC, NULL, 0, true);
}

static void ncsi_rsp_ebf(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&pkt->rsp;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	ncsi_send_command(np, nc, NCSI_PKT_CMD_ECNT, NULL, 0, true);
}

static void ncsi_rsp_sma(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&pkt->rsp;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	ncsi_send_ebf(np, nc);
}

static void ncsi_rsp_gc(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_gc_pkt *gc = (struct ncsi_rsp_gc_pkt *)pkt;
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&gc->rsp;
	struct ncsi_channel *c;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	if (np >= ncsi_priv->n_packages ||
	    nc >= ncsi_priv->packages[np].n_channels) {
		printf("NCSI: Invalid package / channel (0x%02x, 0x%02x)\n",
		       np, nc);
		return;
	}

	c = &ncsi_priv->packages[np].channels[nc];
	c->cap_generic = ntohl(gc->cap) & NCSI_CAP_GENERIC_MASK;
	c->cap_bc = ntohl(gc->bc_cap) & NCSI_CAP_BC_MASK;
	c->cap_mc = ntohl(gc->mc_cap) & NCSI_CAP_MC_MASK;
	c->cap_aen = ntohl(gc->aen_cap) & NCSI_CAP_AEN_MASK;
	c->cap_vlan = ntohl(gc->vlan_mode) & NCSI_CAP_VLAN_MASK;

	/* End of probe for this channel */
}

static void ncsi_rsp_gvi(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_gvi_pkt *gvi = (struct ncsi_rsp_gvi_pkt *)pkt;
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&gvi->rsp;
	struct ncsi_channel *c;
	unsigned int np, nc, i;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	if (np >= ncsi_priv->n_packages ||
	    nc >= ncsi_priv->packages[np].n_channels) {
		printf("NCSI: Invalid package / channel (0x%02x, 0x%02x)\n",
		       np, nc);
		return;
	}

	c = &ncsi_priv->packages[np].channels[nc];
	c->version.version = get_unaligned_be32(&gvi->ncsi_version);
	c->version.alpha2 = gvi->alpha2;
	memcpy(c->version.fw_name, gvi->fw_name, sizeof(c->version.fw_name));
	c->version.fw_version = get_unaligned_be32(&gvi->fw_version);
	for (i = 0; i < ARRAY_SIZE(c->version.pci_ids); i++)
		c->version.pci_ids[i] = get_unaligned_be16(gvi->pci_ids + i);
	c->version.mf_id = get_unaligned_be32(&gvi->mf_id);

	if (ncsi_priv->state == NCSI_PROBE_CHANNEL)
		ncsi_send_command(np, nc, NCSI_PKT_CMD_GC, NULL, 0, true);
}

static void ncsi_rsp_gls(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_gls_pkt *gls = (struct ncsi_rsp_gls_pkt *)pkt;
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)&gls->rsp;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	if (np >= ncsi_priv->n_packages ||
	    nc >= ncsi_priv->packages[np].n_channels) {
		printf("NCSI: Invalid package / channel (0x%02x, 0x%02x)\n",
		       np, nc);
		return;
	}

	ncsi_priv->packages[np].channels[nc].has_link =
					!!(get_unaligned_be32(&gls->status));

	if (ncsi_priv->state == NCSI_PROBE_CHANNEL)
		ncsi_send_command(np, nc, NCSI_PKT_CMD_GVI, NULL, 0, true);
}

static void ncsi_rsp_cis(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)pkt;
	struct ncsi_package *package;
	unsigned int np, nc;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	nc = NCSI_CHANNEL_INDEX(rsp->common.channel);

	if (np >= ncsi_priv->n_packages) {
		printf("NCSI: Mystery package 0x%02x from CIS\n", np);
		return;
	}

	package = &ncsi_priv->packages[np];

	if (nc < package->n_channels) {
		/*
		 * This is fine in general but in the current design we
		 * don't send CIS commands to known channels.
		 */
		debug("NCSI: Duplicate channel 0x%02x\n", nc);
		return;
	}

	package->channels = realloc(package->channels,
				    sizeof(struct ncsi_channel) *
				    (package->n_channels + 1));
	if (!package->channels) {
		printf("NCSI: Could not allocate memory for new channel\n");
		return;
	}

	debug("NCSI: New channel 0x%02x\n", nc);

	package->channels[nc].id = nc;
	package->channels[nc].has_link = false;
	package->n_channels++;

	ncsi_send_gls(np, nc);
}

static void ncsi_rsp_dp(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)pkt;
	unsigned int np;

	/* No action needed */

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);
	if (np >= ncsi_priv->n_packages)
		debug("NCSI: DP response from unknown package %d\n", np);
}

static void ncsi_rsp_sp(struct ncsi_rsp_pkt *pkt)
{
	struct ncsi_rsp_pkt_hdr *rsp = (struct ncsi_rsp_pkt_hdr *)pkt;
	unsigned int np;

	np = NCSI_PACKAGE_INDEX(rsp->common.channel);

	if (np < ncsi_priv->n_packages) {
		/* Already know about this package */
		debug("NCSI: package 0x%02x selected\n", np);
		return;
	}

	debug("NCSI: adding new package %d\n", np);

	ncsi_priv->packages = realloc(ncsi_priv->packages,
				      sizeof(struct ncsi_package) *
				      (ncsi_priv->n_packages + 1));
	if (!ncsi_priv->packages) {
		printf("NCSI: could not allocate memory for new package\n");
		return;
	}

	ncsi_priv->packages[np].id = np;
	ncsi_priv->packages[np].n_channels = 0;
	ncsi_priv->packages[np].channels = NULL;
	ncsi_priv->n_packages++;
}

static void ncsi_update_state(struct ncsi_rsp_pkt_hdr *nh)
{
	bool timeout = !nh;
	int np, nc;

	switch (ncsi_priv->state) {
	case NCSI_PROBE_PACKAGE_SP:
		if (!timeout &&
		    ncsi_priv->current_package + 1 < NCSI_PACKAGE_MAX) {
			ncsi_priv->current_package++;
		} else {
			ncsi_priv->state = NCSI_PROBE_PACKAGE_DP;
			ncsi_priv->current_package = 0;
		}
		return ncsi_probe_packages();
	case NCSI_PROBE_PACKAGE_DP:
		if (ncsi_priv->current_package + 1 < ncsi_priv->n_packages &&
		    !timeout) {
			ncsi_priv->current_package++;
		} else {
			if (!ncsi_priv->n_packages) {
				printf("NCSI: no packages found\n");
				net_set_state(NETLOOP_FAIL);
				return;
			}
			printf("NCSI: probing channels\n");
			ncsi_priv->state = NCSI_PROBE_CHANNEL_SP;
			ncsi_priv->current_package = 0;
			ncsi_priv->current_channel = 0;
		}
		return ncsi_probe_packages();
	case NCSI_PROBE_CHANNEL_SP:
		if (!timeout && nh->common.type == NCSI_PKT_RSP_SP) {
			ncsi_priv->state = NCSI_PROBE_CHANNEL;
			return ncsi_probe_packages();
		}
		printf("NCSI: failed to select package 0x%0x2 or timeout\n",
		       ncsi_priv->current_package);
		net_set_state(NETLOOP_FAIL);
		break;
	case NCSI_PROBE_CHANNEL:
		// TODO only does package 0 for now
		if (ncsi_priv->pending_requests == 0) {
			np = ncsi_priv->current_package;
			nc = ncsi_priv->current_channel;

			/* Configure first channel that has link */
			if (ncsi_priv->packages[np].channels[nc].has_link) {
				ncsi_priv->state = NCSI_CONFIG;
			} else if (ncsi_priv->current_channel + 1 <
				   NCSI_CHANNEL_MAX) {
				ncsi_priv->current_channel++;
			} else {
				// XXX As above only package 0
				printf("NCSI: no channel found with link\n");
				net_set_state(NETLOOP_FAIL);
				return;
			}
			return ncsi_probe_packages();
		}
		break;
	case NCSI_CONFIG:
		if (ncsi_priv->pending_requests == 0) {
			printf("NCSI: configuration done!\n");
			net_set_state(NETLOOP_SUCCESS);
		} else if (timeout) {
			printf("NCSI: timeout during configure\n");
			net_set_state(NETLOOP_FAIL);
		}
		break;
	default:
		printf("NCSI: something went very wrong, nevermind\n");
		net_set_state(NETLOOP_FAIL);
		break;
	}
}

static void ncsi_timeout_handler(void)
{
	if (ncsi_priv->pending_requests)
		ncsi_priv->pending_requests--;

	ncsi_update_state(NULL);
}

static int ncsi_send_command(unsigned int np, unsigned int nc, unsigned int cmd,
			     uchar *payload, int len, bool wait)
{
	struct ncsi_pkt_hdr *hdr;
	__be32 *pchecksum;
	int eth_hdr_size;
	u32 checksum;
	uchar *pkt, *start;
	int final_len;

	pkt = calloc(1, PKTSIZE_ALIGN + PKTALIGN);
	if (!pkt)
		return -ENOMEM;
	start = pkt;

	eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_NCSI);
	pkt += eth_hdr_size;

	/* Set NCSI command header fields */
	hdr = (struct ncsi_pkt_hdr *)pkt;
	hdr->mc_id = 0;
	hdr->revision = NCSI_PKT_REVISION;
	hdr->id = ++ncsi_priv->last_request;
	ncsi_priv->requests[ncsi_priv->last_request] = 1;
	hdr->type = cmd;
	hdr->channel = NCSI_TO_CHANNEL(np, nc);
	hdr->length = htons(len);

	if (payload && len)
		memcpy(pkt + sizeof(struct ncsi_pkt_hdr), payload, len);

	/* Calculate checksum */
	checksum = ncsi_calculate_checksum((unsigned char *)hdr,
					   sizeof(*hdr) + len);
	pchecksum = (__be32 *)((void *)(hdr + 1) + len);
	put_unaligned_be32(htonl(checksum), pchecksum);

	if (wait) {
		net_set_timeout_handler(1000UL, ncsi_timeout_handler);
		ncsi_priv->pending_requests++;
	}

	if (len < 26)
		len = 26;
	/* frame header, packet header, payload, checksum */
	final_len = eth_hdr_size + sizeof(struct ncsi_cmd_pkt_hdr) + len + 4;

	net_send_packet(start, final_len);
	free(start);
	return 0;
}

static void ncsi_handle_aen(struct ip_udp_hdr *ip, unsigned int len)
{
	struct ncsi_aen_pkt_hdr *hdr = (struct ncsi_aen_pkt_hdr *)ip;
	int payload, i;
	__be32 pchecksum;
	u32 checksum;

	switch (hdr->type) {
	case NCSI_PKT_AEN_LSC:
		printf("NCSI: link state changed\n");
		payload = 12;
		break;
	case NCSI_PKT_AEN_CR:
		printf("NCSI: re-configuration required\n");
		payload = 4;
		break;
	case NCSI_PKT_AEN_HNCDSC:
		/* Host notifcation - N/A but weird */
		debug("NCSI: HNCDSC AEN received\n");
		return;
	default:
		printf("%s: Invalid type 0x%02x\n", __func__, hdr->type);
		return;
	}

	/* Validate packet */
	if (hdr->common.revision != 1) {
		printf("NCSI: 0x%02x response has unsupported revision 0x%x\n",
		       hdr->common.type, hdr->common.revision);
		return;
	}

	if (ntohs(hdr->common.length) != payload) {
		printf("NCSI: 0x%02x response has incorrect length %d\n",
		       hdr->common.type, hdr->common.length);
		return;
	}

	pchecksum = get_unaligned_be32((void *)(hdr + 1) + payload - 4);
	if (pchecksum != 0) {
		checksum = ncsi_calculate_checksum((unsigned char *)hdr,
						   sizeof(*hdr) + payload - 4);
		if (pchecksum != checksum) {
			printf("NCSI: 0x%02x response has invalid checksum\n",
			       hdr->common.type);
			return;
		}
	}

	/* Link or configuration lost - just redo the discovery process */
	ncsi_priv->state = NCSI_PROBE_PACKAGE_SP;
	for (i = 0; i < ncsi_priv->n_packages; i++)
		free(ncsi_priv->packages[i].channels);
	free(ncsi_priv->packages);
	ncsi_priv->n_packages = 0;

	ncsi_priv->current_package = NCSI_PACKAGE_MAX;
	ncsi_priv->current_channel = NCSI_CHANNEL_MAX;

	ncsi_probe_packages();
}

void ncsi_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip,
		  unsigned int len)
{
	struct ncsi_rsp_pkt *pkt = (struct ncsi_rsp_pkt *)ip;
	struct ncsi_rsp_pkt_hdr *nh = (struct ncsi_rsp_pkt_hdr *)&pkt->rsp;
	void (*handler)(struct ncsi_rsp_pkt *pkt) = NULL;
	unsigned short payload;

	if (ncsi_priv->pending_requests)
		ncsi_priv->pending_requests--;

	if (len < sizeof(struct ncsi_rsp_pkt_hdr)) {
		printf("NCSI: undersized packet: %u bytes\n", len);
		goto out;
	}

	if (nh->common.type == NCSI_PKT_AEN)
		return ncsi_handle_aen(ip, len);

	switch (nh->common.type) {
	case NCSI_PKT_RSP_SP:
		payload = 4;
		handler = ncsi_rsp_sp;
		break;
	case NCSI_PKT_RSP_DP:
		payload = 4;
		handler = ncsi_rsp_dp;
		break;
	case NCSI_PKT_RSP_CIS:
		payload = 4;
		handler = ncsi_rsp_cis;
		break;
	case NCSI_PKT_RSP_GLS:
		payload = 16;
		handler = ncsi_rsp_gls;
		break;
	case NCSI_PKT_RSP_GVI:
		payload = 40;
		handler = ncsi_rsp_gvi;
		break;
	case NCSI_PKT_RSP_GC:
		payload = 32;
		handler = ncsi_rsp_gc;
		break;
	case NCSI_PKT_RSP_SMA:
		payload = 4;
		handler = ncsi_rsp_sma;
		break;
	case NCSI_PKT_RSP_EBF:
		payload = 4;
		handler = ncsi_rsp_ebf;
		break;
	case NCSI_PKT_RSP_ECNT:
		payload = 4;
		handler = ncsi_rsp_ecnt;
		break;
	case NCSI_PKT_RSP_EC:
		payload = 4;
		handler = ncsi_rsp_ec;
		break;
	case NCSI_PKT_RSP_AE:
		payload = 4;
		handler = NULL;
		break;
	default:
		printf("NCSI: unsupported packet type 0x%02x\n",
		       nh->common.type);
		goto out;
	}

	if (ncsi_validate_rsp(pkt, payload) != 0) {
		printf("NCSI: discarding invalid packet of type 0x%02x\n",
		       nh->common.type);
		goto out;
	}

	if (handler)
		handler(pkt);
out:
	ncsi_update_state(nh);
}

static void ncsi_send_sp(unsigned int np)
{
	uchar payload[4] = {0};

	ncsi_send_command(np, NCSI_RESERVED_CHANNEL, NCSI_PKT_CMD_SP,
			  (unsigned char *)&payload,
			  cmd_payload(NCSI_PKT_CMD_SP), true);
}

static void ncsi_send_dp(unsigned int np)
{
	ncsi_send_command(np, NCSI_RESERVED_CHANNEL, NCSI_PKT_CMD_DP, NULL, 0,
			  true);
}

static void ncsi_send_gls(unsigned int np, unsigned int nc)
{
	ncsi_send_command(np, nc, NCSI_PKT_CMD_GLS, NULL, 0, true);
}

static void ncsi_send_cis(unsigned int np, unsigned int nc)
{
	ncsi_send_command(np, nc, NCSI_PKT_CMD_CIS, NULL, 0, true);
}

static void ncsi_send_ae(unsigned int np, unsigned int nc)
{
	struct ncsi_cmd_ae_pkt cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.mode = htonl(ncsi_priv->packages[np].channels[nc].cap_aen);

	ncsi_send_command(np, nc, NCSI_PKT_CMD_AE,
			  ((unsigned char *)&cmd)
			  + sizeof(struct ncsi_cmd_pkt_hdr),
			  cmd_payload(NCSI_PKT_CMD_AE), true);
}

static void ncsi_send_ebf(unsigned int np, unsigned int nc)
{
	struct ncsi_cmd_ebf_pkt cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.mode = htonl(ncsi_priv->packages[np].channels[nc].cap_bc);

	ncsi_send_command(np, nc, NCSI_PKT_CMD_EBF,
			  ((unsigned char *)&cmd)
			  + sizeof(struct ncsi_cmd_pkt_hdr),
			  cmd_payload(NCSI_PKT_CMD_EBF), true);
}

static void ncsi_send_sma(unsigned int np, unsigned int nc)
{
	struct ncsi_cmd_sma_pkt cmd;
	unsigned char *addr, i;

	addr = eth_get_ethaddr();
	if (!addr) {
		printf("NCSI: no MAC address configured\n");
		return;
	}

	memset(&cmd, 0, sizeof(cmd));
	for (i = 0; i < ARP_HLEN; i++)
		cmd.mac[i] = addr[i];
	cmd.index = 1;
	cmd.at_e = 1;

	ncsi_send_command(np, nc, NCSI_PKT_CMD_SMA,
			  ((unsigned char *)&cmd)
			  + sizeof(struct ncsi_cmd_pkt_hdr),
			  cmd_payload(NCSI_PKT_CMD_SMA), true);
}

void ncsi_probe_packages(void)
{
	struct ncsi_package *package;
	unsigned int np, nc;

	switch (ncsi_priv->state) {
	case NCSI_PROBE_PACKAGE_SP:
		if (ncsi_priv->current_package == NCSI_PACKAGE_MAX)
			ncsi_priv->current_package = 0;
		ncsi_send_sp(ncsi_priv->current_package);
		break;
	case NCSI_PROBE_PACKAGE_DP:
		ncsi_send_dp(ncsi_priv->current_package);
		break;
	case NCSI_PROBE_CHANNEL_SP:
		if (ncsi_priv->n_packages > 0)
			ncsi_send_sp(ncsi_priv->current_package);
		else
			printf("NCSI: no packages discovered, configuration not possible\n");
		break;
	case NCSI_PROBE_CHANNEL:
		/* Kicks off chain of channel discovery */
		ncsi_send_cis(ncsi_priv->current_package,
			      ncsi_priv->current_channel);
		break;
	case NCSI_CONFIG:
		for (np = 0; np < ncsi_priv->n_packages; np++) {
			package = &ncsi_priv->packages[np];
			for (nc = 0; nc < package->n_channels; nc++)
				if (package->channels[nc].has_link)
					break;
			if (nc < package->n_channels)
				break;
		}
		if (np == ncsi_priv->n_packages) {
			printf("NCSI: no link available\n");
			return;
		}

		printf("NCSI: configuring channel %d\n", nc);
		ncsi_priv->current_package = np;
		ncsi_priv->current_channel = nc;
		/* Kicks off rest of configure chain */
		ncsi_send_sma(np, nc);
		break;
	default:
		printf("NCSI: unknown state 0x%x\n", ncsi_priv->state);
	}
}

int ncsi_probe(struct phy_device *phydev)
{
	if (!phydev->priv) {
		phydev->priv = malloc(sizeof(struct ncsi));
		if (!phydev->priv)
			return -ENOMEM;
		memset(phydev->priv, 0, sizeof(struct ncsi));
	}

	ncsi_priv = phydev->priv;

	return 0;
}

int ncsi_startup(struct phy_device *phydev)
{
	/* Set phydev parameters */
	phydev->speed = SPEED_100;
	phydev->duplex = DUPLEX_FULL;
	/* Normal phy reset is N/A */
	phydev->flags |= PHY_FLAG_BROKEN_RESET;

	/* Set initial probe state */
	ncsi_priv->state = NCSI_PROBE_PACKAGE_SP;

	/* No active package/channel yet */
	ncsi_priv->current_package = NCSI_PACKAGE_MAX;
	ncsi_priv->current_channel = NCSI_CHANNEL_MAX;

	/* Pretend link works so the MAC driver sets final bits up */
	phydev->link = true;

	/* Set ncsi_priv so we can use it when called from net_loop() */
	ncsi_priv = phydev->priv;

	return 0;
}

int ncsi_shutdown(struct phy_device *phydev)
{
	printf("NCSI: Disabling package %d\n", ncsi_priv->current_package);
	ncsi_send_dp(ncsi_priv->current_package);
	return 0;
}

static struct phy_driver ncsi_driver = {
	.uid		= PHY_NCSI_ID,
	.mask		= 0xffffffff,
	.name		= "NC-SI",
	.features	= PHY_100BT_FEATURES | PHY_DEFAULT_FEATURES |
				SUPPORTED_100baseT_Full | SUPPORTED_MII,
	.probe		= ncsi_probe,
	.startup	= ncsi_startup,
	.shutdown	= ncsi_shutdown,
};

int phy_ncsi_init(void)
{
	phy_register(&ncsi_driver);
	return 0;
}
