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; }
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; }
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; }