/******************************************************************************* * gprtClearAllCtr * * DESCRIPTION: * This routine clears all port rx/tx counters. * * INPUTS: * None. * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * * * GalTis: * *******************************************************************************/ GT_STATUS gprtClearAllCtr ( IN GT_QD_DEV *dev ) { IN GT_STATUS retVal; /* Functions return value. */ IN GT_U16 mode; /* hold counters current mode */ DBG_INFO(("gprtClearAllCtr Called.\n")); if (IS_IN_DEV_GROUP(dev,DEV_88E6093_FAMILY)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } /* get counter current mode */ if(hwGetGlobalRegField(dev,QD_REG_GLOBAL_CONTROL,8,1,&mode) != GT_OK) { DBG_INFO(("Failed (Get field).\n")); return GT_FAIL; } /* write opposite value to reset counter */ if(hwSetGlobalRegField(dev,QD_REG_GLOBAL_CONTROL,8,1,(GT_U16)(1 - mode)) != GT_OK) { DBG_INFO(("Failed (Get field).\n")); return GT_FAIL; } /* restore counters mode */ retVal = hwSetGlobalRegField(dev,QD_REG_GLOBAL_CONTROL,8,1,mode); DBG_INFO(("OK.\n")); return retVal; }
/******************************************************************************* * gsysGetFreeQSize * * DESCRIPTION: * This routine gets Free Queue Counter. This counter reflects the * current number of unalllocated buffers available for all the ports. * * INPUTS: * None. * * OUTPUTS: * count - Free Queue Counter * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS gsysGetFreeQSize ( IN GT_QD_DEV *dev, OUT GT_U16 *count ) { GT_STATUS retVal; /* Functions return value. */ DBG_INFO(("gsysGetFreeQSize Called.\n")); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_OUT_Q_SIZE)) { DBG_INFO(("Not Supported.\n")); return GT_NOT_SUPPORTED; } /* get the counter */ retVal = hwGetGlobalRegField(dev,QD_REG_TOTAL_FREE_COUNTER,0,9,count); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gstatsGetHistogramMode * * DESCRIPTION: * This routine gets the Histogram Counters Mode. * * INPUTS: * None. * * OUTPUTS: * mode - Histogram Mode (GT_COUNT_RX_ONLY, GT_COUNT_TX_ONLY, * and GT_COUNT_RX_TX) * * RETURNS: * GT_OK - on success * GT_BAD_PARAM - on bad parameter * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * *******************************************************************************/ GT_STATUS gstatsGetHistogramMode ( IN GT_QD_DEV *dev, OUT GT_HISTOGRAM_MODE *mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* The register's read data. */ DBG_INFO(("gstatsGetHistogramMode Called.\n")); /* Only Gigabit Switch supports this status. */ if (!((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_MANAGED_SWITCH)) || (IS_IN_DEV_GROUP(dev,DEV_RMON_REALTIME_SUPPORT)))) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } if(mode == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Get the Histogram mode bit. */ if (IS_IN_DEV_GROUP(dev,DEV_88E6999_FAMILY) || IS_IN_DEV_GROUP(dev,DEV_88E6390_FAMILY)) retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_CONTROL2,6,2,&data); else retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,10,2,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } *mode = data - 1; /* Software definition starts from 0 ~ 2, while hardware supports the values from 1 to 3 */ DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * eventQdSr * * DESCRIPTION: * QuarterDeck interrupt service routine. * * INPUTS: * None. * * OUTPUTS: * None. * * RETURNS: * None. * * COMMENTS: * None. * *******************************************************************************/ GT_BOOL eventQdSr ( IN GT_QD_DEV* dev, OUT GT_U16* intCause ) { GT_STATUS retVal; /* Function calls return value. */ retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,0,4,intCause); if(retVal != GT_OK) return GT_FALSE; return (*intCause)?GT_TRUE:GT_FALSE; }
/******************************************************************************* * eventGetIntStatus * * DESCRIPTION: * This routine reads an hardware driven event status. * * INPUTS: * None. * * OUTPUTS: * intCause - It provides the source of interrupt of the following: * GT_STATS_DONE, GT_VTU_PROB, GT_VTU_DONE, GT_ATU_FULL, * GT_ATU_DONE, GT_PHY_INTERRUPT, GT_EE_INTERRUPT, GT_DEVICE_INT, * and GT_AVB_INTERRUPT * For Gigabit Switch, GT_ATU_FULL is replaced with GT_ATU_PROB and * if there is no internal phy, GT_PHY_INTERRUPT is not supported. * * RETURNS: * GT_OK - read success. * GT_FAIL - otherwise * * COMMENTS: * Each switch device has its own set of event Types. Please refer to the * device datasheet for the list of event types that the device supports. * *******************************************************************************/ GT_STATUS eventGetIntStatus ( IN GT_QD_DEV *dev, OUT GT_U16 *intCause ) { GT_STATUS retVal; /* Function calls return value. */ GT_U8 len; if (IS_IN_DEV_GROUP(dev,DEV_AVB_INTERRUPT)) len = 9; else if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INTERRUPT)) len = 8; else len = 7; retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,0,len,intCause); return retVal; }
/******************************************************************************* * gsysGetPPUState * * DESCRIPTION: * This routine get the PPU State. These two bits return * the current value of the PPU. * * INPUTS: * None. * * OUTPUTS: * mode - GT_PPU_STATE * * RETURNS: * GT_OK - on success * GT_BAD_PARAM - on bad parameter * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS gsysGetPPUState ( IN GT_QD_DEV *dev, OUT GT_PPU_STATE *mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* The register's read data. */ DBG_INFO(("gsysGetPPUState Called.\n")); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) { DBG_INFO(("Not Supported.\n")); return GT_NOT_SUPPORTED; } if(mode == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* get the bits from hardware */ retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,14,2,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } if (IS_IN_DEV_GROUP(dev,DEV_PPU_READ_ONLY)) { data |= 0x4000; } *mode = data; DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gsysGetInitReady * * DESCRIPTION: * This routine get the InitReady bit. This bit is set to a one when the ATU, * the Queue Controller and the Statistics Controller are done with their * initialization and are ready to accept frames. * * INPUTS: * None. * * OUTPUTS: * mode - GT_TRUE: switch is ready, GT_FALSE otherwise. * * RETURNS: * GT_OK - on success * GT_BAD_PARAM - on bad parameter * GT_FAIL - on error * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS gsysGetInitReady ( IN GT_QD_DEV *dev, OUT GT_BOOL *mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* The register's read data. */ DBG_INFO(("gsysGetInitReady Called.\n")); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_QD_PLUS|DEV_ENHANCED_FE_SWITCH)) { DBG_INFO(("Not Supported.\n")); return GT_NOT_SUPPORTED; } if(mode == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* get the bits from hardware */ retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,11,1,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } BIT_2_BOOL(data,*mode); DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * statsCapture * * DESCRIPTION: * This function is used to capture all counters of a port. * * INPUTS: * port - port number * * OUTPUTS: * None. * * RETURNS: * GT_OK on success, * GT_FAIL otherwise. * * COMMENTS: * If Semaphore is used, Semaphore should be acquired before this function call. *******************************************************************************/ static GT_STATUS statsCapture ( IN GT_QD_DEV *dev, IN GT_U8 port ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data, histoData;/* Data to be set into the */ /* register. */ GT_U16 portNum; if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS)) { portNum = (port + 1) << 5; } else { portNum = (GT_U16)port; } /* Get the Histogram mode bit. */ retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData); if(retVal != GT_OK) { return retVal; } histoData &= 0xC00; #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 1; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { return retVal; } } #endif data = (1 << 15) | (GT_STATS_CAPTURE_PORT << 12) | portNum | histoData; retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); if(retVal != GT_OK) { return retVal; } return GT_OK; }
static GT_STATUS statsOperationPerform ( IN GT_QD_DEV *dev, IN GT_STATS_OPERATION statsOp, IN GT_U8 port, IN GT_STATS_COUNTERS counter, OUT GT_VOID *statsData ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data,histoData; /* Data to be set into the */ /* register. */ GT_U32 statsCounter; GT_U32 lastCounter; GT_U16 portNum; gtSemTake(dev,dev->statsRegsSem,OS_WAIT_FOREVER); if (!((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) || (IS_IN_DEV_GROUP(dev,DEV_RMON_REALTIME_SUPPORT)))) { if (IS_IN_DEV_GROUP(dev,DEV_MELODY_SWITCH)) lastCounter = (GT_U32)STATS2_Late; else lastCounter = (GT_U32)STATS_OutDiscards; } else { lastCounter = (GT_U32)STATS2_Late; } if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS)) { portNum = (port + 1) << 5; } else { portNum = (GT_U16)port; } /* Wait until the stats in ready. */ #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 2; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; regAccess.rw_reg_list[1].cmd = HW_REG_READ; regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[1].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[1].data = 0; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } histoData = qdLong2Short(regAccess.rw_reg_list[1].data); } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } } /* Get the Histogram mode bit. */ retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } #endif histoData &= 0xC00; /* Set the STAT Operation register */ switch (statsOp) { case STATS_FLUSH_ALL: data = (1 << 15) | (GT_STATS_FLUSH_ALL << 12) | histoData; retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); gtSemGive(dev,dev->statsRegsSem); return retVal; case STATS_FLUSH_PORT: data = (1 << 15) | (GT_STATS_FLUSH_PORT << 12) | portNum | histoData; retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); gtSemGive(dev,dev->statsRegsSem); return retVal; case STATS_READ_COUNTER: retVal = statsCapture(dev,port); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } retVal = statsReadCounter(dev,counter,(GT_U32*)statsData); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } break; case STATS_READ_REALTIME_COUNTER: retVal = statsReadRealtimeCounter(dev,port,counter,(GT_U32*)statsData); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } break; case STATS_READ_ALL: retVal = statsCapture(dev,port); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } for(statsCounter=0; statsCounter<=lastCounter; statsCounter++) { retVal = statsReadCounter(dev,statsCounter,((GT_U32*)statsData + statsCounter)); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } } break; default: gtSemGive(dev,dev->statsRegsSem); return GT_FAIL; } gtSemGive(dev,dev->statsRegsSem); return GT_OK; }
/******************************************************************************* * statsReadRealtimeCounter * * DESCRIPTION: * This function is used to read a realtime counter. * * INPUTS: * port - port to be accessed * counter - counter to be read if it's read operation * * OUTPUTS: * statsData - points to the data storage where the MIB counter will be saved. * * RETURNS: * GT_OK on success, * GT_FAIL otherwise. * * COMMENTS: * If Semaphore is used, Semaphore should be acquired before this function call. *******************************************************************************/ static GT_STATUS statsReadRealtimeCounter ( IN GT_QD_DEV *dev, IN GT_U8 port, IN GT_U32 counter, OUT GT_U32 *statsData ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data, histoData;/* Data to be set into the register. */ GT_U16 counter3_2; /* Counter Register Bytes 3 & 2 */ GT_U16 counter1_0; /* Counter Register Bytes 1 & 0 */ /* Get the Histogram mode bit. */ retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData); if(retVal != GT_OK) { return retVal; } histoData &= 0xC00; #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 1; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { return retVal; } } #endif data = (GT_U16)((1 << 15) | (GT_STATS_READ_COUNTER << 12) | ((port+1) << 5) | counter | histoData); retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); if(retVal != GT_OK) { return retVal; } #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 1; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { return retVal; } } #endif retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER3_2,&counter3_2); if(retVal != GT_OK) { return retVal; } retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER1_0,&counter1_0); if(retVal != GT_OK) { return retVal; } *statsData = (counter3_2 << 16) | counter1_0; return GT_OK; }
static GT_STATUS stuOperationPerform ( IN GT_QD_DEV *dev, IN GT_STU_OPERATION stuOp, INOUT GT_U8 *valid, INOUT GT_STU_ENTRY *entry ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* Data to be set into the */ /* register. */ gtSemTake(dev,dev->vtuRegsSem,OS_WAIT_FOREVER); /* Wait until the VTU in ready. */ data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } } /* Set the VTU data register if Load operation is required. */ if (stuOp == LOAD_PURGE_STU_ENTRY) { if (*valid == 1) { /* set the Port State for all the ports */ retVal = stuSetSTUData(dev,entry); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } /* Set the valid bit (QD_REG_VTU_VID_REG) */ data= *valid << 12 ; retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_VTU_VID_REG),data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } } else { /* Clear the valid bit (QD_REG_VTU_VID_REG) */ data= 0 ; retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_VTU_VID_REG),data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } } } /* Set the SID register (QD_REG_STU_SID_REG) */ data= (entry->sid) & 0x3F; retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_STU_SID_REG),data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } /* Start the STU Operation by defining the stuOp and VTUBusy */ data = (1 << 15) | (stuOp << 12); retVal = hwWriteGlobalReg(dev,QD_REG_VTU_OPERATION,data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } /* If the operation is a get next operation wait for the response */ if(stuOp == GET_NEXT_STU_ENTRY) { /* Wait until the STU in ready. */ data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } } /****************** get the valid bit *******************/ retVal = hwGetGlobalRegField(dev,QD_REG_VTU_VID_REG,12,1,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } *valid = (GT_U8)data; /****************** get the sid *******************/ retVal = hwReadGlobalReg(dev,QD_REG_STU_SID_REG,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } /* the sid is bits 0-5 */ entry->sid = data & 0x3F; if (*valid) { /* get the Port State for all the ports */ retVal = stuGetSTUData(dev,entry); if(retVal != GT_OK) { gtSemGive(dev,dev->vtuRegsSem); return retVal; } } /* entry is valid */ } /* end of get next entry */ gtSemGive(dev,dev->vtuRegsSem); return GT_OK; }