/* This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file. */

#include <assert.h>
#include <cpio.h>
#include <error.h>
#include <kmalloc.h>
#include <kref.h>
#include <pmap.h>
#include <slab.h>
#include <smp.h>
#include <stdio.h>
#include <string.h>

#include "ethermii.h"

static int miiprobe(struct mii *mii, int mask)
{
	struct miiphy *miiphy;
	int bit, oui, phyno, r, rmask;

	/*
	 * Probe through mii for PHYs in mask;
	 * return the mask of those found in the current probe.
	 * If the PHY has not already been probed, update
	 * the Mii information.
	 */
	rmask = 0;
	for (phyno = 0; phyno < NMiiPhy; phyno++) {
		bit = 1 << phyno;
		if (!(mask & bit))
			continue;
		if (mii->mask & bit) {
			rmask |= bit;
			continue;
		}
		if (mii->rw(mii, 0, phyno, Bmsr, 0) == -1)
			continue;
		r = mii->rw(mii, 0, phyno, Phyidr1, 0) << 16;
		r |= mii->rw(mii, 0, phyno, Phyidr2, 0);
		oui = (r >> 10) & 0xffff;
		if (oui == 0xffff || oui == 0)
			continue;

		if ((miiphy = kzmalloc(sizeof(struct miiphy), 0)) == NULL)
			continue;

		miiphy->mii = mii;
		miiphy->phyno = phyno;
		miiphy->phyid = r;
		miiphy->oui = oui;

		miiphy->anar = ~0;
		miiphy->fc = ~0;
		miiphy->mscr = ~0;

		mii->phy[phyno] = miiphy;
		if (mii->curphy == NULL)
			mii->curphy = miiphy;
		mii->mask |= bit;
		mii->nphy++;

		rmask |= bit;
	}
	return rmask;
}

int miimir(struct mii *mii, int r)
{
	if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
		return -1;
	return mii->rw(mii, 0, mii->curphy->phyno, r, 0);
}

int miimiw(struct mii *mii, int r, int data)
{
	if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
		return -1;
	return mii->rw(mii, 1, mii->curphy->phyno, r, data);
}

int miireset(struct mii *mii)
{
	int bmcr, timeo;

	if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
		return -1;
	bmcr = mii->rw(mii, 0, mii->curphy->phyno, Bmcr, 0);
	mii->rw(mii, 1, mii->curphy->phyno, Bmcr, BmcrR | bmcr);
	for (timeo = 0; timeo < 1000; timeo++) {
		bmcr = mii->rw(mii, 0, mii->curphy->phyno, Bmcr, 0);
		if (!(bmcr & BmcrR))
			break;
		udelay(1);
	}
	if (bmcr & BmcrR)
		return -1;
	if (bmcr & BmcrI)
		mii->rw(mii, 1, mii->curphy->phyno, Bmcr, bmcr & ~BmcrI);
	return 0;
}

int miiane(struct mii *mii, int a, int p, int e)
{
	int anar, bmsr, mscr, r, phyno;

	if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
		return -1;
	phyno = mii->curphy->phyno;

	mii->rw(mii, 1, phyno, Bmsr, 0);
	bmsr = mii->rw(mii, 0, phyno, Bmsr, 0);
	if (!(bmsr & BmsrAna))
		return -1;

	if (a != ~0)
		anar = (AnaTXFD | AnaTXHD | Ana10FD | Ana10HD) & a;
	else if (mii->curphy->anar != ~0)
		anar = mii->curphy->anar;
	else {
		anar = mii->rw(mii, 0, phyno, Anar, 0);
		anar &= ~(AnaAP | AnaP | AnaT4 | AnaTXFD | AnaTXHD | Ana10FD |
		          Ana10HD);
		if (bmsr & Bmsr10THD)
			anar |= Ana10HD;
		if (bmsr & Bmsr10TFD)
			anar |= Ana10FD;
		if (bmsr & Bmsr100TXHD)
			anar |= AnaTXHD;
		if (bmsr & Bmsr100TXFD)
			anar |= AnaTXFD;
	}
	mii->curphy->anar = anar;

	if (p != ~0)
		anar |= (AnaAP | AnaP) & p;
	else if (mii->curphy->fc != ~0)
		anar |= mii->curphy->fc;
	mii->curphy->fc = (AnaAP | AnaP) & anar;

	if (bmsr & BmsrEs) {
		mscr = mii->rw(mii, 0, phyno, Mscr, 0);
		mscr &= ~(Mscr1000TFD | Mscr1000THD);
		if (e != ~0)
			mscr |= (Mscr1000TFD | Mscr1000THD) & e;
		else if (mii->curphy->mscr != ~0)
			mscr = mii->curphy->mscr;
		else {
			r = mii->rw(mii, 0, phyno, Esr, 0);
			if (r & Esr1000THD)
				mscr |= Mscr1000THD;
			if (r & Esr1000TFD)
				mscr |= Mscr1000TFD;
		}
		mii->curphy->mscr = mscr;
		mii->rw(mii, 1, phyno, Mscr, mscr);
	} else
		mii->curphy->mscr = 0;
	mii->rw(mii, 1, phyno, Anar, anar);

	r = mii->rw(mii, 0, phyno, Bmcr, 0);
	if (!(r & BmcrR)) {
		r |= BmcrAne | BmcrRan;
		mii->rw(mii, 1, phyno, Bmcr, r);
	}

	return 0;
}

int miistatus(struct mii *mii)
{
	struct miiphy *phy;
	int anlpar, bmsr, p, r, phyno;

	if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
		return -1;
	phy = mii->curphy;
	phyno = phy->phyno;

	/*
	 * Check Auto-Negotiation is complete and link is up.
	 * (Read status twice as the Ls bit is sticky).
	 */
	bmsr = mii->rw(mii, 0, phyno, Bmsr, 0);
	if (!(bmsr & (BmsrAnc | BmsrAna)))
		return -1;

	bmsr = mii->rw(mii, 0, phyno, Bmsr, 0);
	if (!(bmsr & BmsrLs)) {
		phy->link = 0;
		return -1;
	}

	phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
	if (phy->mscr) {
		r = mii->rw(mii, 0, phyno, Mssr, 0);
		if ((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)) {
			phy->speed = 1000;
			phy->fd = 1;
		} else if ((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
			phy->speed = 1000;
	}

	anlpar = mii->rw(mii, 0, phyno, Anlpar, 0);
	if (phy->speed == 0) {
		r = phy->anar & anlpar;
		if (r & AnaTXFD) {
			phy->speed = 100;
			phy->fd = 1;
		} else if (r & AnaTXHD)
			phy->speed = 100;
		else if (r & Ana10FD) {
			phy->speed = 10;
			phy->fd = 1;
		} else if (r & Ana10HD)
			phy->speed = 10;
	}
	if (phy->speed == 0)
		return -1;

	if (phy->fd) {
		p = phy->fc;
		r = anlpar & (AnaAP | AnaP);
		if (p == AnaAP && r == (AnaAP | AnaP))
			phy->tfc = 1;
		else if (p == (AnaAP | AnaP) && r == AnaAP)
			phy->rfc = 1;
		else if ((p & AnaP) && (r & AnaP))
			phy->rfc = phy->tfc = 1;
	}

	phy->link = 1;

	return 0;
}

char *miidumpphy(struct mii *mii, char *p, char *e)
{
	int i, r;

	if (mii == NULL || mii->curphy == NULL)
		return p;

	p = seprintf(p, e, "phy:   ");
	for (i = 0; i < NMiiPhyr; i++) {
		if (i && ((i & 0x07) == 0))
			p = seprintf(p, e, "\n       ");
		r = mii->rw(mii, 0, mii->curphy->phyno, i, 0);
		p = seprintf(p, e, " %4.4ux", r);
	}
	p = seprintf(p, e, "\n");

	return p;
}

void miidetach(struct mii *mii)
{
	int i;

	for (i = 0; i < NMiiPhy; i++) {
		if (mii->phy[i] == NULL)
			continue;
		kfree(mii);
		mii->phy[i] = NULL;
	}
	kfree(mii);
}

struct mii *miiattach(void *ctlr, int mask,
                      int (*rw)(struct mii *, int unused_int, int, int, int))
{
	struct mii *mii;

	if ((mii = kzmalloc(sizeof(struct mii), 0)) == NULL)
		return NULL;
	mii->ctlr = ctlr;
	mii->rw = rw;

	if (miiprobe(mii, mask) == 0) {
		kfree(mii);
		mii = NULL;
	}

	return mii;
}
