| #include <Copyright.h> |
| /******************************************************************************** |
| * gtMiiSmiIf.c |
| * |
| * DESCRIPTION: |
| * Includes functions prototypes for initializing and accessing the |
| * MII / SMI interface. |
| * This is the only file to be included from upper layers. |
| * |
| * DEPENDENCIES: |
| * None. |
| * |
| * FILE REVISION NUMBER: |
| * $Revision: 3 $ |
| * |
| *******************************************************************************/ |
| |
| #include <gtDrvSwRegs.h> |
| #include <gtHwCntl.h> |
| #include <gtMiiSmiIf.h> |
| #include <platformDeps.h> |
| #include <gtSem.h> |
| |
| GT_BOOL qdMultiAddrRead (GT_QD_DEV* dev, unsigned int phyAddr , unsigned int MIIReg, |
| unsigned int* value); |
| GT_BOOL qdMultiAddrWrite (GT_QD_DEV* dev, unsigned int phyAddr , unsigned int MIIReg, |
| unsigned int value); |
| /******************************************************************************* |
| * miiSmiIfInit |
| * |
| * DESCRIPTION: |
| * This function initializes the MII / SMI interface. |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * highSmiDevAddr - Indicates whether to use the high device register |
| * addresses when accessing switch's registers (of all kinds) |
| * i.e, the devices registers range is 0x10 to 0x1F, or to |
| * use the low device register addresses (range 0x0 to 0xF). |
| * GT_TRUE - use high addresses (0x10 to 0x1F). |
| * GT_FALSE - use low addresses (0x0 to 0xF). |
| * |
| * RETURNS: |
| * DEVICE_ID - on success |
| * 0 - on error |
| * |
| * COMMENTS: |
| * None. |
| * |
| *******************************************************************************/ |
| GT_U16 miiSmiIfInit |
| ( |
| IN GT_QD_DEV *dev, |
| OUT GT_BOOL * highSmiDevAddr |
| ) |
| { |
| GT_STATUS status; |
| GT_U16 data, data1; |
| |
| if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR,QD_REG_SWITCH_ID,&data)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+1,QD_REG_SWITCH_ID,&data1)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| switch(data & 0xFF00) |
| { |
| case 0x0200: |
| case 0x0300: |
| case 0x0500: |
| case 0x0600: |
| case 0x1500: |
| case 0xF500: |
| case 0xF900: |
| if (data == data1) |
| { |
| *highSmiDevAddr = GT_FALSE; |
| return data; |
| } |
| break; |
| default: |
| break; |
| } |
| |
| if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0x10,QD_REG_SWITCH_ID,&data)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0x11,QD_REG_SWITCH_ID,&data1)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| switch(data & 0xFF00) |
| { |
| case 0x0200: |
| case 0x0300: |
| case 0x0500: |
| case 0x0600: |
| case 0x1500: |
| case 0xF500: |
| case 0xF900: |
| if (data == data1) |
| { |
| *highSmiDevAddr = GT_TRUE; |
| return data; |
| } |
| break; |
| default: |
| break; |
| } |
| |
| if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR_8PORT,QD_REG_SWITCH_ID,&data)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR_8PORT+1,QD_REG_SWITCH_ID,&data1)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| switch(data & 0xFF00) |
| { |
| case 0x0800: |
| case 0x1A00: |
| case 0x1000: |
| case 0x0900: |
| case 0x0400: |
| case 0x1200: |
| case 0x1400: |
| case 0x1600: |
| case 0x1700: |
| case 0x3200: |
| case 0x3700: |
| if (data == data1) |
| { |
| *highSmiDevAddr = GT_FALSE; |
| return data; |
| } |
| break; |
| default: |
| break; |
| } |
| |
| return 0; |
| } |
| |
| |
| /******************************************************************************* |
| * miiSmiManualIfInit |
| * |
| * DESCRIPTION: |
| * This function returns Device ID from the given base address |
| * |
| * INPUTS: |
| * baseAddr - either 0x0 or 0x10. Indicates whether to use the low device |
| * register address or high device register address. |
| * The device register range is from 0x0 to 0xF or from 0x10 |
| * to 0x1F for 5 port switchs and from 0x0 to 0x1B for 8 port |
| * switchs. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * DEVICE_ID - on success |
| * 0 - on error |
| * |
| * COMMENTS: |
| * None. |
| * |
| *******************************************************************************/ |
| GT_U16 miiSmiManualIfInit |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 baseAddr |
| ) |
| { |
| GT_STATUS status; |
| GT_U16 data; |
| |
| if((status = miiSmiIfReadRegister(dev,(GT_U8)(PORT_REGS_START_ADDR+baseAddr),QD_REG_SWITCH_ID,&data)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| switch(data & 0xFF00) |
| { |
| case 0x0200: |
| case 0x0300: |
| case 0x0500: |
| case 0x0600: |
| case 0x1500: |
| case 0xF500: |
| case 0xF900: |
| return data; |
| default: |
| break; |
| } |
| if(baseAddr != 0) |
| return 0; |
| |
| if((status = miiSmiIfReadRegister(dev,(GT_U8)(PORT_REGS_START_ADDR_8PORT+baseAddr),QD_REG_SWITCH_ID,&data)) != GT_OK) |
| { |
| return 0; |
| } |
| |
| switch(data & 0xFF00) |
| { |
| case 0x0800: |
| case 0x1A00: |
| case 0x1000: |
| case 0x0900: |
| case 0x0400: |
| case 0x1200: |
| case 0x1400: |
| case 0x1600: |
| case 0x3200: |
| case 0x1700: |
| case 0x3700: |
| return data; |
| default: |
| break; |
| } |
| |
| return 0; |
| } |
| |
| |
| /******************************************************************************* |
| * miiSmiIfReadRegister |
| * |
| * DESCRIPTION: |
| * This function reads a register throw the SMI / MII interface, to be used |
| * by upper layers. |
| * |
| * INPUTS: |
| * phyAddr - The PHY address to be read. |
| * regAddr - The register address to read. |
| * |
| * OUTPUTS: |
| * data - The register's data. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * |
| * COMMENTS: |
| * None. |
| * |
| *******************************************************************************/ |
| GT_STATUS miiSmiIfReadRegister |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U8 phyAddr, |
| IN GT_U8 regAddr, |
| OUT GT_U16 *data |
| ) |
| { |
| unsigned int tmpData; |
| |
| if(dev->accessMode == SMI_MULTI_ADDR_MODE) |
| { |
| if(qdMultiAddrRead(dev,(GT_U32)phyAddr,(GT_U32)regAddr,&tmpData) != GT_TRUE) |
| { |
| return GT_FAIL; |
| } |
| } |
| else |
| { |
| if(dev->fgtReadMii(dev,(GT_U32)phyAddr,(GT_U32)regAddr,&tmpData) != GT_TRUE) |
| { |
| return GT_FAIL; |
| } |
| } |
| *data = (GT_U16)tmpData; |
| return GT_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * miiSmiIfWriteRegister |
| * |
| * DESCRIPTION: |
| * This function writes to a register throw the SMI / MII interface, to be |
| * used by upper layers. |
| * |
| * INPUTS: |
| * phyAddr - The PHY address to be read. |
| * regAddr - The register address to read. |
| * data - The data to be written to the register. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * |
| * COMMENTS: |
| * None. |
| * |
| *******************************************************************************/ |
| GT_STATUS miiSmiIfWriteRegister |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U8 phyAddr, |
| IN GT_U8 regAddr, |
| IN GT_U16 data |
| ) |
| { |
| if(dev->accessMode == SMI_MULTI_ADDR_MODE) |
| { |
| if(qdMultiAddrWrite(dev,(GT_U32)phyAddr,(GT_U32)regAddr,(GT_U32)data) != GT_TRUE) |
| { |
| return GT_FAIL; |
| } |
| } |
| else |
| { |
| if(dev->fgtWriteMii(dev,(GT_U32)phyAddr,(GT_U32)regAddr,(GT_U32)data) != GT_TRUE) |
| { |
| return GT_FAIL; |
| } |
| } |
| return GT_OK; |
| } |
| |
| |
| /***************************************************************************** |
| * qdMultiAddrRead |
| * |
| * DESCRIPTION: |
| * This function reads data from a device in the secondary MII bus. |
| * |
| * INPUTS: |
| * phyAddr - The PHY address to be read. |
| * regAddr - The register address to read. |
| * value - The storage where register date to be saved. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_TRUE - on success |
| * GT_FALSE - on error |
| * |
| * COMMENTS: |
| * None. |
| * |
| *******************************************************************************/ |
| GT_BOOL qdMultiAddrRead (GT_QD_DEV* dev, unsigned int phyAddr , unsigned int regAddr, |
| unsigned int* value) |
| { |
| unsigned int smiReg; |
| volatile unsigned int timeOut; /* in 100MS units */ |
| volatile int i; |
| |
| /* first check that it is not busy */ |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| timeOut = QD_SMI_ACCESS_LOOP; /* initialize the loop count */ |
| |
| if(smiReg & QD_SMI_BUSY) |
| { |
| for(i = 0 ; i < QD_SMI_TIMEOUT ; i++); |
| do |
| { |
| if(timeOut-- < 1 ) |
| { |
| return GT_FALSE; |
| } |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| } while (smiReg & QD_SMI_BUSY); |
| } |
| |
| smiReg = QD_SMI_BUSY | (phyAddr << QD_SMI_DEV_ADDR_BIT) | (QD_SMI_READ << QD_SMI_OP_BIT) | |
| (regAddr << QD_SMI_REG_ADDR_BIT) | (QD_SMI_CLAUSE22 << QD_SMI_MODE_BIT); |
| |
| if(dev->fgtWriteMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| timeOut = QD_SMI_ACCESS_LOOP; /* initialize the loop count */ |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| |
| if(smiReg & QD_SMI_BUSY) |
| { |
| for(i = 0 ; i < QD_SMI_TIMEOUT ; i++); |
| do |
| { |
| if(timeOut-- < 1 ) |
| { |
| return GT_FALSE; |
| } |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| } while (smiReg & QD_SMI_BUSY); |
| } |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_DATA, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| *value = smiReg; |
| |
| return GT_TRUE; |
| } |
| |
| /***************************************************************************** |
| * qdMultiAddrWrite |
| * |
| * DESCRIPTION: |
| * This function writes data to the device in the secondary MII bus. |
| * |
| * INPUTS: |
| * phyAddr - The PHY address to be read. |
| * regAddr - The register address to read. |
| * value - The data to be written into the register. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_TRUE - on success |
| * GT_FALSE - on error |
| * |
| * COMMENTS: |
| * None. |
| * |
| *******************************************************************************/ |
| |
| GT_BOOL qdMultiAddrWrite (GT_QD_DEV* dev, unsigned int phyAddr , unsigned int regAddr, |
| unsigned int value) |
| { |
| unsigned int smiReg; |
| volatile unsigned int timeOut; /* in 100MS units */ |
| volatile int i; |
| |
| /* first check that it is not busy */ |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| timeOut = QD_SMI_ACCESS_LOOP; /* initialize the loop count */ |
| |
| if(smiReg & QD_SMI_BUSY) |
| { |
| for(i = 0 ; i < QD_SMI_TIMEOUT ; i++); |
| do |
| { |
| if(timeOut-- < 1 ) |
| { |
| return GT_FALSE; |
| } |
| if(dev->fgtReadMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, &smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| } while (smiReg & QD_SMI_BUSY); |
| } |
| |
| if(dev->fgtWriteMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_DATA, value) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| smiReg = QD_SMI_BUSY | (phyAddr << QD_SMI_DEV_ADDR_BIT) | (QD_SMI_WRITE << QD_SMI_OP_BIT) | |
| (regAddr << QD_SMI_REG_ADDR_BIT) | (QD_SMI_CLAUSE22 << QD_SMI_MODE_BIT); |
| |
| if(dev->fgtWriteMii(dev,(GT_U32)dev->phyAddr,(GT_U32)QD_REG_SMI_COMMAND, smiReg) != GT_TRUE) |
| { |
| return GT_FALSE; |
| } |
| |
| return GT_TRUE; |
| } |
| |