// 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.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;
}
