This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-K2H: We are building processor SDK linux for k2hk-evm

Part Number: PROCESSOR-SDK-K2H

Hello everyone,

                         

                          We have Implemented Ethernet  phy related changes in u-boot net driver MCSDK for SFP integration in TI k2hk evm , but we need to implement same changes in PDK for same board but  since the structure of the program is different  from MCSDK to PDK I need your support  regarding  this ethernet changes so how to proceed with this.

The corresponding MCSDK changes to is given in below ethernet driver file keystone_net.c file and phy address and other info is saved in board/ti/ks2_evm/board_k2hk.c.

Thanks and regards,

Phaneesh A Kashyap

keystone_net.c
/*
 * Ethernet driver for TI KS2 EVM.
 *
 * Copyright (C) 2012 Texas Instruments Incorporated
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <common.h>
#include <command.h>

#include <asm/arch/hardware.h>
#include <net.h>
#include <miiphy.h>
#include <malloc.h>
#include <asm/arch/emac_defs.h>
#include <asm/arch/psc_defs.h>
#include <asm/arch/keystone_nav.h>

unsigned int emac_dbg = 0;
#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args)

unsigned int emac_open = 0;
unsigned int xmac_open;
static unsigned int loopback_test = 0;
static unsigned int sys_has_mdio = 1;

#ifdef KS2_EMAC_GIG_ENABLE
#define emac_gigabit_enable(x)	keystone2_eth_gigabit_enable(x)
#else
#define emac_gigabit_enable(x)	/* no gigabit to enable */
#endif

#define RX_BUFF_NUMS	24
#define RX_BUFF_LEN	1520
#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN

#define PHY_CALC_MASK(fieldOffset, fieldLen, mask)		\
	if ((fieldLen + fieldOffset) >= 16)			\
		mask = (0 - (1 << fieldOffset));		\
	else							\
		mask = (((1 << (fieldLen + fieldOffset))) - (1 << fieldOffset))

static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __attribute__((aligned(16)));

struct rx_buff_desc net_rx_buffs = {
	.buff_ptr	= rx_buffs,
	.num_buffs	= RX_BUFF_NUMS,
	.buff_len	= RX_BUFF_LEN,
	.rx_flow	= CPSW_NET_RX_FLOW,
};

extern int cpu_to_bus(u32 *ptr, u32 length);

static void keystone2_eth_mdio_enable(void);

static int gen_init_phy(int phy_addr);
static int gen_is_phy_connected(int phy_addr);
static int gen_get_link_speed(int phy_addr);
static int gen_auto_negotiate(int phy_addr);

static int marvell_88e1111_init_phy(int phy_addr);
static int marvell_88e1111_is_phy_connected(int phy_addr);
static int marvell_88e1111_get_link_speed(int phy_addr);
static int marvell_88e1111_auto_negotiate(int phy_addr);
void sgmii_serdes_setup_156p25mhz(void);

/* EMAC Addresses */
static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;

phy_t phy;

#ifdef CONFIG_MCAST_TFTP
int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set)
{
	return 0;
}
#endif

static void chip_delay(u32 del)
{
	volatile unsigned int i;

	for (i = 0; i < (del / 8); i++);
}

int keystone2_eth_read_mac_addr(struct eth_device *dev)
{
	eth_priv_t *eth_priv;
	u32 maca = 0;
	u32 macb = 0;

	eth_priv = (eth_priv_t*)dev->priv;

	/* Read the e-fuse mac address */
	if ((eth_priv->slave_port<=2) && IS_1GE(eth_priv)) {
		maca = __raw_readl(MAC_ID_BASE_ADDR);
		macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
//		printf("LWS before maca--->%i macb--->%i \n",maca,macb);//added
		/* tmp: workaround for MAC ID regs swapping issue */
		if (!(maca & 0x00ff0000)) {
			maca = macb;
			macb = __raw_readl(MAC_ID_BASE_ADDR);
		}
//		printf("LWS after maca--->%i macb--->%i \n",&maca,&macb);//added
	}

	dev->enetaddr[0] = (macb >>  8) & 0xff;
	dev->enetaddr[1] = (macb >>  0) & 0xff;
	dev->enetaddr[2] = (maca >> 24) & 0xff;
	dev->enetaddr[3] = (maca >> 16) & 0xff;
	dev->enetaddr[4] = (maca >>  8) & 0xff;
	dev->enetaddr[5] = (maca >>  0) & 0xff;
//	printf("LWS maca--->%i macb--->%i \n",&maca,&macb); //added
	return 0;
}

static void keystone2_eth_mdio_enable(void)
{
	u_int32_t	clkdiv;

	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
//	printf("LWS Inside_mido_enable\n");
	writel((clkdiv & 0xffff) |
	       MDIO_CONTROL_ENABLE |
	       MDIO_CONTROL_FAULT |
	       MDIO_CONTROL_FAULT_ENABLE,
	       &adap_mdio->CONTROL);

	while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
		;
}

/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
{
	int	tmp;
	unsigned int tmp1 = readl(&adap_mdio->USERACCESS0);
//	printf("LWS read_val_adap_mdio = %u \n",tmp1);
	while (tmp1 & MDIO_USERACCESS0_GO)
		;

	writel(MDIO_USERACCESS0_GO |
	       MDIO_USERACCESS0_WRITE_READ |
	       ((reg_num & 0x1f) << 21) |
	       ((phy_addr & 0x1f) << 16),
	       &adap_mdio->USERACCESS0);

	/* Wait for command to complete */
	while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
		;

	if (tmp & MDIO_USERACCESS0_ACK) {
		*data = tmp & 0xffff;
		return(0);
	}

	*data = -1;
	return(-1);
}

/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
{
//      printf("LWS adap_mdio->USERACCESS0-----> %u \n",adap_mdio->USERACCESS0);
//	printf("LWS value in USERACCESS0-----> %x \n",readl(&adap_mdio->USERACCESS0));
	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;

	writel(MDIO_USERACCESS0_GO |
	       MDIO_USERACCESS0_WRITE_WRITE |
	       ((reg_num & 0x1f) << 21) |
	       ((phy_addr & 0x1f) << 16) |
	       (data & 0xffff),
	       &adap_mdio->USERACCESS0);

	/* Wait for command to complete */
	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;

	return(0);
}

/* Read bits from a register */
int keystone2_eth_phy_readbits(u8 phy_addr, u8 reg_num, u16 offset,
				u16 len, u16 *data)
{
	u16 reg, mask;

	PHY_CALC_MASK(offset, len, mask);

	if (keystone2_eth_phy_read(phy_addr, reg_num, &reg) != 0)
		return -1;

	*data = (reg & mask) >> offset;

	return 0;
}

/* Write bits to a register */
int keystone2_eth_phy_writebits(u8 phy_addr, u8 reg_num, u16 offset, u16 len,
				u16 data)
{
	u16 reg, mask;

	PHY_CALC_MASK(offset, len, mask);

	if (keystone2_eth_phy_read(phy_addr, reg_num, &reg) != 0)
		return -1;

	reg &= ~mask;
	reg |= data << offset;

	if (keystone2_eth_phy_write(phy_addr, reg_num, reg) != 0)
		return -1;
	return 0;
}

/* PHY functions for a generic PHY */
static int __attribute__((unused)) gen_init_phy(int phy_addr)
{
	int	ret = -1;

	if (!gen_get_link_speed(phy_addr)) {
		/* Try another time */
		ret = gen_get_link_speed(phy_addr);
	}

	return(ret);
}

static int __attribute__((unused)) gen_is_phy_connected(int phy_addr)
{
	u_int16_t	dummy;

	return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
}

static int gen_get_link_speed(int phy_addr)
{
	u_int16_t	tmp;
//  printf("Inside gen get link speed \n");

	if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
			(tmp & 0x04)) {
//    printf("PHY address = %d and MII Status reg = %x \n",phy_addr+1,tmp);
	#if 0
	    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr, 22,1 );
    keystone2_eth_phy_read(phy_addr,0x01, &tmp);
    printf("Port 2 Page 1 reg 1 = %x \n",tmp);

    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr+1, 22,1 );
    keystone2_eth_phy_read(phy_addr+1,0x01, &tmp);
    printf("Port 3 Page 1 reg 1 = %x \n",tmp);

	    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr, 22,4 );
    keystone2_eth_phy_read(phy_addr,17, &tmp);
    printf("Port 2 Page 4 reg 17 = %x \n",tmp);

	    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr+1, 22,4 );
    keystone2_eth_phy_read(phy_addr+1,17, &tmp);
    printf("Port 3 Page 4 reg 17 = %x \n",tmp);
	#endif 
		return(0);
	}
    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr, 22,1 );
    keystone2_eth_phy_read(phy_addr,0x01, &tmp);
    //printf("Port 2 Page 1 reg 1 = %x \n",tmp);

    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr+1, 22,1 );
    keystone2_eth_phy_read(phy_addr+1,0x01, &tmp);
    //printf("Port 3 Page 1 reg 1 = %x \n",tmp);

	    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr, 22,4 );
    keystone2_eth_phy_read(phy_addr,17, &tmp);
    //printf("Port 2 Page 4 reg 17 = %x \n",tmp);

	    /*Fiber link status*/
    keystone2_eth_phy_write(phy_addr+1, 22,4 );
    keystone2_eth_phy_read(phy_addr+1,17, &tmp);
    //printf("Port 3 Page 4 reg 17 = %x \n",tmp);

	return(-1);
}

static int __attribute__((unused)) gen_auto_negotiate(int phy_addr)
{
	u_int16_t	tmp;

	if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
		return(-1);

	/* Restart Auto_negotiation  */
	tmp |= BMCR_ANENABLE;
	keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);

	/*check AutoNegotiate complete */
	udelay (10000);
	if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
		return(-1);

	if (!(tmp & BMSR_ANEGCOMPLETE))
		return(0);

	return(gen_get_link_speed(phy_addr));
}

int marvell_88e1512_init_phy(int phy_addr)
{
	/* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512/88E1514
	   Rev A0, Errata Section 3.1 */
	keystone2_eth_phy_write(phy_addr, 22, 0x00ff);	/* reg page 0xff */
	keystone2_eth_phy_write(phy_addr, 17, 0x214B);
	keystone2_eth_phy_write(phy_addr, 16, 0x2144);
	keystone2_eth_phy_write(phy_addr, 17, 0x0C28);
	keystone2_eth_phy_write(phy_addr, 16, 0x2146);
	keystone2_eth_phy_write(phy_addr, 17, 0xB233);
	keystone2_eth_phy_write(phy_addr, 16, 0x214D);
	keystone2_eth_phy_write(phy_addr, 17, 0xCC0C);
	keystone2_eth_phy_write(phy_addr, 16, 0x2159);
	keystone2_eth_phy_write(phy_addr, 22, 0x0000);	/* reg page 0 */

	keystone2_eth_phy_write(phy_addr, 22, 18);	/* reg page 18 */
	/* Write HWCFG_MODE = SGMII to Copper */
	keystone2_eth_phy_writebits(phy_addr, 20, 0, 3, 1);
	/* Phy reset */
	keystone2_eth_phy_writebits(phy_addr, 20, 15, 1, 1);
	keystone2_eth_phy_write(phy_addr, 22, 0);	/* reg page 18 */
	udelay(100);

	return 0;
}

/* PHY functions for Marvell 88E1111 PHY */
static int marvell_88e1111_init_phy(int phy_addr)
{
	int	ret = -1;

	if (!marvell_88e1111_get_link_speed(phy_addr)) {
		/* Try another time */
		ret = marvell_88e1111_get_link_speed(phy_addr);
	}

	return(ret);
}

static int marvell_88e1111_is_phy_connected(int phy_addr)
{
	u_int16_t	dummy;

	return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
}

static int marvell_88e1111_get_link_speed(int phy_addr)
{
	u_int16_t	tmp;
	unsigned int tmp1 = keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp);
	printf("reading MII_STATUS_REG-->%u \n",tmp1);
	if ((!tmp1) && (tmp & MII_STATUS_LINK_MASK)) {
		printf("condition %x \n",tmp & MII_STATUS_LINK_MASK);
		return(0);
	}

	return(-1);
}

static int marvell_88e1111_auto_negotiate(int phy_addr)
{
	u_int16_t	tmp;

	if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
		return(-1);

	/* Restart Auto_negotiation  */
	tmp |= BMCR_ANENABLE;
	keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);

	/*check AutoNegotiate complete */
	udelay (10000);
	if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
		return(-1);

	if (!(tmp & BMSR_ANEGCOMPLETE))
		return(0);

	return(marvell_88e1111_get_link_speed(phy_addr));
}

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
static int keystone2_mii_phy_read(const char *devname, unsigned char addr,
				unsigned char reg, unsigned short *value)
{
	return keystone2_eth_phy_read(addr, reg, value) ? -1 : 0;
}

static int keystone2_mii_phy_write(const char *devname, unsigned char addr,
				 unsigned char reg, unsigned short value)
{
	return keystone2_eth_phy_write(addr, reg, value) ? -1 : 0;
}
#endif

static void  __attribute__((unused)) 
	keystone2_eth_gigabit_enable(struct eth_device *dev)
{
	u_int16_t data;
	eth_priv_t *eth_priv = (eth_priv_t*)dev->priv;

	if (IS_XGE(eth_priv))
		return;

	if (sys_has_mdio) {
		if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
			!(data & (1 << 6))) /* speed selection MSB */
			return;
	}

	/*
	 * Check if link detected is giga-bit
	 * If Gigabit mode detected, enable gigbit in MAC
	 */
	writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + \
			CPGMACSL_REG_CTL) | EMAC_MACCONTROL_GIGFORCE | \
			EMAC_MACCONTROL_GIGABIT_ENABLE,
	       DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL);
}

int keystone_sgmii_link_status(int port)
{
	u32 status = 0;
//	printf("LWS PORT num---------> %d \n",port);
	status = __raw_readl(SGMII_STATUS_REG(port));
//	printf("SGMII Status = %x \n",status);

	return (status & SGMII_REG_STATUS_LINK);
}

#define MII_88E1510_GEN_CTRL_REG_1              0x14
#define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK    0x7
#define MII_88E1510_SGMII_TO_QSGMII_MODE        0x5    /* SGMII to QSGMII */
#define MII_88E1510_QSGMII_TO_FIBER_MODE        0x2   /* QSGMII to BASE1000 */
#define MII_88E1510_GEN_CTRL_REG_1_RESET        0x8000  /* Soft reset */


#define MII_88E1548_GEN_CTRL_REG_1_AUTO_MEDIA_MASK	0x30
#define MII_88E1548_GEN_CTRL_REG_1_AUTO_MEDIA	0x20


#define QSGMIIGLOBALCTRLREG     0x1B
#define QSGMIIOPCROSSOVERMASK   0x3
#define QSGMIIOPCROSSOVER       0x3

#define QSGMIIPOWERUPMASK 0x0800

#define EN_LOOPBACK	0x4000

#define FIBERCTRLREG    0x0 
#define FIBERRSTMASK    0x8000
#define FIBERRST        0x8000 


#define FIBER_SPECI_CONTROL_REG     16 
#define FIBER_SPECI_MODE_MASK	    3
#define FIBER_SYSTEM_MODE		    10
#define FIBER_MEDIA_MODE		    11

#define QSGMII_SPECI_CONTROL_REG    16 
#define QSGMII_SPECI_MODE_MASK	    1
#define QSGMII_SYSTEM_MODE		    0
#define QSGMII_MEDIA_MODE		    1

#define QSGMIICONTROLMASK	0x8000
#define QSGMIICTRLVAL		0x8000



int regRead(u_int8_t phy_addr, int page, u_int8_t reg_num){

	int ret = 0;
	keystone2_eth_phy_write(phy_addr,22,page);
	keystone2_eth_phy_read(phy_addr,reg_num,&ret); 
	return ret;
}

static int hwd = 0 ;

void fibberSettings(eth_priv_t *eth_priv){
	
	signed int port,page,i,tmp;  
	signed int ret=0;
//	printf("LWS eth_priv->int_name------> %s \n",eth_priv->int_name); //added 
//	printf("LWS entered fiber_settings phy_addr--> %d \n",eth_priv->phy_addr);// Added
//   	printf("LWS Slave_port--> %d \n",eth_priv->slave_port); // Added
/*==================================================================================================================================================================*/
/*Hardware reset*/
/*==================================================================================================================================================================*/
    if ( hwd < 1 ) {
  	keystone2_eth_phy_write(eth_priv->phy_addr,22,4);	/*Sel Page 4*/
	keystone2_eth_phy_read(eth_priv->phy_addr,27,&ret);
  	keystone2_eth_phy_write(eth_priv->phy_addr,27,(ret | 0x8000)); 	/*Hardware reset*/
  	keystone2_eth_phy_read(eth_priv->phy_addr,27,&ret);
  	hwd++;
  	udelay(100000);
   }   	
/*==================================================================================================================================================================*/
/*PHY Init*/
/*==================================================================================================================================================================*/

  keystone2_eth_phy_write(eth_priv->phy_addr,22,0xFF);

  keystone2_eth_phy_write(eth_priv->phy_addr,17,0x2148);
  keystone2_eth_phy_read(eth_priv->phy_addr,17,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x2144);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,17,0x0C28);
  keystone2_eth_phy_read(eth_priv->phy_addr,17,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x2146);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,17,0xB233);
  keystone2_eth_phy_read(eth_priv->phy_addr,17,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x214D);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,17,0xDC0C);
  keystone2_eth_phy_read(eth_priv->phy_addr,17,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x2159);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,17,0x68BA);
  keystone2_eth_phy_read(eth_priv->phy_addr,17,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x2142);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,17,0x8056);
  keystone2_eth_phy_read(eth_priv->phy_addr,17,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x2141);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,22,0xFB);

  keystone2_eth_phy_write(eth_priv->phy_addr,7,0xD);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,22,0x0);

/*Fiber init*/
  keystone2_eth_phy_write(eth_priv->phy_addr,22,0x1);
  keystone2_eth_phy_writebits(eth_priv->phy_addr,16,9,1,0);

  keystone2_eth_phy_write(eth_priv->phy_addr,22,0x0);

/*==================================================================================================================================================================*/
                                                        /*Mode Setting*/
/*==================================================================================================================================================================*/
  /*Read the global control register 1 and set the mode to SGMII to QSGMII for Port 0*/


  keystone2_eth_phy_write(eth_priv->phy_addr,22,18); /*Select Page No 18*/

  keystone2_eth_phy_read(eth_priv->phy_addr,20,&ret);
  keystone2_eth_phy_write(eth_priv->phy_addr,20,0x205);
  keystone2_eth_phy_write(eth_priv->phy_addr,20,0x8205); /*Reset*/
  keystone2_eth_phy_read(eth_priv->phy_addr,20,&ret);


/*Read the global control register 1 and set the mode to QSGMII to 1000Base for Port 0*/

  keystone2_eth_phy_write((eth_priv->phy_addr+1),22,18); /*Select Page No 18*/
  keystone2_eth_phy_write((eth_priv->phy_addr+1),20,0x207); 
  keystone2_eth_phy_write(eth_priv->phy_addr+1,20,0x8207);/*Reset*/

  keystone2_eth_phy_read((eth_priv->phy_addr+1),20,&ret);

/*Sel of port mode System/Media */
  keystone2_eth_phy_write(eth_priv->phy_addr,22,4); /*Select Page No 4*/
  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x6205); //LWS SGMII media mode
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,4); /*Select Page No 4*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,16,0x6204); //LWS SGMII system mode
  keystone2_eth_phy_read(eth_priv->phy_addr+1,16,&ret);


/*QSGMII o/p Crossover*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,4); /*Select Page No 4*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,27,0x7E03);
  keystone2_eth_phy_read(eth_priv->phy_addr+1,27,&ret);


  /*autoneg and speed sel */
  keystone2_eth_phy_write(eth_priv->phy_addr,22,4); /*Select Page No 4*/
  keystone2_eth_phy_write(eth_priv->phy_addr,0,0x9140);
  keystone2_eth_phy_read(eth_priv->phy_addr,0,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,4); /*Select Page No 4*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,0,0x9140);
  keystone2_eth_phy_read(eth_priv->phy_addr+1,0,&ret);


/*MAC power up and clocks */
  keystone2_eth_phy_write(eth_priv->phy_addr,22,2); /*Select Page No 2*/
  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x4008);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,2); /*Select Page No 2*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,16,0x4008);
  keystone2_eth_phy_read(eth_priv->phy_addr+1,16,&ret);


  keystone2_eth_phy_write(eth_priv->phy_addr,22,1); /*Select Page No 1*/
  keystone2_eth_phy_write(eth_priv->phy_addr,16,0x408C);
  keystone2_eth_phy_read(eth_priv->phy_addr,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,22,1); /*Select Page No 1*/
  keystone2_eth_phy_write(eth_priv->phy_addr,26,0x44);
  keystone2_eth_phy_read(eth_priv->phy_addr,26,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr,22,1); /*Select Page No 1*/
  keystone2_eth_phy_write(eth_priv->phy_addr,0,0x9140);
  keystone2_eth_phy_read(eth_priv->phy_addr,0,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,1); /*Select Page No 1*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,16,0x408C);
  keystone2_eth_phy_read(eth_priv->phy_addr+1,16,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,1); /*Select Page No 1*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,26,0x44);
  keystone2_eth_phy_read(eth_priv->phy_addr+1,26,&ret);

  keystone2_eth_phy_write(eth_priv->phy_addr+1,22,1); /*Select Page No 1*/
  keystone2_eth_phy_write(eth_priv->phy_addr+1,0,0x8140);
  keystone2_eth_phy_read(eth_priv->phy_addr+1,0,&ret);


#if 0
    for(page=0;page<=18;page++){
        keystone2_eth_phy_write((eth_priv->phy_addr),22,page); 
        for(i=0;i<32;i++){
            keystone2_eth_phy_read((eth_priv->phy_addr), i, &tmp); 
            printf("PHY Address = %d Page = %d REG = %d val = %4x \n",(eth_priv->phy_addr),page,i,tmp);
        }
    }
    printf("\n\n");

    for(page=0;page<=18;page++){
        keystone2_eth_phy_write((eth_priv->phy_addr +1 ),22,page); 
        for(i=0;i<32;i++){
            keystone2_eth_phy_read((eth_priv->phy_addr+ 1), i, &tmp); 
            printf("PHY Address = %d Page = %d REG = %d val = %4x \n",(eth_priv->phy_addr+1),page,i,tmp);
        }
    }
#endif 
}

static int fibersetdone = 0;

int keystone_get_link_status(struct eth_device *dev)
{
//	int fibersetdone = 0;
	eth_priv_t *eth_priv = (eth_priv_t*)dev->priv;
	int sgmii_link;
	int link_state = 0;
//          printf("Before Fibersettings0 -->%d \n",fibersetdone);
//          printf("Before Fibersettings1 -->%d \n",fibersetdone1);
#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
	int j;
  if ((eth_priv->phy_addr == 0x08) && (eth_priv->phy_addr == 0x0a) && (fibersetdone<=1) ){
	  fibberSettings(eth_priv);
	  fibersetdone++;
// 	  printf("Fibersettings0 Done -->%d \n",fibersetdone);
	
  }
  
  //eth_priv->phy_addr = eth_priv->phy_addr+1;
 // printf("LWS portname------>%s \n",eth_priv->int_name);//added
 // printf("LWS SFP phy_addr---------->%d \n",eth_priv->phy_addr); //added
  keystone2_eth_phy_write(eth_priv->phy_addr,22,1); 
  //printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \n SGMII port = %d PHY address = %x \n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n",eth_priv->slave_port,eth_priv->phy_addr);
	for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0); j++) {
#endif
    //printf("Inside SGMII link check\n");
	sgmii_link = keystone_sgmii_link_status(eth_priv->slave_port - 1);
    	phy.get_link_speed (eth_priv->phy_addr);
//	printf("Link_Speed---->%d \n", phy.get_link_speed (eth_priv->phy_addr));
		if (sgmii_link) {
			link_state = 1;
      		//printf("SGMII link is high \n");
			if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
				if (phy.get_link_speed (eth_priv->phy_addr)) {
//					link_state = 0 ;
					udelay(1000);
				}
		}else{
      //printf("SGMII link is low \n");
    }
#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
	}
#endif
//	printf("LWS link_state-----> %d \n",link_state);
	return link_state;
}

int keystone_sgmii_config(int port, int interface)
{
	unsigned int i, status, mask;
	unsigned int mr_adv_ability, control;

	switch (interface) {
	case SGMII_LINK_MAC_MAC_AUTONEG:
		mr_adv_ability	= (SGMII_REG_MR_ADV_ENABLE |
				   SGMII_REG_MR_ADV_LINK |
				   SGMII_REG_MR_ADV_FULL_DUPLEX |
				   SGMII_REG_MR_ADV_GIG_MODE);
		control		= (SGMII_REG_CONTROL_MASTER |
				   SGMII_REG_CONTROL_AUTONEG);

		break;
	case SGMII_LINK_MAC_PHY:
	case SGMII_LINK_MAC_PHY_FORCED:
		mr_adv_ability	= SGMII_REG_MR_ADV_ENABLE;
		control		= SGMII_REG_CONTROL_AUTONEG;

		break;
	case SGMII_LINK_MAC_MAC_FORCED:
		mr_adv_ability	= (SGMII_REG_MR_ADV_ENABLE |
				   SGMII_REG_MR_ADV_LINK |
				   SGMII_REG_MR_ADV_FULL_DUPLEX |
				   SGMII_REG_MR_ADV_GIG_MODE);
		control		= SGMII_REG_CONTROL_MASTER;

		break;
	case SGMII_LINK_MAC_FIBER:
		mr_adv_ability	= 0x20;
		control		= SGMII_REG_CONTROL_AUTONEG;

		break;
	default:
		mr_adv_ability	= SGMII_REG_MR_ADV_ENABLE;
		control		= SGMII_REG_CONTROL_AUTONEG;
	}

	__raw_writel(0, SGMII_CTL_REG(port));

	/*
	 * Wait for the SerDes pll to lock,
	 * but don't trap if lock is never read
	 */
	for (i = 0; i < 1000; i++)  {
		udelay(2000);
		status = __raw_readl(SGMII_STATUS_REG(port));
		if ((status & SGMII_REG_STATUS_LOCK) != 0)
			break;
	}

	__raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
	__raw_writel(control, SGMII_CTL_REG(port));


	mask = SGMII_REG_STATUS_LINK;

	if (control & SGMII_REG_CONTROL_AUTONEG)
		mask |= SGMII_REG_STATUS_AUTONEG;

	for (i = 0; i < 2000; i++) {
		udelay(2000);
		status = __raw_readl(SGMII_STATUS_REG(port));
		if ((status & mask) == mask)
			break;
	}

	return 0;
}

int mac_sl_reset(u32 port)
{
	u32 i, v;

	if (port >= DEVICE_N_GMACSL_PORTS)
		return (GMACSL_RET_INVALID_PORT);

	/* Set the soft reset bit */
	DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) +
		       CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET);

	/* Wait for the bit to clear */
	for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
		v = DEVICE_REG32_R (DEVICE_EMACSL_BASE(port) +
				    CPGMACSL_REG_RESET);
		if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
		    CPGMAC_REG_RESET_VAL_RESET)
			return (GMACSL_RET_OK);
	}

	/* Timeout on the reset */
	return (GMACSL_RET_WARN_RESET_INCOMPLETE);
}

int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
{
	u32 v, i;
	int ret = GMACSL_RET_OK;

	if (port >= DEVICE_N_GMACSL_PORTS)
		return (GMACSL_RET_INVALID_PORT);

	if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
		cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
		ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
	}

	/* Must wait if the device is undergoing reset */
	for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
		v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
				   CPGMACSL_REG_RESET);
		if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
		    CPGMAC_REG_RESET_VAL_RESET)
			break;
	}

	if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
		return (GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE);

	DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN,
			cfg->max_rx_len);

	DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL,
			cfg->ctl);

	if (!cpu_is_k2hk())
		/* Map RX packet flow priority to 0 */
		DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + \
				CPGMACSL_REG_RX_PRI_MAP, 0);

	return (ret);
}

int ethss_config(u32 ctl, u32 max_pkt_size)
{
	u32 i;

	/* Max length register */
	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size);

	/* Control register */
	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl);

	/* All statistics enabled by default */
	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN,
		       CPSW_REG_VAL_STAT_ENABLE_ALL);

	/* Reset and enable the ALE */
	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL,
		       CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
		       CPSW_REG_VAL_ALE_CTL_BYPASS);

	/* All ports put into forward mode */
	for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
		DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i),
			       CPSW_REG_VAL_PORTCTL_FORWARD_MODE);

	return (0);
}

int ethss_start(void)
{
	int i;
	struct mac_sl_cfg cfg;

	cfg.max_rx_len	= MAX_SIZE_STREAM_BUFFER;
	cfg.ctl		= GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;

	for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
		mac_sl_reset(i);
		mac_sl_config(i, &cfg);
	}

	return (0);
}

int ethss_stop(void)
{
	int i;

	for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
		mac_sl_reset(i);

	return (0);
}

int32_t cpmac_drv_send(u32* buffer, int num_bytes, int slave_port_num)
{
	if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
		num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;

	return netcp_send(buffer, num_bytes, slave_port_num);
}

/* Eth device open */
static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
{
	int link;

	eth_priv_t *eth_priv = (eth_priv_t*)dev->priv;

	debug_emac("+ emac_open\n");

	if (xmac_open) {
		printf("keystone2_eth_open ERR - 10G intf is still open!\n");
		return -1;
	}

	net_rx_buffs.rx_flow	= eth_priv->rx_flow;

	sys_has_mdio =
		(eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;

	sgmii_serdes_setup_156p25mhz();

	if (sys_has_mdio)
		keystone2_eth_mdio_enable();

	keystone_sgmii_config(eth_priv->slave_port - 1,
			      eth_priv->sgmii_link_type);

	udelay(10000);

	/* On chip switch configuration */
	ethss_config(target_get_sw_ctl(), target_get_sw_max_pkt_size());

	/* TODO: add error handling code */
	if (qm_init()) {
		printf("ERROR: qm_init()\n");
		return (-1);
	}

	if (netcp_init(&net_rx_buffs)) {
		qm_close();
		printf("ERROR: netcp_init()\n");
		return (-1);
	}

	/*
	 * Streaming switch configuration. If not present this
	 * statement is defined to void in target.h.
	 * If present this is usually defined to a series of register writes
	 */
	hwConfigStreamingSwitch();
	if (sys_has_mdio) {
		/* Init MDIO & get link state */
		keystone2_eth_mdio_enable();

		if (!loopback_test) {
			link = keystone_get_link_status(dev);
			if (link == 0) {
				netcp_close();
				qm_close();
				return -1;
			}
		}
	}

	if (!loopback_test) {
		emac_gigabit_enable(dev);
	}

	ethss_start();

	debug_emac("- emac_open\n");

	emac_open = 1;

	return(0);
}

/* Eth device close */
void keystone2_eth_close(struct eth_device *dev)
{
	debug_emac("+ emac_close\n");

	if (!emac_open)
		return;

	ethss_stop();

	netcp_close();
	qm_close();

	emac_open = 0;

	debug_emac("- emac_close\n");
}

void keystone2_eth_open_close(struct eth_device *dev)
{
	keystone2_eth_open(dev, NULL);
	keystone2_eth_close(dev);
}

/*
 * This function sends a single packet on the network and returns
 * positive number (number of bytes transmitted) or negative for error
 */
static int keystone2_eth_send_packet(struct eth_device *dev,
				     volatile void *packet, int length)
{
	int ret_status = -1;
	eth_priv_t *eth_priv = (eth_priv_t*)dev->priv;

	if (!loopback_test) {
		if (keystone_get_link_status(dev) == 0)
			return -1;
	}

	if (cpmac_drv_send ((u32*) packet, length, eth_priv->slave_port) != 0)
		return ret_status;

  	//printf("Inside keystone send packet functioni =%x \n",length);
	return (length);
}

/*
 * This function handles receipt of a packet from the network
 */
static int keystone2_eth_rcv_packet(struct eth_device *dev)
{
	void *hd;
	int  pkt_size;
	u32  *pkt;

	hd = netcp_recv(&pkt, &pkt_size);
	if (hd == NULL)
		return (0);

	NetReceive((uchar *)pkt, pkt_size);

	netcp_release_rxhd(hd);

  	//printf("Inside keystone2Rx packet %x \n",pkt_size);
	return pkt_size;
}

inline void keystone2_emac_set_loopback_test(int val)
{
	loopback_test = val;
}

static int xmac_sl_reset(u32 port)
{
	u32 i, v;

	if (port >= DEVICE_N_XMACSL_PORTS)
		return GMACSL_RET_INVALID_PORT;

	/* Set the soft reset bit */
	DEVICE_REG32_W(DEVICE_XMACSL_BASE(port) +
		       CPXMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET);

	/* Wait for the bit to clear */
	for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
		v = DEVICE_REG32_R(DEVICE_XMACSL_BASE(port) +
				    CPXMACSL_REG_RESET);
		if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
		    CPGMAC_REG_RESET_VAL_RESET)
			return GMACSL_RET_OK;
	}

	/* Timeout on the reset */
	return GMACSL_RET_WARN_RESET_INCOMPLETE;
}

static int xmac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
{
	u32 v, i;
	int ret = GMACSL_RET_OK;

	if (port >= DEVICE_N_XMACSL_PORTS)
		return GMACSL_RET_INVALID_PORT;

	if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
		cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
		ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
	}

	/* Must wait if the device is undergoing reset */
	for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
		v = DEVICE_REG32_R(DEVICE_XMACSL_BASE(port) +
				   CPXMACSL_REG_RESET);
		if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
		    CPGMAC_REG_RESET_VAL_RESET)
			break;
	}

	if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
		return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;

	DEVICE_REG32_W(DEVICE_XMACSL_BASE(port) + CPXMACSL_REG_MAXLEN,
			cfg->max_rx_len);

	DEVICE_REG32_W(DEVICE_XMACSL_BASE(port) + CPXMACSL_REG_CTL,
			cfg->ctl);

	/* Map RX packet flow priority to 0 */
	DEVICE_REG32_W(DEVICE_XMACSL_BASE(port) + CPXMACSL_REG_RX_PRI_MAP, 0);

	return ret;
}

static int xgess_config(u32 ctl, u32 max_pkt_size)
{
	u32 i;

	DEVICE_REG32_W(KS2_XGESS_BASE + XGESS_REG_CTL,
				XGESS_REG_VAL_XGMII_MODE);

	/* Max length register */
	DEVICE_REG32_W(DEVICE_CPSWX_BASE + CPSWX_REG_MAXLEN, max_pkt_size);

	/* Control register */
	DEVICE_REG32_W(DEVICE_CPSWX_BASE + CPSWX_REG_CTL, ctl);

	/* All statistics enabled by default */
	DEVICE_REG32_W(DEVICE_CPSWX_BASE + CPSWX_REG_STAT_PORT_EN,
		       CPSWX_REG_VAL_STAT_ENABLE_ALL);

	/* Reset and enable the ALE */
	DEVICE_REG32_W(DEVICE_CPSWX_BASE + CPSWX_REG_ALE_CONTROL,
		       CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
		       CPSW_REG_VAL_ALE_CTL_BYPASS);

	/* All ports put into forward mode */
	for (i = 0; i < DEVICE_CPSWX_NUM_PORTS; i++)
		DEVICE_REG32_W(DEVICE_CPSWX_BASE + CPSWX_REG_ALE_PORTCTL(i),
			       CPSW_REG_VAL_PORTCTL_FORWARD_MODE);

	return 0;
}

static int xgess_start(void)
{
	int i;
	struct mac_sl_cfg cfg;

	cfg.max_rx_len	= MAX_SIZE_STREAM_BUFFER;

	cfg.ctl		= (XMACSL_XGMII_ENABLE	|
			   XMACSL_XGIG_MODE	|
			   XMACSL_RX_ENABLE_CSF	|
			   GMACSL_RX_ENABLE_EXT_CTL);

	for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
		xmac_sl_reset(i);
		xmac_sl_config(i, &cfg);
	}

	return 0;
}

static int xgess_stop(void)
{
	int i;

	for (i = 0; i < DEVICE_N_XMACSL_PORTS; i++)
		xmac_sl_reset(i);

	return 0;
}

/* XGE device open */
static int keystone2_xge_open(struct eth_device *dev, bd_t *bis)
{
	eth_priv_t *eth_priv = (eth_priv_t *)dev->priv;
	int ret;

	debug_emac("+ xmac_open\n");

	if (emac_open) {
		printf("keystone2_xge_open ERR - 1G intf is still open!\n");
		return -1;
	}

	net_rx_buffs.rx_flow	= eth_priv->rx_flow;
	xge_serdes_init();
	udelay(10000);
	xgess_config(target_get_sw_ctl(), target_get_sw_max_pkt_size());

	/* TODO: add error handling code */
	if (cpu_is_k2hk())
		ret = qm2_init();
	else if (cpu_is_k2e())
		ret = qm_init();
	else
		return -1;

	if (ret) {
		printf("ERROR: xge qm(2) init()\n");
		return -1;
	}

	if (netcpx_init(&net_rx_buffs)) {
		if (cpu_is_k2hk())
			qm2_close();
		else
			qm_close();
		printf("ERROR: netcpx_init()\n");
		return -1;
	}

	if (!loopback_test)
		emac_gigabit_enable(dev);

	xgess_start();

	debug_emac("- xmac_open\n");

	xmac_open = 1;

	return 0;
}

/* XGE device close */
static void keystone2_xge_close(struct eth_device *dev)
{
	debug_emac("+ xmac_close\n");

	if (!xmac_open)
		return;

	if (cpu_is_k2l())
		return;

	xgess_stop();

	netcpx_close();

	if (cpu_is_k2hk())
		qm2_close();
	else
		qm_close();

	xmac_open = 0;

	debug_emac("- xmac_close\n");
}

static int keystone2_xge_send_packet(struct eth_device *dev,
			     void *packet, int length)
{
	int ret;
	eth_priv_t *eth_priv = (eth_priv_t *)dev->priv;

	if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
		length = EMAC_MIN_ETHERNET_PKT_SIZE;

	ret = netcpx_send((u32 *)packet, length, eth_priv->slave_port);
	if (ret) {
		printf("netcpx_send error: %d\n", ret);
		return ret;
	}
	return length;
}

static int keystone2_xge_rcv_packet(struct eth_device *dev)
{
	void *hd;
	int  pkt_size;
	u32  *pkt;

	hd = netcpx_recv(&pkt, &pkt_size);
	if (hd == NULL)
		return 0;

	NetReceive((uchar *)pkt, pkt_size);

	netcpx_release_rxhd(hd);

	return pkt_size;
}
/*
 * This function initializes the EMAC hardware. It does NOT initialize
 * EMAC modules power or pin multiplexors, that is done by board_init()
 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 */
int keystone2_emac_initialize(eth_priv_t *eth_priv)
{
	struct eth_device *dev;
	static int phy_registered = 0;
	static int emac_poweron = 1;
	static int xmac_poweron = 1;
	unsigned int temp;
	printf("eth_priv->int_name-------->%s \n",eth_priv->int_name);
	dev = malloc(sizeof *dev);
	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof *dev);

	strcpy(dev->name, eth_priv->int_name);
	dev->priv = eth_priv;

	keystone2_eth_read_mac_addr(dev);

	dev->iobase		= 0;
	dev->init		= keystone2_eth_open;
	dev->halt		= keystone2_eth_close;
	dev->send		= keystone2_eth_send_packet;
	dev->recv		= keystone2_eth_rcv_packet;
#ifdef CONFIG_MCAST_TFTP
	dev->mcast		= keystone2_eth_bcast_addr;
#endif
	eth_priv->dev		= dev;
	eth_register(dev);

	if (emac_poweron && IS_1GE(eth_priv)) {
		emac_poweron = 0;

		/* Workaround to resolve a PA RX path issue in the Ethernet
		 * boot mode by turning off PA/CPGMAC/CRYPTO clock modules */

		/* Set the streaming switch to forward the RX packets to CPSW */
		hwConfigStreamingSwitch();

		/* Turn off rx/tx packet DMA channels */
		for (temp = 0; temp < DEVICE_PA_CDMA_RX_NUM_CHANNELS; temp++)
			writel(0x0, DEVICE_PA_CDMA_RX_CHAN_CFG_BASE + 8 * temp);
		for (temp = 0; temp < DEVICE_PA_CDMA_TX_NUM_CHANNELS; temp++)
			writel(0x0, DEVICE_PA_CDMA_TX_CHAN_CFG_BASE + 8 * temp);

		/* Power off PA/CPGMAC/CRYPTO */
		if (psc_disable_module(KS2_LPSC_CRYPTO))
			return -1;
		if (psc_disable_module(KS2_LPSC_CPGMAC))
			return -1;
		if (psc_disable_module(KS2_LPSC_PA))
			return -1;

		/* By default, select PA PLL clock as PA clock source */
		if (psc_enable_module(KS2_LPSC_PA))
			return -1;
		if (psc_enable_module(KS2_LPSC_CPGMAC))
			return -1;
		if (psc_enable_module(KS2_LPSC_CRYPTO))
			return -1;
		pll_pa_clk_sel(1);
	} else if (IS_XGE(eth_priv)) {
		dev->init	= keystone2_xge_open;
		dev->halt	= keystone2_xge_close;
		dev->send	= keystone2_xge_send_packet;
		dev->recv	= keystone2_xge_rcv_packet;
#ifdef CONFIG_MCAST_TFTP
		dev->mcast	= keystone2_eth_bcast_addr;
#endif
		if (xmac_poweron) {
			xmac_poweron = 0;
			if (psc_enable_module(KS2_LPSC_XGE))
				return -1;
		}
	}

	if ((eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) &&
	    !phy_registered) {
		phy_registered = 1;
#ifdef CONFIG_ETH_PHY_MARVEL_88E1111
		sprintf(phy.name, "88E1111");
		phy.init = marvell_88e1111_init_phy;
		phy.is_phy_connected = marvell_88e1111_is_phy_connected;
		phy.get_link_speed = marvell_88e1111_get_link_speed;
		phy.auto_negotiate = marvell_88e1111_auto_negotiate;
#else
		sprintf(phy.name, "GENERIC");
		phy.init = gen_init_phy;
		phy.is_phy_connected = gen_is_phy_connected;
		phy.get_link_speed = gen_get_link_speed;
		phy.auto_negotiate = gen_auto_negotiate;
#endif
   	//	printf("LWS PHY_Name = %s \n",phy.name);
		miiphy_register(phy.name, keystone2_mii_phy_read,
				keystone2_mii_phy_write);
	}

	if (!cpu_is_k2hk() &&
	    (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)) {
		keystone2_eth_mdio_enable();
		marvell_88e1512_init_phy(eth_priv->phy_addr);
	}

	return(0);
}
board_k2hk.c
/*
 * Copyright (C) 2012 - 2014 Texas Instruments Inc.
 *
 * K2HK EVM : Board initialization
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <common.h>
#include <i2c.h>

#include <asm/arch/hardware.h>
#include <asm/arch/clock.h>
#include <asm/arch/clock_defs.h>
#include <asm/io.h>
#include <asm/arch/nand_defs.h>
#include <asm/arch/emac_defs.h>

DECLARE_GLOBAL_DATA_PTR;

unsigned int external_clk[ext_clk_count] = {
	[sys_clk]	=	122880000,
	[alt_core_clk]	=	125000000,
	[pa_clk]	=	122880000,
	[tetris_clk]	=	125000000,
	[ddr3a_clk]	=	100000000,
	[ddr3b_clk]	=	100000000,
	[mcm_clk]	=	312500000,
	[pcie_clk]	=	100000000,
	[sgmii_srio_clk] =	156250000,
	[xgmii_clk]	=	156250000,
	[usb_clk]	=	100000000,
	[rp1_clk]	=	123456789    /* TODO: cannot find
						what is that */
};

static struct async_emif_config async_emif_config[ASYNC_EMIF_NUM_CS] = {
	{			/* CS0 */
		.mode		= ASYNC_EMIF_MODE_NAND,
		.wr_setup	= 0xf,
		.wr_strobe	= 0x3f,
		.wr_hold	= 7,
		.rd_setup	= 0xf,
		.rd_strobe	= 0x3f,
		.rd_hold	= 7,
		.turn_around	= 3,
		.width		= ASYNC_EMIF_8,
	},

};

static struct pll_init_data core_pll_config[] = {
	{ CORE_PLL,	13,	1,	2 }, /* 799 */
	{ CORE_PLL,	122,	15,	1 }, /* 999 */
	{ CORE_PLL,	625,	32,	2 }, /* 1200 */
};

static struct pll_init_data tetris_pll_config[] = {
	{ TETRIS_PLL,	32,	5,	1 }, /* 800 */
	{ TETRIS_PLL,	40,	5,	1 }, /* 1000 */
	{ TETRIS_PLL,	48,	5,	1 }, /* 1200 */
	{ TETRIS_PLL,	54,	5,	1 }, /* 1350 */
	{ TETRIS_PLL,	56,	5,	1 }, /* 1400 */
};

static struct pll_init_data pa_pll_config =
	{ PASS_PLL,	16,	1,	2 }; /* 983 */


#ifdef CONFIG_SPL_BOARD_INIT
static struct pll_init_data spl_pll_config[] = {
	{ CORE_PLL,	13,	1,	2 }, /* 799 */
	{ TETRIS_PLL,	8,	1,	2 }, /* 500 */
};

void spl_init_keystone_plls(void)
{
	init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
}
#endif

int dram_init(void)
{
	init_ddr3();

	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
				    CONFIG_MAX_RAM_BANK_SIZE);
	init_async_emif(ARRAY_SIZE(async_emif_config), async_emif_config);
	init_ddr3_ecc(K2HK_DDR3A_EMIF_CTRL_BASE);
	return 0;
}

#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
eth_priv_t eth_priv_cfg[] = {
#if 1
	{
		.int_name	= "K2HK_EMAC",
		.rx_flow	= CPSW_PORT_RX_FLOW(0),
		.phy_addr	= 0, /*Vyapi V1*/
//		.phy_addr	= 8, /*Vyapi V2*/
		.slave_port	= 1,
		.sgmii_link_type = SGMII_LINK_MAC_PHY,
	},
	{
		.int_name	= "K2HK_EMAC1",
		.rx_flow	= CPSW_PORT_RX_FLOW(1),
	//	.phy_addr	= 8,
		.phy_addr       = 1, //LWS
		.slave_port	= 2,
		.sgmii_link_type = SGMII_LINK_MAC_PHY,
	},
    {
		.int_name	= "K2HK_EMAC2",
		.rx_flow	= CPSW_PORT_RX_FLOW(2),
		.phy_addr	= 1,
//		.phy_addr       = 10, //added
		.slave_port	= 3,
		.sgmii_link_type = SGMII_LINK_MAC_PHY,
	},
#endif
  
	{
		.int_name	= "K2HK_EMAC3",
		.rx_flow	= CPSW_PORT_RX_FLOW(3),
		.phy_addr	= 0,
		.slave_port	= 4,
		.sgmii_link_type = SGMII_LINK_MAC_PHY,
	},
	{
		.int_name	= "K2HK_XMAC0",
		.rx_flow	= 0,
		.slave_port	= 1,
		.sgmii_link_type = XGMII_LINK_MAC_MAC_FORCED,
	},
	{
		.int_name	= "K2HK_XMAC1",
		.rx_flow	= 8,
		.slave_port	= 2,
		.sgmii_link_type = XGMII_LINK_MAC_MAC_FORCED,
	},
};

inline int get_num_eth_ports(void){
	int total_ports = sizeof(eth_priv_cfg) / sizeof(eth_priv_t);
//	printf("LWS 'get_num_eth' total_ports----->%d \n",total_ports);
	return sizeof(eth_priv_cfg) / sizeof(eth_priv_t);
}

eth_priv_t *get_eth_priv_ptr(int port_num)
{
	if (port_num < 0 || port_num >= get_num_eth_ports())
		return NULL;

	return &eth_priv_cfg[port_num];
}

int get_eth_env_param(char *env_name)
{
	char *env;
	int  res = -1;

	env = getenv(env_name);
	if (env)
		res = simple_strtol(env, NULL, 0);

	return res;
}

static int board_has_xge(void)
{
	int ret, current_bus, has_xge = 1, restore = 0;
	current_bus = i2c_get_bus_num();
//	printf("LWS i2c 'board_has_xge' current bus_num------->%d \n",current_bus);
	if (current_bus != RTM_BOC_XGE_RETIMER_I2C_BUS) {
		ret = i2c_set_bus_num(RTM_BOC_XGE_RETIMER_I2C_BUS);
		if (ret) {
			has_xge = 0;
			goto done;
		}
		restore = 1;
	}

	ret = i2c_probe(RTM_BOC_XGE_RETIMER1_I2C_ADDR);
	if (!ret)
		goto done;

	ret = i2c_probe(RTM_BOC_XGE_RETIMER2_I2C_ADDR);
	if (!ret)
		goto done;

	has_xge = 0;
done:
	/* restore previous bus num */
	if (restore)
		i2c_set_bus_num(current_bus);
//	printf("LWS 'board_has_xge'has_xge--->%d \n",has_xge);
	return has_xge;
}

int board_eth_init(bd_t *bis)
{
	int	j;
	int	res;
	char	link_type_name[32];
	int	has_xge = board_has_xge();
//	printf("LWS---> 'board_eth_init' has_xge---> %d \n",has_xge); //added
	for (j = 0; j < get_num_eth_ports(); j++) {
		if (IS_XGE(&eth_priv_cfg[j]) && !has_xge)
			continue;

		sprintf(link_type_name, "sgmii%d_link_type", j);
//		printf("LWS link_type name %s \n",link_type_name);//added
		res = get_eth_env_param(link_type_name);
//		printf("LWS res=%d \n",res);//added
		if (res >= 0)
			eth_priv_cfg[j].sgmii_link_type = res;
		if (j<=1){
			keystone2_emac_initialize(&eth_priv_cfg[j]);
	       		keystone2_eth_open_close(eth_priv_cfg[j].dev);
//			printf("LWS $$$$$$$$$$$$$$$$ open close %d\n",j);
	}

//	keystone2_eth_open_close(eth_priv_cfg[0].dev);
//	keystone2_eth_open_close(eth_priv_cfg[1].dev);
//	keystone2_eth_open_close(eth_priv_cfg[2].dev); 
}
	return 0;
}
#endif

#if defined(CONFIG_BOARD_EARLY_INIT_F)
int board_early_init_f(void)
{
	int speed;

	speed = get_max_dev_speed();

	if (speed != SPD800 && speed != SPD_RSV)
		init_pll(&core_pll_config[speed]);
	else
		init_pll(&core_pll_config[SPD800]);

	init_pll(&pa_pll_config);

	speed = get_max_arm_speed();

	if (speed != SPD800 && speed != SPD_RSV)
		init_pll(&tetris_pll_config[speed]);
	else
		init_pll(&tetris_pll_config[SPD800]);

	return 0;
}
#endif

int board_init(void)
{

	gd->bd->bi_arch_number = -1;
	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;

	return 0;
}