예제 #1
0
파일: gtPortStat.c 프로젝트: Undrizzle/apps
/*******************************************************************************
* 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;
}
예제 #2
0
/*******************************************************************************
* 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;
}
예제 #3
0
/*******************************************************************************
* 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;
}
예제 #4
0
/*******************************************************************************
* 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;
}
예제 #5
0
/*******************************************************************************
* 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;
}
예제 #6
0
/*******************************************************************************
* 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;
}
예제 #7
0
/*******************************************************************************
* 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;
}
예제 #8
0
/*******************************************************************************
* 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, &regAccess);
      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;

}
예제 #9
0
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, &regAccess);
      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;
}
예제 #10
0
/*******************************************************************************
* 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, &regAccess);
      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, &regAccess);
      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;

}
예제 #11
0
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;
}