Пример #1
0
static int32_t mvl_mii_write(const struct gcu_adapter *adapter, uint32_t mphy, uint32_t phy_num, uint32_t reg_addr, uint16_t phy_data)
{
        int32_t cnt, rc;
        uint16_t smi_cmd_reg;

        smi_cmd_reg = gen_mvl_smi_cmd_reg(phy_num, reg_addr, MVL_SMI_WRITE_OP); 
        rc = mii_write(adapter, mphy, MVL_SMI_DATA_REG, phy_data); 
	if (rc < 0)
		return -1;
        rc = mii_write(adapter, mphy, MVL_SMI_CMD_REG, smi_cmd_reg);
	if (rc < 0)
		return -1;
        
	cnt = 0;
        do {
            udelay(0x32);
            rc = mii_read(adapter, mphy, MVL_SMI_CMD_REG, &smi_cmd_reg);
	    if (rc < 0)
		return -1;
	    if (cnt++ > 10000)
		return -1;
        } while ((smi_cmd_reg & (1 << 15)));

	return 0;
}
Пример #2
0
/* phy_tuning_mse */
void phy_tuning_mse(struct net_device *dev) 
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    volatile EmacRegisters *emac = pDevCtrl->emac;
    int phyaddr;
    int val;
    int i = 0;
    int retry = 0;

    phyaddr = pDevCtrl->EnetInfo.ucPhyAddress;
    val = mii_read(dev, phyaddr, MII_BRCM_TEST);
    val |= MII_BRCM_TEST_SHADOW_ENABLE;
    mii_write(dev, phyaddr, MII_BRCM_TEST, val); // enabled shadow mode

    do {
        i++;
        val = mii_read(dev, phyaddr, MII_AUX_STATUS3); // read the MSE value
        if ((val & MII_AUX_STATUS3_MSE_MASK) >= 0x4000) {
            val = mii_read(dev, phyaddr, MII_TX_CONTROL);
            val &= ~MII_TX_CONTROL_PGA_FIX_ENABLE;
            mii_write(dev, phyaddr, MII_TX_CONTROL, val); // pga fix disable
            udelay(100); /* wait ~100usec */
            val |= MII_TX_CONTROL_PGA_FIX_ENABLE;
            mii_write(dev, phyaddr, MII_TX_CONTROL, val); // pga fix enable
            i = 0;
            retry++;
        }
        if ((i > 12) || (retry > 2)) // read twelve times to ensure good 
            break;
    } while (1);

    val = mii_read(dev, phyaddr, MII_BRCM_TEST);
    val &= ~MII_BRCM_TEST_SHADOW_ENABLE;
    mii_write(dev, phyaddr, MII_BRCM_TEST, val); // disabled shadow mode
}
Пример #3
0
/* BCM5325E register access through MDC/MDIO */
static void ethsw_mdio_rreg(struct net_device *dev, int page, int reg, uint8 *data, int len)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    volatile EmacRegisters *emac; 
    int cmd, res, ret;
    int max_retry = 0;

    emac = pDevCtrl->emac;
    cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd);

    cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_READ;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd);

    do {
        res = mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17);
        udelay(10);
    } while ((max_retry++ < 5) &&
             ((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE));

    ret = 0;
    ret |= mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24) << 0;
    ret |= mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25) << 16;
    switch (len) {
        case 1:
            *data = (uint8)ret;
            break;
        case 2:
            *(uint16 *)data = (uint16)ret;
            break;
        case 4:
            *(uint32 *)data = ret;
            break;
    }
}
Пример #4
0
void mac_phy_reset(void){
  palSetPad(GPIOD, GPIOD_EPHY_NRST);
  halPolledDelay(BOARD_PHY_HARD_RESET_DELAY);
  /* PHY soft reset procedure.*/
  mii_write(&ETHD1, MII_BMCR, BMCR_RESET);
  while (mii_read(&ETHD1, MII_BMCR) & BMCR_RESET)
    ;
  mii_write(&ETHD1, PHYCTRL2, mii_read(&ETHD1, PHYCTRL2) | RMII_RCLKSEL);
}
Пример #5
0
void mii_switch_unPort_vlan_base_mode(struct net_device *dev)
{
    uint16 v16;
    uint8 i=0;

    BcmEnet_devctrl* pDevCtrl = NULL;

   /*add of support ADM6996M LSW by l39225 20061218*/
    if(dev == NULL)
    {
    	  printk("  dev is NULL\n");
    	  return;
    }
    
    pDevCtrl= netdev_priv(dev);
    if(pDevCtrl == NULL)
    {
    	  printk("  pDevCtrl is NULL\n");
    	  return;
    }


   if ( ESW_TYPE_ADM6996M == pDevCtrl->ethSwitch.type)
   {
   	    int val;
   	    
	     val =  0x2f;
	     for (i =0;i<4;i++)
	     {
	 		mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*i , val);
	     }

	      val = 0x30;
	      mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*4 , val);

	      val = 0x3f;
	      mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*5 , val); 	
	    
   }
   /*end of support ADM6996M LSW by l39225 20061218*/
  else
  {
	    v16 = 0xffff; 
	    for (i = 0; i < 5 ; i++)
	    {
	         ethsw_wreg(dev, PAGE_PORT_VLAN, 2*i, &v16, sizeof(v16));
	    }
	    
	    v16 = 0xffff;
	    ethsw_wreg(dev, PAGE_PORT_VLAN, 0x10, &v16, sizeof(v16));
  }
}
Пример #6
0
static void mii_init(au1x00_emac_softc_t *sc)
{
    uint16_t data;

    mii_write(sc, 0, 0x8000);     /* reset */
    do {
        mii_read(sc, 0, &data);
    } while (data & 0x8000);

    mii_write(sc, 0, 0x3200);     /* reset autonegotiation */
    mii_write(sc, 17, 0xffc0);    /* setup LEDs */

}
Пример #7
0
static int
rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
	int phy_addr;
	struct netdev_private *np = netdev_priv(dev);
	struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;

	phy_addr = np->phy_addr;
	switch (cmd) {
	case SIOCDEVPRIVATE:
		break;
	case SIOCGMIIPHY:
		miidata->phy_id = phy_addr;
		break;
	case SIOCGMIIREG:
		miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
		break;
	case SIOCSMIIREG:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
		break;
	default:
		return -EOPNOTSUPP;
	}
	return 0;
}
Пример #8
0
void ethmac_start(const uint8_t* address)
{
    // Copy MAC address
    int i;
    for (i = 0; i < 6; i++)
    {
        mac.mac_address[i] = address[i];
    }

    /* MAC clocks activation and commanded reset procedure.*/
    *ethmac_get_DMABMR() |= ETHMAC_DMABMR__SR;
    while (*ethmac_get_DMABMR() & ETHMAC_DMABMR__SR)
        ;

    // Reset the descriptors
    ethmac_descriptors_reset();

    /* ISR vector enabled.*/
    nvic_enable_interrupt_line(NVIC_IRQ_LINE_ETH);

    /* PHY in power up mode.*/
    mii_write(MII_BMCR, mii_read(MII_BMCR) & ~MII_BMCR__PDOWN);

    /* MAC configuration.*/
    *ethmac_get_MACFFR() = 0;
    *ethmac_get_MACFCR() = 0;
    *ethmac_get_MACVLANTR() = 0;

    /* MAC address setup.*/
    set_mac_address(mac.mac_address);

    /* Transmitter and receiver enabled.
     Note that the complete setup of the MAC is performed when the link
     status is detected.*/
    // No checksum offload
    *ethmac_get_MACCR() = ETHMAC_MACCR__RE | ETHMAC_MACCR__TE;

    /* DMA configuration:
     Descriptor chains pointers.*/
    *ethmac_get_DMARDLAR() = (uint32_t) ethmac_rx_des;
    *ethmac_get_DMATDLAR() = (uint32_t) ethmac_tx_des;

    /* Enabling required interrupt sources.*/
    *ethmac_get_DMASR() = (uint32_t) (*ethmac_get_DMASR());
    *ethmac_get_DMAIER() = ETHMAC_DMAIER__NISE | ETHMAC_DMAIER__AISE
            | ETHMAC_DMAIER__RIE | ETHMAC_DMAIER__TIE;

    /* DMA general settings.*/
    *ethmac_get_DMABMR() = ETHMAC_DMABMR__AAB | ETHMAC_DMABMR__RDP_1Beat
            | ETHMAC_DMABMR__PBL_1Beat;

    /* Transmit FIFO flush.*/
    *ethmac_get_DMAOMR() = ETHMAC_DMAOMR__FTF;
    while (*ethmac_get_DMAOMR() & ETHMAC_DMAOMR__FTF)
        ;

    /* DMA final configuration and start.*/
    *ethmac_get_DMAOMR() = ETHMAC_DMAOMR__DTCEFD | ETHMAC_DMAOMR__RSF
            | ETHMAC_DMAOMR__TSF | ETHMAC_DMAOMR__ST | ETHMAC_DMAOMR__SR;
}
Пример #9
0
/**
 * Check link status
 *
 * @v smsc95xx		SMSC95xx device
 * @ret rc		Return status code
 */
static int smsc95xx_check_link ( struct smsc95xx_device *smsc95xx ) {
	struct net_device *netdev = smsc95xx->netdev;
	int intr;
	int rc;

	/* Read PHY interrupt source */
	intr = mii_read ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_SOURCE );
	if ( intr < 0 ) {
		rc = intr;
		DBGC ( smsc95xx, "SMSC95XX %p could not get PHY interrupt "
		       "source: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Acknowledge PHY interrupt */
	if ( ( rc = mii_write ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_SOURCE,
				intr ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not acknowledge PHY "
		       "interrupt: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Check link status */
	if ( ( rc = mii_check_link ( &smsc95xx->mii, netdev ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not check link: %s\n",
		       smsc95xx, strerror ( rc ) );
		return rc;
	}

	DBGC ( smsc95xx, "SMSC95XX %p link %s (intr %#04x)\n",
	       smsc95xx, ( netdev_link_ok ( netdev ) ? "up" : "down" ), intr );
	return 0;
}
Пример #10
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;
}
Пример #11
0
/* Auto-Configure this MII interface */
static MII_CONFIG mii_autoconfigure(struct net_device *dev)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    int i;
    int val;
    MII_CONFIG eConfig;

    TRACE(("mii_autoconfigure\n"));

    /* enable and restart autonegotiation */
    val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR);
    val |= (BMCR_ANRESTART | BMCR_ANENABLE);
    mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR, val);

    /* wait for it to finish */
    for (i = 0; i < 1000; i++) {
        mdelay(1);
        val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMSR);
        if (val & BMSR_ANEGCOMPLETE) {
            break;
        }
    }

    eConfig = mii_getconfig(dev);
    if (val & BMSR_ANEGCOMPLETE) {
        eConfig |= MII_AUTONEG;
    } 

    return eConfig;
}
Пример #12
0
/**
 * Reset MII interface
 *
 * @v mii		MII interface
 * @ret rc		Return status code
 */
int mii_reset ( struct mii_interface *mii ) {
	unsigned int i;
	int bmcr;
	int rc;

	/* Power-up, enable autonegotiation and initiate reset */
	if ( ( rc = mii_write ( mii, MII_BMCR,
				( BMCR_RESET | BMCR_ANENABLE ) ) ) != 0 ) {
		DBGC ( mii, "MII %p could not write BMCR: %s\n",
		       mii, strerror ( rc ) );
		return rc;
	}

	/* Wait for reset to complete */
	for ( i = 0 ; i < MII_RESET_MAX_WAIT_MS ; i++ ) {

		/* Check if reset has completed */
		bmcr = mii_read ( mii, MII_BMCR );
		if ( bmcr < 0 ) {
			rc = bmcr;
			DBGC ( mii, "MII %p could not read BMCR: %s\n",
			       mii, strerror ( rc ) );
			return rc;
		}

		/* If reset is not complete, delay 1ms and retry */
		if ( bmcr & BMCR_RESET ) {
			mdelay ( 1 );
			continue;
		}

		/* Force autonegotation on again, in case it was
		 * cleared by the reset.
		 */
		if ( ( rc = mii_write ( mii, MII_BMCR, BMCR_ANENABLE ) ) != 0 ){
			DBGC ( mii, "MII %p could not write BMCR: %s\n",
			       mii, strerror ( rc ) );
			return rc;
		}

		DBGC ( mii, "MII %p reset after %dms\n", mii, i );
		return 0;
	}

	DBGC ( mii, "MII %p timed out waiting for reset\n", mii );
	return -ETIMEDOUT;
}
Пример #13
0
/* reset the MII */
static void mii_soft_reset(struct net_device *dev, int PhyAddr) 
{
    int val;

    mii_write(dev, PhyAddr, MII_BMCR, BMCR_RESET);
    udelay(10); /* wait ~10usec */
    do {
        val = mii_read(dev, PhyAddr, MII_BMCR);
    } while (val & BMCR_RESET);
}
Пример #14
0
void
mii_dealan(struct local *l, unsigned timo)
{
	unsigned anar, bound;

	anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA;
	mii_write(l, l->phy, MII_ANAR, anar);
	mii_write(l, l->phy, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
	l->anlpar = 0;
	bound = getsecs() + timo;
	do {
		l->bmsr = mii_read(l, l->phy, MII_BMSR) |
		   mii_read(l, l->phy, MII_BMSR); /* read twice */
		if ((l->bmsr & BMSR_LINK) && (l->bmsr & BMSR_ACOMP)) {
			l->anlpar = mii_read(l, l->phy, MII_ANLPAR);
			break;
		}
		DELAY(10 * 1000);
	} while (getsecs() < bound);
	return;
}
Пример #15
0
static void pga_fix_enable(struct net_device *dev)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    int val;
    int phyaddr;

    phyaddr = pDevCtrl->EnetInfo.ucPhyAddress;
    val = (MII_BRCM_TEST_HARDRESET |
           MII_BRCM_TEST_10BT_SERIAL_NODRIB |
           MII_BRCM_TEST_100TX_POWERDOWN |
           MII_BRCM_TEST_10BT_POWERDOWN );
    mii_write(dev, phyaddr, MII_BRCM_TEST, val); //  reset phy
    val = mii_read(dev, phyaddr, MII_BRCM_TEST);
    val |= MII_BRCM_TEST_SHADOW_ENABLE;
    mii_write(dev, phyaddr, MII_BRCM_TEST, val); //  shadow mode
    val = mii_read(dev, phyaddr, MII_TX_CONTROL);
    val |= MII_TX_CONTROL_PGA_FIX_ENABLE;
    mii_write(dev, phyaddr, MII_TX_CONTROL, val); // pga fix enable
    val = mii_read(dev, phyaddr, MII_BRCM_TEST);
    val &= ~MII_BRCM_TEST_SHADOW_ENABLE;
    mii_write(dev, phyaddr, MII_BRCM_TEST, val); //  shadow mode
}
Пример #16
0
static void vt_enable_port(int phy)
{
	const struct gcu_adapter *adapter;
	adapter = gcu_get_adapter();
	if (!adapter) {
		printk("No adapter??\n");
		return;
	}

	mii_write(adapter, phy, 23, 0x1100);

	gcu_release_adapter(&adapter);
}
Пример #17
0
/* set the MII loopback mode */
static void mii_loopback(struct net_device *dev)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    uint32 val;

    TRACE(("mii_loopback\n"));

    val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR);
    /* Disable autonegotiation */
    val &= ~BMCR_ANENABLE;
    /* Enable Loopback */
    val |= BMCR_LOOPBACK;
    mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR, val);
}
Пример #18
0
static int
mii_set_media_pcs (struct net_device *dev)
{
	__u16 bmcr;
	__u16 esr;
	__u16 anar;
	int phy_addr;
	struct netdev_private *np;
	np = netdev_priv(dev);
	phy_addr = np->phy_addr;

	/* Auto-Negotiation? */
	if (np->an_enable) {
		/* Advertise capabilities */
		esr = mii_read (dev, phy_addr, PCS_ESR);
		anar = mii_read (dev, phy_addr, MII_ANAR) &
			~PCS_ANAR_HALF_DUPLEX &
			~PCS_ANAR_FULL_DUPLEX;
		if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD))
			anar |= PCS_ANAR_HALF_DUPLEX;
		if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD))
			anar |= PCS_ANAR_FULL_DUPLEX;
		anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC;
		mii_write (dev, phy_addr, MII_ANAR, anar);

		/* Soft reset PHY */
		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
		bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN |
		       MII_BMCR_RESET;
		mii_write (dev, phy_addr, MII_BMCR, bmcr);
		mdelay(1);
	} else {
		/* Force speed setting */
		/* PHY Reset */
		bmcr = MII_BMCR_RESET;
		mii_write (dev, phy_addr, MII_BMCR, bmcr);
		mdelay(10);
		if (np->full_duplex) {
			bmcr = MII_BMCR_DUPLEX_MODE;
			printk (KERN_INFO "Manual full duplex\n");
		} else {
			bmcr = 0;
			printk (KERN_INFO "Manual half duplex\n");
		}
		mii_write (dev, phy_addr, MII_BMCR, bmcr);
		mdelay(10);

		/*  Advertise nothing */
		mii_write (dev, phy_addr, MII_ANAR, 0);
	}
	return 0;
}
Пример #19
0
void mii_switch_unmanage_mode(struct net_device *dev)
{
    uint8 value;

    BcmEnet_devctrl* pDevCtrl = NULL;

   /*add of support ADM6996M LSW by l39225 20061218*/
    if(dev == NULL)
    {
    	  printk("  dev is NULL\n");
    	  return;
    }
    
    pDevCtrl= netdev_priv(dev);
    if(pDevCtrl == NULL)
    {
    	  printk("  pDevCtrl is NULL\n");
    	  return;
    }


   if ( ESW_TYPE_ADM6996M == pDevCtrl->ethSwitch.type)
   {
   	    int val;
   	    
   	    val =  mii_read(dev,0,SWI_SYSTEM_CTRLREG3);
   	    val &= ~0x1800;
	    mii_write(dev, 0, SWI_SYSTEM_CTRLREG3, val);
	    
   }
   /*end of support ADM6996M LSW by l39225 20061218*/
  else 
  {
	    ethsw_rreg(dev, PAGE_CONTROL, REG_SWITCH_MODE, &value, sizeof(value));
	    value &= ~REG_SWITCH_MODE_FRAME_MANAGE_MODE;
	    ethsw_wreg(dev, PAGE_CONTROL, REG_SWITCH_MODE, &value, sizeof(value));

	    value = 0;
	    ethsw_wreg(dev, PAGE_MANAGEMENT, REG_GLOBAL_CONFIG, &value, sizeof(value));
  }
}
Пример #20
0
void ethmac_enable()
{
    // Enable the clocks
    rcc_ahb_enable(RCC_AHB_BIT_ETHMAC);
    rcc_ahb_enable(RCC_AHB_BIT_ETHMACTX);
    rcc_ahb_enable(RCC_AHB_BIT_ETHMACRX);

    // Configure MII
    uint32_t tmp = *ethmac_get_MACMIIAR();
    tmp &= ~ETHMAC_MACMIIAR__CR_MASK;
    tmp |= mac.mii_cr;
    *ethmac_get_MACMIIAR() = tmp;

    // Find the PHY address
    mii_find_phy_addr();

    // Reset the PHY
    log_debug("Resetting PHY... (was %04x)", mii_read(MII_BMCR));
    mii_write(MII_BMCR, MII_BMCR__RESET);
    while (mii_read(MII_BMCR) & MII_BMCR__RESET)
        ;
    log_debug("\tOK (now %04x)", mii_read(MII_BMCR));
}
Пример #21
0
static void ethsw_mdio_wreg(struct net_device *dev, int page, int reg, uint8 *data, int len)
{
    BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
    volatile EmacRegisters *emac; 
    uint32 cmd, res;
    int val = 0;
    int max_retry = 0;

    emac = pDevCtrl->emac;
    switch (len) {
        case 1:
            val = *data;
            break;
        case 2:
            val = *(uint16 *)data;
            break;
        case 4:
            val = *(uint32 *)data;
            break;
    }
    cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd);

    cmd = val>>0 & 0xffff;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24, cmd);
    cmd = val>>16 & 0xffff;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25, cmd);
    cmd = 0;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG26, cmd);
    cmd = 0;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG27, cmd);

    cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_WRITE;
    mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd);

    do {
        res = mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17);
        udelay(10);
    } while ((max_retry++ < 5) &&
             ((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE));
}
Пример #22
0
static int
mii_set_media (struct net_device *dev)
{
	__u16 pscr;
	__u16 bmcr;
	__u16 bmsr;
	__u16 anar;
	int phy_addr;
	struct netdev_private *np;
	np = netdev_priv(dev);
	phy_addr = np->phy_addr;

	/* Does user set speed? */
	if (np->an_enable) {
		/* Advertise capabilities */
		bmsr = mii_read (dev, phy_addr, MII_BMSR);
		anar = mii_read (dev, phy_addr, MII_ANAR) &
			     ~MII_ANAR_100BX_FD &
			     ~MII_ANAR_100BX_HD &
			     ~MII_ANAR_100BT4 &
			     ~MII_ANAR_10BT_FD &
			     ~MII_ANAR_10BT_HD;
		if (bmsr & MII_BMSR_100BX_FD)
			anar |= MII_ANAR_100BX_FD;
		if (bmsr & MII_BMSR_100BX_HD)
			anar |= MII_ANAR_100BX_HD;
		if (bmsr & MII_BMSR_100BT4)
			anar |= MII_ANAR_100BT4;
		if (bmsr & MII_BMSR_10BT_FD)
			anar |= MII_ANAR_10BT_FD;
		if (bmsr & MII_BMSR_10BT_HD)
			anar |= MII_ANAR_10BT_HD;
		anar |= MII_ANAR_PAUSE | MII_ANAR_ASYMMETRIC;
		mii_write (dev, phy_addr, MII_ANAR, anar);

		/* Enable Auto crossover */
		pscr = mii_read (dev, phy_addr, MII_PHY_SCR);
		pscr |= 3 << 5;	/* 11'b */
		mii_write (dev, phy_addr, MII_PHY_SCR, pscr);

		/* Soft reset PHY */
		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
		bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | MII_BMCR_RESET;
		mii_write (dev, phy_addr, MII_BMCR, bmcr);
		mdelay(1);
	} else {
		/* Force speed setting */
		/* 1) Disable Auto crossover */
		pscr = mii_read (dev, phy_addr, MII_PHY_SCR);
		pscr &= ~(3 << 5);
		mii_write (dev, phy_addr, MII_PHY_SCR, pscr);

		/* 2) PHY Reset */
		bmcr = mii_read (dev, phy_addr, MII_BMCR);
		bmcr |= MII_BMCR_RESET;
		mii_write (dev, phy_addr, MII_BMCR, bmcr);

		/* 3) Power Down */
		bmcr = 0x1940;	/* must be 0x1940 */
		mii_write (dev, phy_addr, MII_BMCR, bmcr);
		mdelay (100);	/* wait a certain time */

		/* 4) Advertise nothing */
		mii_write (dev, phy_addr, MII_ANAR, 0);

		/* 5) Set media and Power Up */
		bmcr = MII_BMCR_POWER_DOWN;
		if (np->speed == 100) {
			bmcr |= MII_BMCR_SPEED_100;
			printk (KERN_INFO "Manual 100 Mbps, ");
		} else if (np->speed == 10) {
			printk (KERN_INFO "Manual 10 Mbps, ");
		}
		if (np->full_duplex) {
			bmcr |= MII_BMCR_DUPLEX_MODE;
			printk (KERN_CONT "Full duplex\n");
		} else {
			printk (KERN_CONT "Half duplex\n");
		}
#if 0
		/* Set 1000BaseT Master/Slave setting */
		mscr = mii_read (dev, phy_addr, MII_MSCR);
		mscr |= MII_MSCR_CFG_ENABLE;
		mscr &= ~MII_MSCR_CFG_VALUE = 0;
#endif
		mii_write (dev, phy_addr, MII_BMCR, bmcr);
		mdelay(10);
	}
	return 0;
}
Пример #23
0
void mii_switch_frame_manage_mode(struct net_device *dev)
{
    uint8 value;
    BcmEnet_devctrl* pDevCtrl = NULL;
    int i = 0;

   /*add of support ADM6996M LSW by l39225 20061218*/
    if(dev == NULL)
    {
    	  printk("  dev is NULL\n");
    	  return;
    }
    
    pDevCtrl= netdev_priv(dev);
    if(pDevCtrl == NULL)
    {
    	  printk("  pDevCtrl is NULL\n");
    	  return;
    }


   if ( ESW_TYPE_ADM6996M == pDevCtrl->ethSwitch.type)
   {
   	    int val;
   	    
   	    val =  mii_read(dev,0,SWI_SYSTEM_CTRLREG3);
   	    val |= 0xe000;
   	    val &= 0xafff;
   	    val |=  0x1800;
	    mii_write(dev, 0, SWI_SYSTEM_CTRLREG3, val);

#if 0    //VALN TAG
	    val = mii_read(dev,0,SWI_ARP_CTRLREG );
	    val |=0x40;
	    mii_write(dev, 0, SWI_ARP_CTRLREG , val);
#endif

	    val = BRCM_TYPE;
	    mii_write(dev, 0, SWI_ADMTAG_ETHTYPE , val);

	    val = 0x1ff;
	    mii_write(dev, 0, SWI_SPCTAG_INSCTRL , val);


	     val =  0x2f;
	     for (i =0;i<4;i++)
	     {
	 		mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*i , val);
	     }

	      val = 0x30;
	      mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*4 , val);

	      val = 0x3f;
	      mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*5 , val); 
	    
   }
   /*end of support ADM6996M LSW by l39225 20061218*/
   else 
   {
	    ethsw_rreg(dev, PAGE_CONTROL, REG_SWITCH_MODE, &value, sizeof(value));
	    value |= REG_SWITCH_MODE_FRAME_MANAGE_MODE;
	    value |= REG_SWITCH_MODE_SW_FWDG_EN;
	    ethsw_wreg(dev, PAGE_CONTROL, REG_SWITCH_MODE, &value, sizeof(value));

	    ethsw_rreg(dev, PAGE_CONTROL, REG_MII_PORT_CONTROL, &value, sizeof(value));
	    value |= REG_MII_PORT_CONTROL_RX_UCST_EN;
	    value |= REG_MII_PORT_CONTROL_RX_MCST_EN;
	    value |= REG_MII_PORT_CONTROL_RX_BCST_EN;
	    ethsw_wreg(dev, PAGE_CONTROL, REG_MII_PORT_CONTROL, &value, sizeof(value));

	    value = 0x80;
	    ethsw_wreg(dev, PAGE_MANAGEMENT, REG_GLOBAL_CONFIG, &value, sizeof(value));

	    ethsw_rreg(dev, PAGE_VLAN, REG_VLAN_CTRL5, &value, sizeof(value));
	    value |= REG_VLAN_CTRL5_ENBL_MANAGE_RX_BYPASS;
	    value |= REG_VLAN_CTRL5_ENBL_CRC_GEN;
	    ethsw_wreg(dev, PAGE_VLAN, REG_VLAN_CTRL5, &value, sizeof(value));
	    
	    /* start of y42304 20060809: 使能lanswitch接收BPDU报文 */
	    ethsw_rreg(dev, PAGE_MANAGEMENT, REG_GLOBAL_CONFIG, &value, sizeof(value));
	    //value |= 0x82;
	    value |= 0x8a;
	    ethsw_wreg(dev, PAGE_MANAGEMENT, REG_GLOBAL_CONFIG, &value, sizeof(value));
	    /* end of y42304 20060809: 使能lanswitch接收BPDU报文 */
   }

}
Пример #24
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;
}
Пример #25
0
/*start of add lsw port separate by port_base vlan by 139225 2006-8-15*/
void mii_switch_port_vlan_base_mode(struct net_device *dev,unsigned short vlan)
{
    uint16 v16;
    uint8 i = 0;
    uint8 j = 0;
    uint8 uPort[5] ={0,0,0,0,0};
    int val = 0;

    BcmEnet_devctrl* pDevCtrl = NULL;

   /*add of support ADM6996M LSW by l39225 20061218*/
    if(dev == NULL)
    {
    	  printk("  dev is NULL\n");
    	  return;
    }
    
    pDevCtrl= netdev_priv(dev);
    if(pDevCtrl == NULL)
    {
    	  printk("  pDevCtrl is NULL\n");
    	  return;
    }

    for ( i= 0; i < 5; i++)
    {
        if( ((vlan >> i ) & 0x0001) > 0)
        {
             uPort[i] = 1;
        }
    }

   if ( ESW_TYPE_ADM6996M != pDevCtrl->ethSwitch.type)
   {
   	    for(i = 0; i < 5;i++)
	    {
	        for (j= i+1; j < 5; j++)
	        {
	             if ( (uPort[i] > 0) && (uPort[j] > 0) )
	             {
	                ethsw_rreg(dev, PAGE_PORT_VLAN, i*2, &v16, sizeof(v16));
	                v16 |= 0x0100; //forward only to MII port
	                v16 |= (0x0001 <<  j);
	                ethsw_wreg(dev, PAGE_PORT_VLAN, i*2, &v16, sizeof(v16));

	                ethsw_rreg(dev, PAGE_PORT_VLAN,  2*j, &v16, sizeof(v16));
	                v16 |= 0x0100;
	                v16 |= (0x0001 << i);
	                ethsw_wreg(dev, PAGE_PORT_VLAN,  2*j, &v16, sizeof(v16));
	             }
	             else if( (uPort[i] ==  0) && (uPort[j] == 0))
	             {
	                   continue;
	             }
	             else
	             {
	                  ethsw_rreg(dev, PAGE_PORT_VLAN, i*2, &v16, sizeof(v16));
	                  v16 |= 0x0100; //forward only to MII port
	                  v16 &= ~(0x0001 <<  j);
	                  ethsw_wreg(dev, PAGE_PORT_VLAN, i*2, &v16, sizeof(v16));

	                  ethsw_rreg(dev, PAGE_PORT_VLAN, 2*j, &v16, sizeof(v16));
	                  v16 |= 0x0100;
	                  v16 &= ~(0x0001 << i);
	                  ethsw_wreg(dev, PAGE_PORT_VLAN, 2*j, &v16, sizeof(v16));
	             }
	        }     
   	   }
   	    v16 = 0xffff;
           ethsw_wreg(dev, PAGE_PORT_VLAN , 0x10, &v16, sizeof(v16));
   }
   else
   {
	    for(i = 0; i < 5;i++)
	    {
	        for (j= i+1; j < 5; j++)
	        {
	             if ( (uPort[i] > 0) && (uPort[j] > 0) )
	             {
		               val = mii_read(dev,0,SWI_VLANFILTER_LOWREG0 +2*i);
		               val |= 0x20; //forward only to MII port
		               val |= (0x0001 <<  j);
		               mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*i , val);

		               val = mii_read(dev,0,SWI_VLANFILTER_LOWREG0 +2*j);
		               val |= 0x20; //forward only to MII port
		               val |= (0x0001 << i);
		               mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*j , val);
	    
	             }
	             else if( (uPort[i] ==  0) && (uPort[j] == 0))
	             {
	                   continue;
	             }
	             else
	             {
	                  val = mii_read(dev,0,SWI_VLANFILTER_LOWREG0 +2*i);
	                  val |= 0x020; //forward only to MII port
	                  val &= ~(0x0001 <<  j);
	                  mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*i , val);

	                  val = mii_read(dev,0,SWI_VLANFILTER_LOWREG0 +2*j);
	                  val |= 0x20;
	                  val &= ~(0x0001 << i);
	                  mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*j , val);
	             }
	        }
	    }
	    
	   val = 0x3f;
	   mii_write(dev, 0, SWI_VLANFILTER_LOWREG0 +2*5 , val); 	
   	}
}
Пример #26
0
/**
 * Open network device
 *
 * @v netdev		Network device
 * @ret rc		Return status code
 */
static int smsc95xx_open ( struct net_device *netdev ) {
	struct smsc95xx_device *smsc95xx = netdev->priv;
	union smsc95xx_mac mac;
	int rc;

	/* Clear stored interrupt status */
	smsc95xx->int_sts = 0;

	/* Copy MAC address */
	memset ( &mac, 0, sizeof ( mac ) );
	memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );

	/* Configure bulk IN empty response */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_HW_CFG,
				      SMSC95XX_HW_CFG_BIR ) ) != 0 )
		goto err_hw_cfg;

	/* Open USB network device */
	if ( ( rc = usbnet_open ( &smsc95xx->usbnet ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not open: %s\n",
		       smsc95xx, strerror ( rc ) );
		goto err_open;
	}

	/* Configure interrupt endpoint */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_INT_EP_CTL,
				      ( SMSC95XX_INT_EP_CTL_RXDF_EN |
					SMSC95XX_INT_EP_CTL_PHY_EN ) ) ) != 0 )
		goto err_int_ep_ctl;

	/* Configure bulk IN delay */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_BULK_IN_DLY,
				      SMSC95XX_BULK_IN_DLY_SET ( 0 ) ) ) != 0 )
		goto err_bulk_in_dly;

	/* Configure MAC */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_MAC_CR,
				      ( SMSC95XX_MAC_CR_RXALL |
					SMSC95XX_MAC_CR_FDPX |
					SMSC95XX_MAC_CR_MCPAS |
					SMSC95XX_MAC_CR_PRMS |
					SMSC95XX_MAC_CR_PASSBAD |
					SMSC95XX_MAC_CR_TXEN |
					SMSC95XX_MAC_CR_RXEN ) ) ) != 0 )
		goto err_mac_cr;

	/* Configure transmit datapath */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_TX_CFG,
				      SMSC95XX_TX_CFG_ON ) ) != 0 )
		goto err_tx_cfg;

	/* Write MAC address high register */
	if ( ( rc = smsc95xx_raw_writel ( smsc95xx, SMSC95XX_ADDRH,
					  mac.addr.h ) ) != 0 )
		goto err_addrh;

	/* Write MAC address low register */
	if ( ( rc = smsc95xx_raw_writel ( smsc95xx, SMSC95XX_ADDRL,
					  mac.addr.l ) ) != 0 )
		goto err_addrl;

	/* Enable PHY interrupts */
	if ( ( rc = mii_write ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_MASK,
				( SMSC95XX_PHY_INTR_ANEG_DONE |
				  SMSC95XX_PHY_INTR_LINK_DOWN ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not set PHY interrupt "
		       "mask: %s\n", smsc95xx, strerror ( rc ) );
		goto err_phy_intr_mask;
	}

	/* Update link status */
	smsc95xx_check_link ( smsc95xx );

	return 0;

 err_phy_intr_mask:
 err_addrl:
 err_addrh:
 err_tx_cfg:
 err_mac_cr:
 err_bulk_in_dly:
 err_int_ep_ctl:
	usbnet_close ( &smsc95xx->usbnet );
 err_open:
 err_hw_cfg:
	smsc95xx_reset ( smsc95xx );
	return rc;
}
Пример #27
0
void vEMACInit( void )
{
int iData;
extern int periph_clk_khz;
const unsigned portCHAR ucMACAddress[] =
{
	configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5
};

	/* Enable the ENET clock. */
	SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;

	/* Allow concurrent access to MPU controller to avoid bus errors. */
	MPU_CESR = 0;

	prvInitialiseDescriptors();

	/* Reset and enable. */
	ENET_ECR = ENET_ECR_RESET_MASK;
	
	/* Wait at least 8 clock cycles */
	vTaskDelay( 2 );
	
	/* Start the MII interface*/
	mii_init( 0, periph_clk_khz / 1000L );

	/* Configure the transmit interrupt. */
	set_irq_priority( emacTX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
	enable_irq( emacTX_INTERRUPT_NO );

	/* Configure the receive interrupt. */
	set_irq_priority( emacRX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
	enable_irq( emacRX_INTERRUPT_NO );

	/* Configure the error interrupt. */
	set_irq_priority( emacERROR_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
	enable_irq( emacERROR_INTERRUPT_NO );

	/* Configure the pins to the PHY - RMII mode used. */
	PORTB_PCR0  = PORT_PCR_MUX( 4 ); /* RMII0_MDIO / MII0_MDIO. */
	PORTB_PCR1  = PORT_PCR_MUX( 4 ); /* RMII0_MDC / MII0_MDC */
	PORTA_PCR14 = PORT_PCR_MUX( 4 ); /* RMII0_CRS_DV / MII0_RXDV */
	PORTA_PCR12 = PORT_PCR_MUX( 4 ); /* RMII0_RXD1 / MII0_RXD1 */
	PORTA_PCR13 = PORT_PCR_MUX( 4 ); /* RMII0_RXD0/MII0_RXD0 */
	PORTA_PCR15 = PORT_PCR_MUX( 4 ); /* RMII0_TXEN/MII0_TXEN */
	PORTA_PCR16 = PORT_PCR_MUX( 4 ); /* RMII0_TXD0/MII0_TXD0 */
	PORTA_PCR17 = PORT_PCR_MUX( 4 ); /* RMII0_TXD1/MII0_TXD1 */

	/* Is there communication with the PHY? */
	do
	{
		vTaskDelay( emacLINK_DELAY );
		iData = 0xFFFF;
		mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &iData );
	
	} while( iData == 0xFFFF );

	/* Start to auto negotiate. */
	mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
	
	/* Wait for auto negotiate to complete. */
	do
	{
		vTaskDelay( emacLINK_DELAY );
		mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &iData );
	
	} while( !( iData & PHY_BMSR_AN_COMPLETE ) );

	/* A link has been established.  What was negotiated? */
	iData = 0;
	mii_read( 0, configPHY_ADDRESS, emacPHY_STATUS, &iData );

	/* Clear the Individual and Group Address Hash registers */
	ENET_IALR = 0;
	ENET_IAUR = 0;
	ENET_GALR = 0;
	ENET_GAUR = 0;

	/* Set the Physical Address for the selected ENET */
	enet_set_address( 0, ucMACAddress );

	ENET_RCR = ENET_RCR_MAX_FL( UIP_BUFSIZE ) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;

	/* Clear the control registers. */
	ENET_TCR = 0;

	if( iData & emacPHY_DUPLEX_STATUS )
	{
		/* Full duplex */
		ENET_RCR &= ( unsigned long )~ENET_RCR_DRT_MASK;
		ENET_TCR |= ENET_TCR_FDEN_MASK;
	}
	else
	{
		/* Half duplex */
		ENET_RCR |= ENET_RCR_DRT_MASK;
		ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK;
	}

	if( iData & emacPHY_SPEED_STATUS )
	{
		/* 10Mbps */
		ENET_RCR |= ENET_RCR_RMII_10T_MASK;
	}

    ENET_ECR = ENET_ECR_EN1588_MASK;

	/* Store and forward checksum. */
	ENET_TFWR = ENET_TFWR_STRFWD_MASK;

	/* Set Rx Buffer Size */
	ENET_MRBR = ( unsigned short ) UIP_BUFSIZE;
	
	/* Point to the start of the circular Rx buffer descriptor queue */
	ENET_RDSR = ( unsigned long ) &( xRxDescriptors[ 0 ] );
	
	/* Point to the start of the circular Tx buffer descriptor queue */
	ENET_TDSR = ( unsigned long ) &( xTxDescriptors[ 0 ] );
	
	/* Clear all ENET interrupt events */
	ENET_EIR = ( unsigned long ) -1;
	
	/* Enable interrupts. */
	ENET_EIMR = 0
			/*rx irqs*/
			| ENET_EIMR_RXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_RXB_MASK*/
			/*xmit irqs*/
			| ENET_EIMR_TXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_TXB_MASK*/
			/*enet irqs*/
			| ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK
			;
	
	/* Enable the MAC itself. */
	ENET_ECR |= ENET_ECR_ETHEREN_MASK;
	
	/* Indicate that there have been empty receive buffers produced */
	ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
Пример #28
0
void mii_enablephyinterrupt(struct net_device *dev, int phy_id)
{
    mii_write(dev, phy_id, MII_INTERRUPT, 
        MII_INTR_ENABLE | MII_INTR_MASK_FDX | MII_INTR_MASK_LINK_SPEED);
}
Пример #29
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;
}
Пример #30
0
int mii_init(struct net_device *dev)
{
	struct BcmEnet_devctrl *pDevCtrl = netdev_priv(dev);
	volatile struct uniMacRegs *umac;
	int bmcr;

	umac = pDevCtrl->umac;
	pDevCtrl->mii.phy_id = pDevCtrl->phyAddr;
	pDevCtrl->mii.phy_id_mask = 0x1f;
	pDevCtrl->mii.reg_num_mask = 0x1f;
	pDevCtrl->mii.dev = dev;
	pDevCtrl->mii.mdio_read = mii_read;
	pDevCtrl->mii.mdio_write = mii_write;

	/* Enable autoneg if it's not */
	bmcr = mii_read(dev, pDevCtrl->phyAddr, MII_BMCR);
	switch (pDevCtrl->phyType) {

	case BRCM_PHY_TYPE_INT:
		pDevCtrl->mii.supports_gmii = 0;
		pDevCtrl->sys->sys_port_ctrl = PORT_MODE_INT_EPHY;
		/* enable APD */
		pDevCtrl->ext->ext_pwr_mgmt |= EXT_PWR_DN_EN_LD;
		pDevCtrl->ext->ext_pwr_mgmt |= EXT_PHY_RESET;
		udelay(5);
		pDevCtrl->ext->ext_pwr_mgmt &= ~EXT_PHY_RESET;
		/* enable 64 clock MDIO */
		mii_write(dev, pDevCtrl->phyAddr, 0x1d, 0x1000);
		mii_read(dev, pDevCtrl->phyAddr, 0x1d);
		printk(KERN_INFO "Config internal EPHY through MDIO\n");
		break;
	case BRCM_PHY_TYPE_EXT_MII:
		pDevCtrl->mii.supports_gmii = 0;
		pDevCtrl->sys->sys_port_ctrl = PORT_MODE_EXT_EPHY;
		mii_write(dev, pDevCtrl->phyAddr, MII_BMCR, bmcr|MII_BMCR);
		printk(KERN_INFO "Config EPHY through MDIO\n");
		break;
	case BRCM_PHY_TYPE_EXT_RGMII:
		GENET_RGMII_OOB_CTRL(pDevCtrl) |= RGMII_MODE_EN;
		/* Don't shift tx clock by 90 degree, does it still needed? */
		GENET_RGMII_OOB_CTRL(pDevCtrl) |= (1 << 16);
		pDevCtrl->mii.supports_gmii = 1;
		pDevCtrl->sys->sys_port_ctrl = PORT_MODE_EXT_GPHY;
		mii_write(dev, pDevCtrl->phyAddr, MII_BMCR, bmcr|MII_BMCR);
		printk(KERN_INFO "Config GPHY through MDIO\n");
		break;
	case BRCM_PHY_TYPE_EXT_RGMII_IBS:
		GENET_RGMII_OOB_CTRL(pDevCtrl) |= RGMII_MODE_EN;
		GENET_RGMII_OOB_CTRL(pDevCtrl) |= (1 << 16);
		/* Use in-band signaling for auto config.*/
		GENET_RGMII_OOB_CTRL(pDevCtrl) |= OOB_DISABLE;
		umac->cmd |= CMD_AUTO_CONFIG;
		pDevCtrl->mii.supports_gmii = 1;
		pDevCtrl->sys->sys_port_ctrl = PORT_MODE_EXT_GPHY;
		mii_write(dev, pDevCtrl->phyAddr, MII_BMCR, bmcr|MII_BMCR);
		printk(KERN_INFO "Automatic Config GPHY\n");
		break;
	case BRCM_PHY_TYPE_MOCA:
		printk(KERN_INFO "Config MoCA...\n");
		umac->cmd = umac->cmd  | (UMAC_SPEED_1000 << CMD_SPEED_SHIFT);
		pDevCtrl->mii.force_media = 1;
		pDevCtrl->sys->sys_port_ctrl = PORT_MODE_INT_GPHY;
		break;
	default:
		printk(KERN_ERR "unknown phy_type : %d\n", pDevCtrl->phyType);
		break;
	}

	return 0;
}