/*
 * Copyright 2012 Freescale Semiconductor, Inc.
 *	Roy Zang <tie-fei.zang@freescale.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/* MAXFRM - maximum frame length */
#define MAXFRM_MASK	0x0000ffff

#include <common.h>
#include <phy.h>
#include <asm/types.h>
#include <asm/io.h>
#include <asm/fsl_memac.h>

#include "fm.h"

static void memac_init_mac(struct fsl_enet_mac *mac)
{
	struct memac *regs = mac->base;

	/* mask all interrupt */
	out_be32(&regs->imask, IMASK_MASK_ALL);

	/* clear all events */
	out_be32(&regs->ievent, IEVENT_CLEAR_ALL);

	/* set the max receive length */
	out_be32(&regs->maxfrm, mac->max_rx_len & MAXFRM_MASK);

	/* multicast frame reception for the hash entry disable */
	out_be32(&regs->hashtable_ctrl, 0);
}

static void memac_enable_mac(struct fsl_enet_mac *mac)
{
	struct memac *regs = mac->base;

	setbits_be32(&regs->command_config, MEMAC_CMD_CFG_RXTX_EN);
}

static void memac_disable_mac(struct fsl_enet_mac *mac)
{
	struct memac *regs = mac->base;

	clrbits_be32(&regs->command_config, MEMAC_CMD_CFG_RXTX_EN);
}

static void memac_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr)
{
	struct memac *regs = mac->base;
	u32 mac_addr0, mac_addr1;

	/*
	 * if a station address of 0x12345678ABCD, perform a write to
	 * MAC_ADDR0 of 0x78563412, MAC_ADDR1 of 0x0000CDAB
	 */
	mac_addr0 = (mac_addr[3] << 24) | (mac_addr[2] << 16) | \
			(mac_addr[1] << 8)  | (mac_addr[0]);
	out_be32(&regs->mac_addr_0, mac_addr0);

	mac_addr1 = ((mac_addr[5] << 8) | mac_addr[4]) & 0x0000ffff;
	out_be32(&regs->mac_addr_1, mac_addr1);
}

static void memac_set_interface_mode(struct fsl_enet_mac *mac,
					phy_interface_t type, int speed)
{
	/* Roy need more work here */

	struct memac *regs = mac->base;
	u32 if_mode, if_status;

	/* clear all bits relative with interface mode */
	if_mode = in_be32(&regs->if_mode);
	if_status = in_be32(&regs->if_status);

	/* set interface mode */
	switch (type) {
	case PHY_INTERFACE_MODE_GMII:
		if_mode &= ~IF_MODE_MASK;
		if_mode |= IF_MODE_GMII;
		break;
	case PHY_INTERFACE_MODE_RGMII:
		if_mode |= (IF_MODE_GMII | IF_MODE_RG);
		break;
	case PHY_INTERFACE_MODE_RMII:
		if_mode |= (IF_MODE_GMII | IF_MODE_RM);
		break;
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
		if_mode &= ~IF_MODE_MASK;
		if_mode |= (IF_MODE_GMII);
		break;
	default:
		break;
	}
	/* Enable automatic speed selection */
	if_mode |= IF_MODE_EN_AUTO;

	if (type == PHY_INTERFACE_MODE_RGMII) {
		if_mode &= ~IF_MODE_EN_AUTO;
		if_mode &= ~IF_MODE_SETSP_MASK;
		switch (speed) {
		case SPEED_1000:
			if_mode |= IF_MODE_SETSP_1000M;
			break;
		case SPEED_100:
			if_mode |= IF_MODE_SETSP_100M;
			break;
		case SPEED_10:
			if_mode |= IF_MODE_SETSP_10M;
		default:
			break;
		}
	}

	debug(" %s, if_mode = %x\n", __func__,  if_mode);
	debug(" %s, if_status = %x\n", __func__,  if_status);
	out_be32(&regs->if_mode, if_mode);
	return;
}

void init_memac(struct fsl_enet_mac *mac, void *base,
		void *phyregs, int max_rx_len)
{
	mac->base = base;
	mac->phyregs = phyregs;
	mac->max_rx_len = max_rx_len;
	mac->init_mac = memac_init_mac;
	mac->enable_mac = memac_enable_mac;
	mac->disable_mac = memac_disable_mac;
	mac->set_mac_addr = memac_set_mac_addr;
	mac->set_if_mode = memac_set_interface_mode;
}
