/******************************************************************************* * driverFindPhyID * * DESCRIPTION: * This function get Phy ID from Phy register 2 and 3. * * INPUTS: * hwPort - port number where the Phy is connected * * OUTPUTS: * phyId - Phy ID * * RETURNS: * GT_OK - if found Marvell Phy, * GT_FAIL - othrwise. * * COMMENTS: * None. * *******************************************************************************/ static GT_STATUS driverFindPhyID ( IN GT_QD_DEV *dev, IN GT_U8 hwPort, OUT GT_U32 *phyID ) { GT_U16 ouiMsb, ouiLsb; GT_STATUS status; if((status= hwReadPhyReg(dev,hwPort,2,&ouiMsb)) != GT_OK) { DBG_INFO(("Not able to read Phy Register.\n")); return status; } if((status= hwReadPhyReg(dev,hwPort,3,&ouiLsb)) != GT_OK) { DBG_INFO(("Not able to read Phy Register.\n")); return status; } if(ouiMsb != MARVELL_OUI_MSb) return GT_FAIL; *phyID = (GT_U32)ouiLsb; return GT_OK; }
GT_STATUS gprtGetPhyIntPortSummary ( IN GT_QD_DEV *dev, OUT GT_U16 *intPortMask ) { GT_STATUS retVal; GT_U8 hwPort; /* the physical port number */ GT_U16 portVec; #ifdef GT_USE_MAD if (dev->use_mad==GT_TRUE) return gprtGetPhyIntPortSummary_mad(dev, intPortMask); #endif DBG_INFO(("gprtGetPhyIntPortSummary Called.\n")); /* translate LPORT 0 to hardware port */ hwPort = GT_LPORT_2_PORT(0); *intPortMask=0; if (IS_IN_DEV_GROUP(dev,DEV_DEV_PHY_INTERRUPT)) { return GT_NOT_SUPPORTED; } if (IS_IN_DEV_GROUP(dev,DEV_INTERNAL_GPHY)) { /* get the interrupt port summary from global register */ retVal = hwGetGlobal2RegField(dev,QD_REG_PHYINT_SOURCE,0,dev->maxPorts,&portVec); GT_GIG_PHY_INT_MASK(dev,portVec); *intPortMask = (GT_U16)GT_PORTVEC_2_LPORTVEC(portVec); } else { /* get the interrupt port summary from phy */ retVal = hwReadPhyReg(dev,hwPort, QD_PHY_INT_PORT_SUMMARY_REG, &portVec); *intPortMask = (GT_U16)GT_PORTVEC_2_LPORTVEC(portVec); } if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); } else { DBG_INFO(("OK.\n")); } return retVal; }
static GT_STATUS phySetAutoMode ( IN GT_QD_DEV *dev, IN GT_U8 hwPort, IN GT_PHY_AUTO_MODE mode ) { GT_U16 u16Data; DBG_INFO(("phySetAutoMode Called.\n")); if(hwReadPhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,&u16Data) != GT_OK) { DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG)); return GT_FAIL; } /* Mask out all auto mode related bits. */ u16Data &= ~QD_PHY_MODE_AUTO_AUTO; switch(mode) { case SPEED_AUTO_DUPLEX_AUTO: u16Data |= QD_PHY_MODE_AUTO_AUTO; break; case SPEED_100_DUPLEX_AUTO: u16Data |= QD_PHY_MODE_100_AUTO; break; case SPEED_10_DUPLEX_AUTO: u16Data |= QD_PHY_MODE_10_AUTO; break; case SPEED_AUTO_DUPLEX_FULL: u16Data |= QD_PHY_MODE_AUTO_FULL; break; case SPEED_AUTO_DUPLEX_HALF: u16Data |= QD_PHY_MODE_AUTO_HALF; break; default: DBG_INFO(("Unknown Auto Mode (%d)\n",mode)); return GT_FAIL; } /* Write to Phy AutoNegotiation Advertisement Register. */ if(hwWritePhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data) != GT_OK) { DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d,data:%#x).\n",hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data)); return GT_FAIL; } return GT_OK; }
GT_STATUS gprtGetPhyIntStatus ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_U16* intType ) { GT_STATUS retVal; GT_U8 hwPort; /* the physical port number */ #ifdef GT_USE_MAD if (dev->use_mad==GT_TRUE) return gprtGetPhyIntStatus_mad(dev, port, intType); #endif DBG_INFO(("gprtGetPhyIntStatus Called.\n")); /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PHY(port); if((IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE)) && (hwPort > 3)) { if(!(dev->validSerdesVec & (1 << hwPort))) { if(!((IS_IN_DEV_GROUP(dev,DEV_SERDES_ACCESS_CONFIG)) && (hwPort == 4))) GT_GET_SERDES_PORT(dev,&hwPort); } if(hwPort >= dev->maxPhyNum) { return GT_NOT_SUPPORTED; } } /* check if the port is configurable */ if(!IS_CONFIGURABLE_PHY(dev,hwPort)) { return GT_NOT_SUPPORTED; } retVal = hwReadPhyReg(dev,hwPort, QD_PHY_INT_STATUS_REG, intType); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); } else { DBG_INFO(("OK.\n")); } return retVal; }
/******************************************************************************* * gprtSetPortDuplexMode * * DESCRIPTION: * Sets duplex mode for a specific logical port. This function will keep the speed * and loopback mode to the previous value, but disable others, such as Autonegotiation. * * INPUTS: * port - logical port number * dMode - dulpex mode * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * data sheet register 0.8 - Duplex Mode * *******************************************************************************/ GT_STATUS gprtSetPortDuplexMode ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_BOOL dMode ) { GT_STATUS retVal; /* Functions return value. */ GT_U8 hwPort; /* the physical port number */ GT_U16 u16Data; DBG_INFO(("gprtSetPortDuplexMode Called.\n")); /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); /* check if the port is configurable */ if(!IS_CONFIGURABLE_PHY(dev,hwPort)) { return GT_NOT_SUPPORTED; } if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK) { DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG)); return GT_FAIL; } if(dMode) { u16Data = QD_PHY_RESET | (u16Data & (QD_PHY_LOOPBACK | QD_PHY_SPEED)) | QD_PHY_DUPLEX; } else { u16Data = QD_PHY_RESET | (u16Data & (QD_PHY_LOOPBACK | QD_PHY_SPEED)); } DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x", hwPort,QD_PHY_CONTROL_REG,u16Data)); /* Write to Phy Control Register. */ retVal = hwWritePhyReg(dev,hwPort,QD_PHY_CONTROL_REG,u16Data); if(retVal != GT_OK) DBG_INFO(("Failed.\n")); else DBG_INFO(("OK.\n")); return retVal; }
static MAD_BOOL madSMIRead(MAD_DEV* dev, unsigned int smiAddr, unsigned int reg, unsigned int* value) { GT_STATUS status; GT_U16 data; status = hwReadPhyReg((GT_QD_DEV *)(dev->swDev), smiAddr, reg, &data); if(status == GT_OK) { *value = data; return MAD_TRUE; } else return MAD_FALSE; }
GT_STATUS gprtSetPause ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_BOOL state ) { GT_U8 hwPort; /* the physical port number */ GT_U16 u16Data; GT_STATUS retVal = GT_OK; DBG_INFO(("phySetPause Called.\n")); /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); /* check if the port is configurable */ if(!IS_CONFIGURABLE_PHY(dev,hwPort)) { return GT_NOT_SUPPORTED; } if(hwReadPhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,&u16Data) != GT_OK) { DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG)); return GT_FAIL; } if(state == GT_TRUE) { /* Set the Pause bit. */ u16Data |= QD_PHY_PAUSE; } else { /* Reset the Pause bit. */ u16Data &= ~QD_PHY_PAUSE; } /* Write to Phy AutoNegotiation Advertisement Register. */ if(hwWritePhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data) != GT_OK) { DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d,data:%#x).\n",hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data)); return GT_FAIL; } return retVal; }
GT_STATUS gprtPortRestartAutoNeg ( IN GT_QD_DEV *dev, IN GT_LPORT port ) { GT_STATUS retVal; GT_U8 hwPort; /* the physical port number */ GT_U16 u16Data; DBG_INFO(("gprtPortRestartAutoNeg Called.\n")); /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); /* check if the port is configurable */ if(!IS_CONFIGURABLE_PHY(dev,hwPort)) { return GT_NOT_SUPPORTED; } if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK) { DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG)); return GT_FAIL; } u16Data &= (QD_PHY_DUPLEX | QD_PHY_SPEED); u16Data |= (QD_PHY_RESTART_AUTONEGO | QD_PHY_AUTONEGO); DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x", hwPort,QD_PHY_CONTROL_REG,u16Data)); /* Write to Phy Control Register. */ retVal = hwWritePhyReg(dev,hwPort,QD_PHY_CONTROL_REG,u16Data); if(retVal != GT_OK) DBG_INFO(("Failed.\n")); else DBG_INFO(("OK.\n")); return retVal; }