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

#include <common.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;
}
