/*
 * MPC8560 FCC Fast Ethernet
 * Copyright (c) 2003 Motorola,Inc.
 * Xianghua Xiao, (X.Xiao@motorola.com)
 *
 * Copyright (c) 2000 MontaVista Software, Inc.   Dan Malek (dmalek@jlc.net)
 *
 * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * MPC8560 FCC Fast Ethernet
 * Basic ET HW initialization and packet RX/TX routines
 *
 * This code will not perform the IO port configuration. This should be
 * done in the iop_conf_t structure specific for the board.
 *
 * TODO:
 * add a PHY driver to do the negotiation
 * reflect negotiation results in FPSMR
 * look for ways to configure the board specific stuff elsewhere, eg.
 *    config_xxx.h or the board directory
 */

#include <common.h>
#include <malloc.h>
#include <asm/cpm_85xx.h>
#include <command.h>
#include <config.h>
#include <net.h>

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
#include <miiphy.h>
#endif

#if defined(CONFIG_ETHER_ON_FCC) && defined(CONFIG_CMD_NET) && \
	defined(CONFIG_NET_MULTI)

static struct ether_fcc_info_s
{
	int ether_index;
	int proff_enet;
	ulong cpm_cr_enet_sblock;
	ulong cpm_cr_enet_page;
	ulong cmxfcr_mask;
	ulong cmxfcr_value;
}
	ether_fcc_info[] =
{
#ifdef CONFIG_ETHER_ON_FCC1
{
	0,
	PROFF_FCC1,
	CPM_CR_FCC1_SBLOCK,
	CPM_CR_FCC1_PAGE,
	CONFIG_SYS_CMXFCR_MASK1,
	CONFIG_SYS_CMXFCR_VALUE1
},
#endif

#ifdef CONFIG_ETHER_ON_FCC2
{
	1,
	PROFF_FCC2,
	CPM_CR_FCC2_SBLOCK,
	CPM_CR_FCC2_PAGE,
	CONFIG_SYS_CMXFCR_MASK2,
	CONFIG_SYS_CMXFCR_VALUE2
},
#endif

#ifdef CONFIG_ETHER_ON_FCC3
{
	2,
	PROFF_FCC3,
	CPM_CR_FCC3_SBLOCK,
	CPM_CR_FCC3_PAGE,
	CONFIG_SYS_CMXFCR_MASK3,
	CONFIG_SYS_CMXFCR_VALUE3
},
#endif
};

/*---------------------------------------------------------------------*/

/* Maximum input DMA size.  Must be a should(?) be a multiple of 4. */
#define PKT_MAXDMA_SIZE         1520

/* The FCC stores dest/src/type, data, and checksum for receive packets. */
#define PKT_MAXBUF_SIZE         1518
#define PKT_MINBUF_SIZE         64

/* Maximum input buffer size.  Must be a multiple of 32. */
#define PKT_MAXBLR_SIZE         1536

#define TOUT_LOOP 1000000

#define TX_BUF_CNT 2

static uint rxIdx;	/* index of the current RX buffer */
static uint txIdx;	/* index of the current TX buffer */

/*
 * FCC Ethernet Tx and Rx buffer descriptors.
 * Provide for Double Buffering
 * Note: PKTBUFSRX is defined in net.h
 */

typedef volatile struct rtxbd {
    cbd_t rxbd[PKTBUFSRX];
    cbd_t txbd[TX_BUF_CNT];
} RTXBD;

/*  Good news: the FCC supports external BDs! */
#ifdef __GNUC__
static RTXBD rtx __attribute__ ((aligned(8)));
#else
#error "rtx must be 64-bit aligned"
#endif

#undef ET_DEBUG

static int fec_send(struct eth_device* dev, volatile void *packet, int length)
{
    int i = 0;
    int result = 0;

    if (length <= 0) {
	printf("fec: bad packet size: %d\n", length);
	goto out;
    }

    for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
	if (i >= TOUT_LOOP) {
	    printf("fec: tx buffer not ready\n");
	    goto out;
	}
    }

    rtx.txbd[txIdx].cbd_bufaddr = (uint)packet;
    rtx.txbd[txIdx].cbd_datlen = length;
    rtx.txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST | \
			       BD_ENET_TX_TC | BD_ENET_TX_PAD);

    for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
	if (i >= TOUT_LOOP) {
	    printf("fec: tx error\n");
	    goto out;
	}
    }

#ifdef ET_DEBUG
    printf("cycles: 0x%x txIdx=0x%04x status: 0x%04x\n", i, txIdx,rtx.txbd[txIdx].cbd_sc);
    printf("packets at 0x%08x, length_in_bytes=0x%x\n",(uint)packet,length);
    for(i=0;i<(length/16 + 1);i++) {
	 printf("%08x %08x %08x %08x\n",*((uint *)rtx.txbd[txIdx].cbd_bufaddr+i*4),\
    *((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 1),*((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 2), \
    *((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 3));
    }
#endif

    /* return only status bits */
    result = rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_STATS;
    txIdx = (txIdx + 1) % TX_BUF_CNT;

out:
    return result;
}

static int fec_recv(struct eth_device* dev)
{
    int length;

    for (;;)
    {
	if (rtx.rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
	    length = -1;
	    break;     /* nothing received - leave for() loop */
	}
	length = rtx.rxbd[rxIdx].cbd_datlen;

	if (rtx.rxbd[rxIdx].cbd_sc & 0x003f) {
	    printf("fec: rx error %04x\n", rtx.rxbd[rxIdx].cbd_sc);
	}
	else {
	    /* Pass the packet up to the protocol layers. */
	    NetReceive(NetRxPackets[rxIdx], length - 4);
	}


	/* Give the buffer back to the FCC. */
	rtx.rxbd[rxIdx].cbd_datlen = 0;

	/* wrap around buffer index when necessary */
	if ((rxIdx + 1) >= PKTBUFSRX) {
	    rtx.rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
	    rxIdx = 0;
	}
	else {
	    rtx.rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
	    rxIdx++;
	}
    }
    return length;
}


static int fec_init(struct eth_device* dev, bd_t *bis)
{
    struct ether_fcc_info_s * info = dev->priv;
    int i;
    volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR;
    volatile ccsr_cpm_cp_t *cp = &(cpm->im_cpm_cp);
    fcc_enet_t *pram_ptr;
    unsigned long mem_addr;

#if 0
    mii_discover_phy();
#endif

    /* 28.9 - (1-2): ioports have been set up already */

    /* 28.9 - (3): connect FCC's tx and rx clocks */
    cpm->im_cpm_mux.cmxuar = 0; /* ATM */
    cpm->im_cpm_mux.cmxfcr = (cpm->im_cpm_mux.cmxfcr & ~info->cmxfcr_mask) |
							info->cmxfcr_value;

    /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, set Mode Ethernet */
    if(info->ether_index == 0) {
	cpm->im_cpm_fcc1.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
    } else if (info->ether_index == 1) {
	cpm->im_cpm_fcc2.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
    } else if (info->ether_index == 2) {
	cpm->im_cpm_fcc3.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
    }

    /* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet,MII */
    if(info->ether_index == 0) {
	cpm->im_cpm_fcc1.fpsmr = CONFIG_SYS_FCC_PSMR | FCC_PSMR_ENCRC;
    } else if (info->ether_index == 1){
	cpm->im_cpm_fcc2.fpsmr = CONFIG_SYS_FCC_PSMR | FCC_PSMR_ENCRC;
    } else if (info->ether_index == 2){
	cpm->im_cpm_fcc3.fpsmr = CONFIG_SYS_FCC_PSMR | FCC_PSMR_ENCRC;
    }

    /* 28.9 - (6): FDSR: Ethernet Syn */
    if(info->ether_index == 0) {
	cpm->im_cpm_fcc1.fdsr = 0xD555;
    } else if (info->ether_index == 1) {
	cpm->im_cpm_fcc2.fdsr = 0xD555;
    } else if (info->ether_index == 2) {
	cpm->im_cpm_fcc3.fdsr = 0xD555;
    }

    /* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */
    rxIdx = 0;
    txIdx = 0;

    /* Setup Receiver Buffer Descriptors */
    for (i = 0; i < PKTBUFSRX; i++)
    {
      rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
      rtx.rxbd[i].cbd_datlen = 0;
      rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
    }
    rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;

    /* Setup Ethernet Transmitter Buffer Descriptors */
    for (i = 0; i < TX_BUF_CNT; i++)
    {
      rtx.txbd[i].cbd_sc = 0;
      rtx.txbd[i].cbd_datlen = 0;
      rtx.txbd[i].cbd_bufaddr = 0;
    }
    rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;

    /* 28.9 - (7): initialize parameter ram */
    pram_ptr = (fcc_enet_t *)&(cpm->im_dprambase[info->proff_enet]);

    /* clear whole structure to make sure all reserved fields are zero */
    memset((void*)pram_ptr, 0, sizeof(fcc_enet_t));

    /*
     * common Parameter RAM area
     *
     * Allocate space in the reserved FCC area of DPRAM for the
     * internal buffers.  No one uses this space (yet), so we
     * can do this.  Later, we will add resource management for
     * this area.
     * CPM_FCC_SPECIAL_BASE:	0xB000 for MPC8540, MPC8560
     *				0x9000 for MPC8541, MPC8555
     */
    mem_addr = CPM_FCC_SPECIAL_BASE + ((info->ether_index) * 64);
    pram_ptr->fen_genfcc.fcc_riptr = mem_addr;
    pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32;
    /*
     * Set maximum bytes per receive buffer.
     * It must be a multiple of 32.
     */
    pram_ptr->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; /* 1536 */
    /* localbus SDRAM should be preferred */
    pram_ptr->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB |
				       CONFIG_SYS_CPMFCR_RAMTYPE) << 24;
    pram_ptr->fen_genfcc.fcc_rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
    pram_ptr->fen_genfcc.fcc_rbdstat = 0;
    pram_ptr->fen_genfcc.fcc_rbdlen = 0;
    pram_ptr->fen_genfcc.fcc_rdptr = 0;
    /* localbus SDRAM should be preferred */
    pram_ptr->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB |
				       CONFIG_SYS_CPMFCR_RAMTYPE) << 24;
    pram_ptr->fen_genfcc.fcc_tbase = (unsigned int)(&rtx.txbd[txIdx]);
    pram_ptr->fen_genfcc.fcc_tbdstat = 0;
    pram_ptr->fen_genfcc.fcc_tbdlen = 0;
    pram_ptr->fen_genfcc.fcc_tdptr = 0;

    /* protocol-specific area */
    pram_ptr->fen_statbuf = 0x0;
    pram_ptr->fen_cmask = 0xdebb20e3;	/* CRC mask */
    pram_ptr->fen_cpres = 0xffffffff;	/* CRC preset */
    pram_ptr->fen_crcec = 0;
    pram_ptr->fen_alec = 0;
    pram_ptr->fen_disfc = 0;
    pram_ptr->fen_retlim = 15;		/* Retry limit threshold */
    pram_ptr->fen_retcnt = 0;
    pram_ptr->fen_pper = 0;
    pram_ptr->fen_boffcnt = 0;
    pram_ptr->fen_gaddrh = 0;
    pram_ptr->fen_gaddrl = 0;
    pram_ptr->fen_mflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
    /*
     * Set Ethernet station address.
     *
     * This is supplied in the board information structure, so we
     * copy that into the controller.
     * So far we have only been given one Ethernet address. We make
     * it unique by setting a few bits in the upper byte of the
     * non-static part of the address.
     */
#define ea eth_get_dev()->enetaddr
    pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
    pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
    pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
#undef ea
    pram_ptr->fen_ibdcount = 0;
    pram_ptr->fen_ibdstart = 0;
    pram_ptr->fen_ibdend = 0;
    pram_ptr->fen_txlen = 0;
    pram_ptr->fen_iaddrh = 0;  /* disable hash */
    pram_ptr->fen_iaddrl = 0;
    pram_ptr->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register: 64 */
    /* pad pointer. use tiptr since we don't need a specific padding char */
    pram_ptr->fen_padptr = pram_ptr->fen_genfcc.fcc_tiptr;
    pram_ptr->fen_maxd1 = PKT_MAXDMA_SIZE;	/* maximum DMA1 length:1520 */
    pram_ptr->fen_maxd2 = PKT_MAXDMA_SIZE;	/* maximum DMA2 length:1520 */

#if defined(ET_DEBUG)
    printf("parm_ptr(0xff788500) = %p\n",pram_ptr);
    printf("pram_ptr->fen_genfcc.fcc_rbase %08x\n",
	pram_ptr->fen_genfcc.fcc_rbase);
    printf("pram_ptr->fen_genfcc.fcc_tbase %08x\n",
	pram_ptr->fen_genfcc.fcc_tbase);
#endif

    /* 28.9 - (8)(9): clear out events in FCCE */
    /* 28.9 - (9): FCCM: mask all events */
    if(info->ether_index == 0) {
	cpm->im_cpm_fcc1.fcce = ~0x0;
	cpm->im_cpm_fcc1.fccm = 0;
    } else if (info->ether_index == 1) {
	cpm->im_cpm_fcc2.fcce = ~0x0;
	cpm->im_cpm_fcc2.fccm = 0;
    } else if (info->ether_index == 2) {
	cpm->im_cpm_fcc3.fcce = ~0x0;
	cpm->im_cpm_fcc3.fccm = 0;
    }

    /* 28.9 - (10-12): we don't use ethernet interrupts */

    /* 28.9 - (13)
     *
     * Let's re-initialize the channel now.  We have to do it later
     * than the manual describes because we have just now finished
     * the BD initialization.
     */
    cp->cpcr = mk_cr_cmd(info->cpm_cr_enet_page,
			    info->cpm_cr_enet_sblock,
			    0x0c,
			    CPM_CR_INIT_TRX) | CPM_CR_FLG;
    do {
	__asm__ __volatile__ ("eieio");
    } while (cp->cpcr & CPM_CR_FLG);

    /* 28.9 - (14): enable tx/rx in gfmr */
    if(info->ether_index == 0) {
	cpm->im_cpm_fcc1.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
    } else if (info->ether_index == 1) {
	cpm->im_cpm_fcc2.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
    } else if (info->ether_index == 2) {
	cpm->im_cpm_fcc3.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
    }

    return 1;
}

static void fec_halt(struct eth_device* dev)
{
    struct ether_fcc_info_s * info = dev->priv;
    volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR;

    /* write GFMR: disable tx/rx */
    if(info->ether_index == 0) {
	cpm->im_cpm_fcc1.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
    } else if(info->ether_index == 1) {
	cpm->im_cpm_fcc2.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
    } else if(info->ether_index == 2) {
	cpm->im_cpm_fcc3.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
    }
}

int fec_initialize(bd_t *bis)
{
	struct eth_device* dev;
	int i;

	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
	{
		dev = (struct eth_device*) malloc(sizeof *dev);
		memset(dev, 0, sizeof *dev);

		sprintf(dev->name, "FCC%d ETHERNET",
			ether_fcc_info[i].ether_index + 1);
		dev->priv   = &ether_fcc_info[i];
		dev->init   = fec_init;
		dev->halt   = fec_halt;
		dev->send   = fec_send;
		dev->recv   = fec_recv;

		eth_register(dev);

#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
		&& defined(CONFIG_BITBANGMII)
		miiphy_register(dev->name,
				bb_miiphy_read,	bb_miiphy_write);
#endif
	}

	return 1;
}

#endif
