Ejemplo n.º 1
0
int mii_init(struct net_device *dev)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    volatile EmacRegisters *emac;
    int data32;
    char *phytype = "";
    char *setup = "";

    switch(pDevCtrl->EnetInfo.ucPhyType) {
        case BP_ENET_INTERNAL_PHY:
            phytype = "Internal PHY";
            break;

        case BP_ENET_EXTERNAL_PHY:
            phytype = "External PHY";
            break;

        default:
            printk(KERN_INFO ": Unknown PHY type\n");
            return -1;
    }
    switch (pDevCtrl->EnetInfo.usConfigType) {
        case BP_ENET_CONFIG_MDIO:
            setup = "MDIO";
            break;

        default:
            setup = "Undefined Interface";
            break;
    }
    printk(KERN_INFO "Config %s Through %s", phytype, setup);

    emac = pDevCtrl->emac;
    switch(pDevCtrl->EnetInfo.ucPhyType) {

        case BP_ENET_INTERNAL_PHY:
            /* init mii clock, do soft reset of phy, default is 10Base-T */
            emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC;
            /* reset phy */
            mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress);
            mii_setup(dev);
            break;

        case BP_ENET_EXTERNAL_PHY:
            emac->config |= EMAC_EXT_PHY;
            emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC;
            /* reset phy */
            mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress);

            data32 = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_ADVERTISE);
            data32 |= ADVERTISE_FDFC; /* advertise flow control capbility */
            mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_ADVERTISE, data32);

            mii_setup(dev);
            break;
        default:
            break;
    }
    return 0;
}
Ejemplo n.º 2
0
int mii_init(struct net_device *dev)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    volatile EmacRegisters *emac;
    int data32;
    uint16 data16;
#if defined (CONFIG_BCM96338) || defined (CONFIG_BCM96348)
    uint16 blkEnables;
#endif
    uint8 data8;
    int i;
    char *phytype = "";
    char *setup = "";

    

    switch(pDevCtrl->EnetInfo.ucPhyType) {
        case BP_ENET_INTERNAL_PHY:
            phytype = "Internal PHY";
            break;

        case BP_ENET_EXTERNAL_PHY:
            phytype = "External PHY";
            break;

        case BP_ENET_EXTERNAL_SWITCH:
            phytype = "Ethernet Switch";
            break;

        default:
            printk(KERN_INFO CARDNAME ": Unknown PHY type\n");
            return -1;
    }
    switch (pDevCtrl->EnetInfo.usConfigType) {
        case BP_ENET_CONFIG_MDIO_PSEUDO_PHY:
            setup = "MDIO Pseudo PHY Interface";
            break;

        case BP_ENET_CONFIG_SPI_SSB_0:
            setup = "SPI Slave Select 0";
            break;

        case BP_ENET_CONFIG_SPI_SSB_1:
            setup = "SPI Slave Select 1";
            break;

        case BP_ENET_CONFIG_SPI_SSB_2:
            setup = "SPI Slave Select 2";
            break;

        case BP_ENET_CONFIG_SPI_SSB_3:
            setup = "SPI Slave Select 3";
            break;

        case BP_ENET_CONFIG_MDIO:
            setup = "MDIO";
            break;

         /*start of support   infineon ADM6996M LSW by l39225 20061218*/
        case  BP_ENET_CONFIG_SMI:
        	setup = "SMI";
        	break;
         /*end of support   infineon ADM6996M LSW by l39225 20061218*/

        default:
            setup = "Undefined Interface";
            break;
    }
    printk("Config %s Through %s\n", phytype, setup);

    emac = pDevCtrl->emac;
    switch(pDevCtrl->EnetInfo.ucPhyType) {

        case BP_ENET_INTERNAL_PHY:
            /* init mii clock, do soft reset of phy, default is 10Base-T */
            emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC;
            /* reset phy */
            mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress);
#if defined(CONFIG_BCM96338)
            pga_fix_enable(dev);
#endif
            mii_setup(dev);
            break;

        case BP_ENET_EXTERNAL_PHY:
            emac->config |= EMAC_EXT_PHY;
            emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC;
            /* reset phy */
            if (pDevCtrl->EnetInfo.usGpioPhyReset != BP_NOT_DEFINED) {
                data16 = GPIO_NUM_TO_MASK(pDevCtrl->EnetInfo.usGpioPhyReset);
                GPIO->GPIODir |= data16;
                if (pDevCtrl->EnetInfo.usGpioPhyReset & BP_ACTIVE_LOW) {
                    GPIO->GPIOio &= ~data16;
                    udelay(400); /* hold > 150us */
                    GPIO->GPIOio |= data16;
                }
                else {
                    GPIO->GPIOio |= data16;
                    udelay(400); /* hold > 150us */
                    GPIO->GPIOio &= ~data16;
                }
                mdelay(1100); /* wait > 1 second */
            } else {
                mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress);
            }

            data32 = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_ADVERTISE);
            data32 |= ADVERTISE_FDFC; /* advertise flow control capbility */
            mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_ADVERTISE, data32);

            mii_setup(dev);
            break;

        case BP_ENET_EXTERNAL_SWITCH:
#if defined(CONFIG_BCM96358)
            GPIO->GPIOMode |= GPIO_MODE_EMAC2_MII_CLK_INV;
#endif
            emac->config |= EMAC_EXT_PHY;
            emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC;
            emac->txControl = EMAC_FD;
            switch (pDevCtrl->EnetInfo.usConfigType) 
            {
                case BP_ENET_CONFIG_MDIO_PSEUDO_PHY:
                    mii_soft_reset(dev, PSEUDO_PHY_ADDR);
                    break;

                case BP_ENET_CONFIG_SPI_SSB_0:
                case BP_ENET_CONFIG_SPI_SSB_1:
                case BP_ENET_CONFIG_SPI_SSB_2:
                case BP_ENET_CONFIG_SPI_SSB_3:
#if defined (CONFIG_BCM96338) || defined (CONFIG_BCM96348)
                    blkEnables = PERF->blkEnables;
                    if ((blkEnables & SPI_CLK_EN) == 0) {
                        blkEnables |= SPI_CLK_EN;
                        PERF->blkEnables = blkEnables;
                    }
                    pDevCtrl->ethSwitch.cid = 0xff;
                    pDevCtrl->ethSwitch.page = 0xff;
#endif
                    break;

                case BP_ENET_CONFIG_MDIO:
                    /* reset phy */
                    if (pDevCtrl->EnetInfo.numSwitchPorts) {
                        for (i = 0; i < pDevCtrl->EnetInfo.numSwitchPorts; i++) {
                            mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress | i);
                        }
                    }
                    return 0;

		  /*start of support   infineon ADM6996M LSW by l39225 20061218*/
		 case  BP_ENET_CONFIG_SMI:
		       if (pDevCtrl->EnetInfo.numSwitchPorts) 
		       {
                           for (i = 0; i < pDevCtrl->EnetInfo.numSwitchPorts; i++)
                           {
				    int val;
				    mii_write(dev, 0, SWI_PHYREG_START_ADDR+i*SWI_PHYREG_OFFSET, BMCR_RESET);
				    udelay(10); 
				    do 
				    {
				        val = mii_read(dev, 0, SWI_PHYREG_START_ADDR+i*SWI_PHYREG_OFFSET);
				    } while (val & BMCR_RESET);
                            }
                     }
		       break;
		   /*end of support   infineon ADM6996M LSW by l39225 20061218*/
 
                default:
                    printk(KERN_INFO CARDNAME ": Unknown PHY configuration type\n");
                    break;
            }
            if( pDevCtrl->EnetInfo.usConfigType != BP_ENET_CONFIG_SMI)
            {
	            if (pDevCtrl->EnetInfo.numSwitchPorts) {
	                data8 = 0;
	                switch (pDevCtrl->EnetInfo.numSwitchPorts) {
	                    case 5:
	                        data8 |= REG_POWER_DOWN_MODE_PORT5_PHY_DISABLE;
	                    case 4:
	                        data8 |= REG_POWER_DOWN_MODE_PORT4_PHY_DISABLE;
	                    case 3:
	                        data8 |= REG_POWER_DOWN_MODE_PORT3_PHY_DISABLE;
	                    case 2:
	                        data8 |= REG_POWER_DOWN_MODE_PORT2_PHY_DISABLE;
	                    case 1:
	                        /* 
	                         * y42304 delete: Do not set bit 0 to a 1 , Doing so 
	                         * disable pll power and lanswitch function 
	                         */
	                        //data8 |= REG_POWER_DOWN_MODE_PORT1_PHY_DISABLE; 
	                        break;
	                    default:
	                        break;
	                }

	                /* start of enet y42304 modified 20060711: power down port 5*/
	                data8 |= REG_POWER_DOWN_MODE_PORT5_PHY_DISABLE;
	                /* disable Switch port PHY */
	                ethsw_wreg(dev, PAGE_CONTROL, REG_POWER_DOWN_MODE, (uint8 *)&data8, sizeof(data8));
	                
	                /* enable Switch port 0-3 PHY */
	                data8 |= REG_POWER_DOWN_MODE_PORT1_PHY_DISABLE;
	                data8 = ((~data8) | REG_POWER_DOWN_MODE_PORT5_PHY_DISABLE);                           
	                ethsw_wreg(dev, PAGE_CONTROL, REG_POWER_DOWN_MODE, (uint8 *)&data8, sizeof(data8));                
	                /* end of enet y42304 modified 20060711: power down port 5*/
	            }

	            /* setup Switch MII1 port state override */
	            ethsw_rreg(dev, PAGE_CONTROL, REG_CONTROL_MII1_PORT_STATE_OVERRIDE, &data8, sizeof(data8));

	            if (pDevCtrl->EnetInfo.usReverseMii == BP_ENET_REVERSE_MII)
	                data8 |= REG_CONTROL_MPSO_REVERSE_MII;
	            data8 |= (REG_CONTROL_MPSO_MII_SW_OVERRIDE|REG_CONTROL_MPSO_LINKPASS);
	            data8 |= (REG_CONTROL_MPSO_LP_FLOW_CONTROL|REG_CONTROL_MPSO_SPEED100|REG_CONTROL_MPSO_FDX);

	            ethsw_wreg(dev, PAGE_CONTROL, REG_CONTROL_MII1_PORT_STATE_OVERRIDE, &data8, sizeof(data8));

	            /* checking Switch functional */
	            data8 = 0;
	            ethsw_rreg(dev, PAGE_CONTROL, REG_CONTROL_MII1_PORT_STATE_OVERRIDE, &data8, sizeof(data8));
	            if ((data8 & (REG_CONTROL_MPSO_MII_SW_OVERRIDE|REG_CONTROL_MPSO_LINKPASS)) !=
	                (REG_CONTROL_MPSO_MII_SW_OVERRIDE|REG_CONTROL_MPSO_LINKPASS) ||
	                (data8 == 0xff)) {
	                    printk(KERN_INFO CARDNAME ": error on Ethernet Switch setup\n");
	                    return -1;
	            }
	            if (pDevCtrl->EnetInfo.usReverseMii == BP_ENET_REVERSE_MII) {
	                if ((data8 & REG_CONTROL_MPSO_REVERSE_MII) != REG_CONTROL_MPSO_REVERSE_MII) {
	                    printk(KERN_INFO CARDNAME ": error on Ethernet Switch reverse MII setup\n");
	                    return -1;
	                }
	            }
	            pDevCtrl->ethSwitch.type = ethsw_switch_type(dev);
           }
            /*start of support   infineon ADM6996M LSW by l39225 20061218*/
           else 
           {
                int i ,v;
                for( i = 0; i< 5;i++)
                {
                    v = mii_read(dev,0,0x01+2*i);
                    v |= 0x8000;
                    mii_write(dev,0,0x01+2*i,v);
                }

                v = mii_read(dev,0,0x08);
                v |= 0x8000;
                mii_write(dev,0,0x08,v);
                
           		pDevCtrl->ethSwitch.type =  ESW_TYPE_ADM6996M;
           }
          /*end of support   infineon ADM6996M LSW by l39225 20061218*/
            break;

        default:
            break;
    }

    return 0;
}
Ejemplo n.º 3
0
int mii_init(struct net_device *dev)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    volatile uniMacRegs *umac;
	volatile rbufRegs * txrx_ctrl;
    int data32, advertise;

    printk(KERN_INFO "Config %s Through MDIO\n", gsPhyType[pDevCtrl->EnetInfo.PhyType] );

    umac = pDevCtrl->umac;
	txrx_ctrl = pDevCtrl->txrx_ctrl;
    switch(pDevCtrl->EnetInfo.PhyType) {

        case BP_ENET_INTERNAL_PHY:
		case BP_ENET_EXTERNAL_PHY:
            /* do we need to set mii clock? do soft reset of phy, default is 10Base-T */
            /* reset phy */
            mii_soft_reset(dev, pDevCtrl->EnetInfo.PhyAddress);
            mii_setup(dev);
            break;
        case BP_ENET_EXTERNAL_GPHY:
			txrx_ctrl->rgmii_oob_ctrl |= RGMII_MODE_EN;
			txrx_ctrl->rgmii_oob_ctrl |= (1 << 16);	/* Don't shift tx clock by 90 degree */
			/* Find out if the external PHY is really GPHY, advertise 1000 ability if it is*/
			data32 = mii_read(dev, pDevCtrl->EnetInfo.PhyAddress, MII_BMSR);
			if (data32 & BMSR_ERCAP) {
				data32 = mii_read(dev, pDevCtrl->EnetInfo.PhyAddress, MII_ESTATUS);
				advertise = mii_read(dev, pDevCtrl->EnetInfo.PhyAddress, MII_CTRL1000);
				
				if (data32 & ESTATUS_1000_TFULL)
					advertise |= ADVERTISE_1000FULL;
				else if (data32 & ESTATUS_1000_THALF)
					advertise |= ADVERTISE_1000HALF;

				mii_write(dev, pDevCtrl->EnetInfo.PhyAddress, MII_CTRL1000, advertise);
			}
            mii_setup(dev);
            break;
		case BP_ENET_EXTERNAL_GPHY_IBS:
			txrx_ctrl->rgmii_oob_ctrl |= RGMII_MODE_EN;
			txrx_ctrl->rgmii_oob_ctrl |= (1 << 16);
			/* Use in-band signaling for auto config.*/
			txrx_ctrl->rgmii_oob_ctrl |= OOB_DISABLE;
			umac->cmd |= CMD_AUTO_CONFIG;
			/* Advertise 1000Base capability, neccesary?*/
			data32 = mii_read(dev, pDevCtrl->EnetInfo.PhyAddress, MII_BMSR);
			if (data32 & BMSR_ERCAP) {
				data32 = mii_read(dev, pDevCtrl->EnetInfo.PhyAddress, MII_ESTATUS);
				advertise = mii_read(dev, pDevCtrl->EnetInfo.PhyAddress, MII_CTRL1000);
				
				if (data32 & ESTATUS_1000_TFULL)
					advertise |= ADVERTISE_1000FULL;
				else if (data32 & ESTATUS_1000_THALF)
					advertise |= ADVERTISE_1000HALF;

				mii_write(dev, pDevCtrl->EnetInfo.PhyAddress, MII_CTRL1000, advertise);
			}
            mii_setup(dev);
            break;
		case BP_ENET_EXTERNAL_MOCA:
			umac->cmd = umac->cmd  | (UMAC_SPEED_1000 << CMD_SPEED_SHIFT);
			break;
        default:
            break;
    }

    return 0;
}