| #include <Copyright.h> |
| |
| /******************************************************************************* |
| * gtPIRL.c |
| * |
| * DESCRIPTION: |
| * API definitions for PIRL Resources |
| * |
| * DEPENDENCIES: |
| * |
| * FILE REVISION NUMBER: |
| *******************************************************************************/ |
| |
| #include <msApi.h> |
| #include <gtSem.h> |
| #include <gtHwCntl.h> |
| #include <gtDrvSwRegs.h> |
| |
| /****************************************************************************/ |
| /* STATS operation function declaration. */ |
| /****************************************************************************/ |
| static GT_STATUS pirlOperationPerform |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_PIRL_OPERATION pirlOp, |
| INOUT GT_PIRL_OP_DATA *opData |
| ); |
| |
| static GT_STATUS pirlInitialize |
| ( |
| IN GT_QD_DEV *dev |
| ); |
| |
| static GT_STATUS pirlInitIRLUnit |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit |
| ); |
| |
| static GT_STATUS pirlDataToResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_PIRL_DATA *pirlData, |
| OUT GT_PIRL_RESOURCE *res |
| ); |
| |
| static GT_STATUS pirlResourceToData |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_PIRL_RESOURCE *res, |
| OUT GT_PIRL_DATA *pirlData |
| ); |
| |
| static GT_STATUS pirlWriteResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_PIRL_RESOURCE *res |
| ); |
| |
| static GT_STATUS pirlReadResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| OUT GT_PIRL_RESOURCE *res |
| ); |
| |
| static GT_STATUS pirlSetPortVec |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_U32 portVec |
| ); |
| |
| static GT_STATUS pirlGetPortVec |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| OUT GT_U32 *portVec |
| ); |
| |
| static GT_STATUS pirlSetFcMode |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_LPORT port, |
| IN GT_PIRL_FC_DEASSERT mode |
| ); |
| |
| /******************************************************************************* |
| * gpirlActivate |
| * |
| * DESCRIPTION: |
| * This routine activates Ingress Rate Limiting for the given ports by |
| * initializing a resource bucket, assigning ports, and configuring |
| * Bucket Parameters. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used (0 ~ 11). |
| * portVec - the list of ports that share the bucket. |
| * pirlData - PIRL resource parameters. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlActivate |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_U32 portVec, |
| IN GT_PIRL_DATA *pirlData |
| ) |
| { |
| GT_STATUS retVal; |
| GT_PORT_STP_STATE pState[MAX_SWITCH_PORTS]; |
| GT_LPORT port; |
| GT_PIRL_OPERATION op; |
| GT_PIRL_OP_DATA opData; |
| GT_PIRL_RESOURCE pirlRes; |
| |
| DBG_INFO(("gpirlActivate Called.\n")); |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* check if the given bucket number is valid */ |
| if (!GT_IS_IRLUNIT_VALID(dev,irlUnit)) |
| { |
| DBG_INFO(("GT_BAD_PARAM irlUnit\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* check if the given portVec is valid */ |
| if ((!portVec) || (portVec >= (GT_U32)(1<<dev->numOfPorts))) |
| { |
| DBG_INFO(("GT_BAD_PARAM portVec\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* set or reset port's ingress resource bit based on the portVec */ |
| retVal = pirlSetPortVec(dev, irlUnit, portVec); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| /* Disable ports that share the bucket */ |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = gstpGetPortState(dev, port, &pState[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| retVal = gstpSetPortState(dev, port, GT_PORT_DISABLE); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| } |
| |
| /* Program Tuning register */ |
| op = PIRL_WRITE_RESOURCE; |
| opData.irlUnit = irlUnit; |
| opData.irlReg = 0xF; |
| opData.irlData = 0x7; |
| retVal = pirlOperationPerform(dev,op,&opData); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n")); |
| return retVal; |
| } |
| |
| /* Program the Ingress Rate Resource Parameters */ |
| retVal = pirlDataToResource(dev,pirlData,&pirlRes); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Data to PIRL Resource conversion failed.\n")); |
| return retVal; |
| } |
| |
| retVal = pirlWriteResource(dev,irlUnit,&pirlRes); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Write Resource failed.\n")); |
| return retVal; |
| } |
| |
| /* Initialize internal counters */ |
| retVal = pirlInitIRLUnit(dev,irlUnit); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Write Resource failed.\n")); |
| return retVal; |
| } |
| |
| /* Program PirlFCMode for each port that shares Bucket */ |
| if (pirlRes.ebsLimitAction == ESB_LIMIT_ACTION_FC) |
| { |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = pirlSetFcMode(dev,port,pirlData->fcDeassertMode[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL FC Mode set failed.\n")); |
| return retVal; |
| } |
| } |
| } |
| |
| /* Set the ports in their original state */ |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = gstpSetPortState(dev, port, pState[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| } |
| |
| DBG_INFO(("OK.\n")); |
| return GT_OK; |
| |
| } |
| |
| |
| /******************************************************************************* |
| * gpirlDeactivate |
| * |
| * DESCRIPTION: |
| * This routine deactivates Ingress Rate Limiting for the given bucket. |
| * It simply removes every ports from the Ingress Rate Resource. |
| * It is assumed that gpirlActivate has been successfully called with |
| * the irlUnit before this function is called. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used (0 ~ 11). |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlDeactivate |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit |
| ) |
| { |
| GT_STATUS retVal; |
| |
| DBG_INFO(("gpirlDectivate Called.\n")); |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* check if the given bucket number is valid */ |
| if (!GT_IS_IRLUNIT_VALID(dev,irlUnit)) |
| { |
| DBG_INFO(("GT_BAD_PARAM\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* reset port's ingress resource bit */ |
| retVal = pirlSetPortVec(dev, irlUnit, 0); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| DBG_INFO(("OK.\n")); |
| return GT_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * gpirlUpdateParam |
| * |
| * DESCRIPTION: |
| * This routine updates IRL Parameter. |
| * It is assumed that gpirlActivate has been successfully called with |
| * the given irlUnit before this function is called. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used (0 ~ 11). |
| * pirlData - PIRL resource parameters. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlUpdateParam |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_PIRL_DATA *pirlData |
| ) |
| { |
| GT_STATUS retVal; |
| GT_PORT_STP_STATE pState[MAX_SWITCH_PORTS]; |
| GT_LPORT port; |
| GT_PIRL_RESOURCE pirlRes; |
| GT_U32 portVec; |
| |
| DBG_INFO(("gpirlUpdateParam Called.\n")); |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* check if the given bucket number is valid */ |
| if (!GT_IS_IRLUNIT_VALID(dev,irlUnit)) |
| { |
| DBG_INFO(("GT_BAD_PARAM\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* get port list that share ingress resource */ |
| retVal = pirlGetPortVec(dev, irlUnit, &portVec); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| /* check if the given portVec is valid */ |
| if (!portVec) |
| { |
| DBG_INFO(("IRL Unit not Activated\n")); |
| return GT_FAIL; |
| } |
| |
| /* Disable ports that share the bucket */ |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = gstpGetPortState(dev, port, &pState[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| retVal = gstpSetPortState(dev, port, GT_PORT_DISABLE); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| } |
| |
| /* Program the Ingress Rate Resource Parameters */ |
| retVal = pirlDataToResource(dev,pirlData,&pirlRes); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Data to PIRL Resource conversion failed.\n")); |
| return retVal; |
| } |
| |
| retVal = pirlWriteResource(dev,irlUnit,&pirlRes); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Write Resource failed.\n")); |
| return retVal; |
| } |
| |
| /* Initialize internal counrters for the bucket */ |
| retVal = pirlInitIRLUnit(dev,irlUnit); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Write Resource failed.\n")); |
| return retVal; |
| } |
| |
| /* Program PirlFCMode for each port that shares Bucket */ |
| if (pirlRes.ebsLimitAction == ESB_LIMIT_ACTION_FC) |
| { |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = pirlSetFcMode(dev,port,pirlData->fcDeassertMode[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL FC Mode set failed.\n")); |
| return retVal; |
| } |
| } |
| } |
| |
| /* Set the ports in their original state */ |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = gstpSetPortState(dev, port, pState[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| } |
| |
| DBG_INFO(("OK.\n")); |
| return GT_OK; |
| |
| } |
| |
| |
| /******************************************************************************* |
| * gpirlReadParam |
| * |
| * DESCRIPTION: |
| * This routine retrieves IRL Parameter. |
| * It is assumed that gpirlActivate has been successfully called with |
| * the given irlUnit before this function is called. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used (0 ~ 11). |
| * |
| * OUTPUTS: |
| * pirlData - PIRL resource parameters. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlReadParam |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| OUT GT_PIRL_DATA *pirlData |
| ) |
| { |
| GT_STATUS retVal; |
| GT_LPORT port; |
| GT_PIRL_RESOURCE pirlRes; |
| GT_U32 portVec; |
| |
| DBG_INFO(("gpirlReadParam Called.\n")); |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* check if the given bucket number is valid */ |
| if (!GT_IS_IRLUNIT_VALID(dev,irlUnit)) |
| { |
| DBG_INFO(("GT_BAD_PARAM\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* get port list that share ingress resource */ |
| retVal = pirlGetPortVec(dev, irlUnit, &portVec); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| /* check if the given portVec is valid */ |
| if (!portVec) |
| { |
| DBG_INFO(("IRL Unit not Activated\n")); |
| return GT_FAIL; |
| } |
| |
| /* Read the Ingress Rate Resource Parameters */ |
| retVal = pirlReadResource(dev,irlUnit,&pirlRes); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Read Resource failed.\n")); |
| return retVal; |
| } |
| |
| retVal = pirlResourceToData(dev,&pirlRes,pirlData); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL Resource to PIRL Data conversion failed.\n")); |
| return retVal; |
| } |
| |
| /* Program PirlFCMode for each port that shares Bucket */ |
| if (pirlRes.ebsLimitAction == ESB_LIMIT_ACTION_FC) |
| { |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(!GT_IS_PORT_SET(portVec,port)) |
| continue; |
| |
| retVal = grcGetPirlFcMode(dev,port,&pirlData->fcDeassertMode[port]); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL FC Mode get failed.\n")); |
| return retVal; |
| } |
| } |
| } |
| |
| DBG_INFO(("OK.\n")); |
| return GT_OK; |
| |
| } |
| |
| |
| |
| /******************************************************************************* |
| * gpirlUpdatePortVec |
| * |
| * DESCRIPTION: |
| * This routine updates port list that share the bucket. |
| * It is assumed that gpirlActivate has been successfully called with |
| * the given irlUnit before this function is called. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used (0 ~ 11). |
| * portVec - the list of ports that share the bucket. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlUpdatePortVec |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_U32 portVec |
| ) |
| { |
| GT_STATUS retVal; |
| GT_U32 tmpVec; |
| |
| DBG_INFO(("gpirlActivate Called.\n")); |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* check if the given bucket number is valid */ |
| if (!GT_IS_IRLUNIT_VALID(dev,irlUnit)) |
| { |
| DBG_INFO(("GT_BAD_PARAM\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* check if the given portVec is valid */ |
| if ((!portVec) || (portVec > (GT_U32)(1<<dev->numOfPorts))) |
| { |
| DBG_INFO(("GT_BAD_PARAM\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* get port list that share ingress resource */ |
| retVal = pirlGetPortVec(dev, irlUnit, &tmpVec); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| /* check if the given portVec is valid */ |
| if (!tmpVec) |
| { |
| DBG_INFO(("IRL Unit not Activated\n")); |
| return GT_FAIL; |
| } |
| |
| /* set or reset port's ingress resource bit based on the portVec */ |
| retVal = pirlSetPortVec(dev, irlUnit, portVec); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| DBG_INFO(("OK.\n")); |
| return GT_OK; |
| |
| } |
| |
| |
| /******************************************************************************* |
| * gpirlReadPortVec |
| * |
| * DESCRIPTION: |
| * This routine retrieves port list that share the bucket. |
| * It is assumed that gpirlActivate has been successfully called with |
| * the given irlUnit before this function is called. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used (0 ~ 11). |
| * |
| * OUTPUTS: |
| * portVec - the list of ports that share the bucket. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlReadPortVec |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| OUT GT_U32 *portVec |
| ) |
| { |
| GT_STATUS retVal; |
| |
| DBG_INFO(("gpirlReadPortVec Called.\n")); |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* check if the given bucket number is valid */ |
| if (!GT_IS_IRLUNIT_VALID(dev,irlUnit)) |
| { |
| DBG_INFO(("GT_BAD_PARAM\n")); |
| return GT_BAD_PARAM; |
| } |
| |
| /* get port list that share ingress resource */ |
| retVal = pirlGetPortVec(dev, irlUnit, portVec); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Getting Port State failed\n")); |
| return retVal; |
| } |
| |
| /* check if the given portVec is valid */ |
| if (!*portVec) |
| { |
| DBG_INFO(("IRL Unit not Activated\n")); |
| return GT_FAIL; |
| } |
| |
| DBG_INFO(("OK.\n")); |
| return GT_OK; |
| |
| } |
| |
| |
| |
| /******************************************************************************* |
| * grcGetPirlFcMode |
| * |
| * DESCRIPTION: |
| * This routine gets Port Ingress Rate Limit Flow Control mode. |
| * When EBSLimitAction is programmed to generate a flow control message, |
| * the deassertion of flow control is controlled by this mode. |
| * GT_PIRL_FC_DEASSERT_EMPTY: |
| * De-assert when the ingress rate resource has become empty |
| * GT_PIRL_FC_DEASSERT_CBS_LIMIT |
| * De-assert when the ingress rate resource has enough room as |
| * specified by the CBSLimit. |
| * Please refer to GT_PIRL_RESOURCE structure for EBSLimitAction and |
| * CBSLimit. |
| * |
| * INPUTS: |
| * port - logical port number |
| * |
| * OUTPUTS: |
| * mode - GT_PIRL_FC_DEASSERT enum type |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| GT_STATUS grcGetPirlFcMode |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_LPORT port, |
| OUT GT_PIRL_FC_DEASSERT *mode |
| ) |
| { |
| GT_U16 data; |
| GT_STATUS retVal; /* Functions return value. */ |
| GT_U8 hwPort; /* Physical port. */ |
| |
| DBG_INFO(("grcSetDaNrlEn Called.\n")); |
| |
| hwPort = GT_LPORT_2_PORT(port); |
| |
| /* check if the given Switch supports this feature. */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* Get the PirlFcMode. */ |
| retVal = hwGetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,12,1,&data); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| |
| *mode = (GT_PIRL_FC_DEASSERT)data; |
| DBG_INFO(("OK.\n")); |
| |
| return GT_OK; |
| } |
| |
| /******************************************************************************* |
| * gpirlGetIngressRateResource |
| * |
| * DESCRIPTION: |
| * This routine gets Ingress Rate Limiting Resources assigned to the port. |
| * This vector is used to attach specific counter resources to the physical |
| * port. And the same counter resource can be attached to more than one port. |
| * |
| * INPUTS: |
| * port - logical port number |
| * |
| * OUTPUTS: |
| * resVec - resource vector (bit 11:0, since there is 12 resources) |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlGetIngressRateResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_LPORT port, |
| OUT GT_U32 *resVec |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value. */ |
| GT_U8 hwPort; /* Physical port. */ |
| GT_U16 data; |
| |
| DBG_INFO(("grcGetIngressRateResource Called.\n")); |
| |
| hwPort = GT_LPORT_2_PORT(port); |
| |
| /* check if the given Switch supports this feature. */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| /* Get the resource vector. */ |
| retVal = hwGetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,0,12,&data); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| |
| *resVec = (GT_U32)data; |
| |
| DBG_INFO(("OK.\n")); |
| |
| return GT_OK; |
| } |
| |
| /******************************************************************************* |
| * gpirlSetCurTimeUpInt |
| * |
| * DESCRIPTION: |
| * This function sets the current time update interval. |
| * Please contact FAE for detailed information. |
| * |
| * INPUTS: |
| * upInt - updata interval (0 ~ 7) |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_BAD_PARAM - if invalid parameter is given |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlSetCurTimeUpInt |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 upInt |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_PIRL_OPERATION op; |
| GT_PIRL_OP_DATA opData; |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| if (upInt > 0x7) |
| return GT_BAD_PARAM; |
| |
| op = PIRL_READ_RESOURCE; |
| |
| opData.irlUnit = 0xF; |
| opData.irlReg = 1; |
| opData.irlData = 0; |
| |
| retVal = pirlOperationPerform(dev, op, &opData); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| |
| op = PIRL_WRITE_RESOURCE; |
| opData.irlData = (opData.irlData & 0xFFF8) | (GT_U16)upInt; |
| |
| retVal = pirlOperationPerform(dev, op, &opData); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| |
| return GT_OK; |
| } |
| |
| /****************************************************************************/ |
| /* Internal functions. */ |
| /****************************************************************************/ |
| |
| /******************************************************************************* |
| * gpirlInitialize |
| * |
| * DESCRIPTION: |
| * This routine initializes PIRL Resources. |
| * |
| * INPUTS: |
| * None |
| * |
| * OUTPUTS: |
| * None |
| * |
| * RETURNS: |
| * None |
| * |
| * COMMENTS: |
| * None |
| * |
| *******************************************************************************/ |
| GT_STATUS gpirlInitialize |
| ( |
| IN GT_QD_DEV *dev |
| ) |
| { |
| GT_STATUS retVal; |
| GT_LPORT port; |
| GT_U8 hwPort; /* Physical port. */ |
| |
| /* reset port's ingress resource bit */ |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| hwPort = GT_LPORT_2_PORT(port); |
| |
| /* Set the resource vector. */ |
| retVal = hwSetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,0,12,0); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| } |
| |
| retVal = pirlInitialize(dev); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| |
| return GT_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * statsOperationPerform |
| * |
| * DESCRIPTION: |
| * This function accesses Ingress Rate Command Register and Data Register. |
| * |
| * INPUTS: |
| * pirlOp - The stats operation bits to be written into the stats |
| * operation register. |
| * port - port number |
| * counter - counter to be read if it's read operation |
| * |
| * OUTPUTS: |
| * pirlData - points to the data storage where the MIB counter will be saved. |
| * |
| * RETURNS: |
| * GT_OK on success, |
| * GT_FAIL otherwise. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| static GT_STATUS pirlOperationPerform |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_PIRL_OPERATION pirlOp, |
| INOUT GT_PIRL_OP_DATA *opData |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_U16 data; /* temporary Data storage */ |
| |
| gtSemTake(dev,dev->pirlRegsSem,OS_WAIT_FOREVER); |
| |
| /* Wait until the pirl in ready. */ |
| data = 1; |
| while(data == 1) |
| { |
| retVal = hwGetGlobal2RegField(dev,QD_REG_INGRESS_RATE_COMMAND,15,1,&data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| } |
| |
| /* Set the PIRL Operation register */ |
| switch (pirlOp) |
| { |
| case PIRL_INIT_ALL_RESOURCE: |
| data = (1 << 15) | (PIRL_INIT_ALL_RESOURCE << 12); |
| retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| break; |
| case PIRL_INIT_RESOURCE: |
| data = (GT_U16)((1 << 15) | (PIRL_INIT_RESOURCE << 12) | |
| ((opData->irlUnit&0xF)<< 4)); |
| retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| break; |
| |
| case PIRL_WRITE_RESOURCE: |
| data = (GT_U16)opData->irlData; |
| retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_DATA,data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| |
| data = (GT_U16)((1 << 15) | (PIRL_WRITE_RESOURCE << 12) | |
| ((opData->irlUnit&0xF) << 4) | (opData->irlReg & 0xF)); |
| retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| break; |
| |
| case PIRL_READ_RESOURCE: |
| data = (GT_U16)((1 << 15) | (PIRL_READ_RESOURCE << 12) | |
| ((opData->irlUnit&0xF) << 4) | (opData->irlReg & 0xF)); |
| retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| |
| data = 1; |
| while(data == 1) |
| { |
| retVal = hwGetGlobal2RegField(dev,QD_REG_INGRESS_RATE_COMMAND,15,1,&data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| } |
| |
| retVal = hwReadGlobal2Reg(dev,QD_REG_INGRESS_RATE_DATA,&data); |
| opData->irlData = (GT_U32)data; |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| |
| default: |
| |
| gtSemGive(dev,dev->pirlRegsSem); |
| return GT_FAIL; |
| } |
| |
| /* Wait until the pirl in ready. */ |
| data = 1; |
| while(data == 1) |
| { |
| retVal = hwGetGlobal2RegField(dev,QD_REG_INGRESS_RATE_COMMAND,15,1,&data); |
| if(retVal != GT_OK) |
| { |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| } |
| |
| gtSemGive(dev,dev->pirlRegsSem); |
| return retVal; |
| } |
| |
| /* |
| * Initialize all PIRL resources to the inital state. |
| */ |
| static GT_STATUS pirlInitialize |
| ( |
| IN GT_QD_DEV *dev |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_PIRL_OPERATION op; |
| |
| op = PIRL_INIT_ALL_RESOURCE; |
| |
| retVal = pirlOperationPerform(dev, op, NULL); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| |
| retVal = gpirlSetCurTimeUpInt(dev,7); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| } |
| |
| return retVal; |
| } |
| |
| /* |
| * Initialize the selected PIRL resource to the inital state. |
| * This function initializes only the BSM structure for the IRL Unit. |
| */ |
| static GT_STATUS pirlInitIRLUnit |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_PIRL_OPERATION op; |
| GT_PIRL_OP_DATA opData; |
| |
| op = PIRL_INIT_RESOURCE; |
| opData.irlUnit = irlUnit; |
| |
| retVal = pirlOperationPerform(dev, op, &opData); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| |
| return retVal; |
| } |
| |
| /* |
| * convert PIRL Data structure to PIRL Resource structure. |
| * if PIRL Data is not valid, return GT_BAD_PARARM; |
| */ |
| static GT_STATUS pirlDataToResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_PIRL_DATA *pirlData, |
| OUT GT_PIRL_RESOURCE *res |
| ) |
| { |
| GT_U16 typeMask; |
| |
| switch(pirlData->accountQConf) |
| { |
| case GT_FALSE: |
| case GT_TRUE: |
| res->accountQConf = pirlData->accountQConf; |
| break; |
| default: |
| return GT_BAD_PARAM; |
| } |
| |
| switch(pirlData->accountFiltered) |
| { |
| case GT_FALSE: |
| case GT_TRUE: |
| res->accountFiltered = pirlData->accountFiltered; |
| break; |
| default: |
| return GT_BAD_PARAM; |
| } |
| |
| switch(pirlData->ebsLimitAction) |
| { |
| case ESB_LIMIT_ACTION_DROP: |
| case ESB_LIMIT_ACTION_FC: |
| res->ebsLimitAction = pirlData->ebsLimitAction; |
| break; |
| default: |
| return GT_BAD_PARAM; |
| } |
| |
| if(pirlData->customSetup.isValid == GT_TRUE) |
| { |
| res->ebsLimit = pirlData->customSetup.ebsLimit; |
| res->cbsLimit = pirlData->customSetup.cbsLimit; |
| res->bktIncrement = pirlData->customSetup.bktIncrement; |
| res->bktRateFactor = pirlData->customSetup.bktRateFactor; |
| } |
| else |
| { |
| if(pirlData->ingressRate == 0) |
| return GT_BAD_PARAM; |
| |
| if(pirlData->ingressRate < 1000) /* less than 1Mbps */ |
| { |
| /* it should be divided by 64 */ |
| if(pirlData->ingressRate % 64) |
| return GT_BAD_PARAM; |
| res->bktRateFactor = pirlData->ingressRate/64; |
| } |
| else if(pirlData->ingressRate <= 100000) /* less than or equal to 100Mbps */ |
| { |
| /* it should be divided by 1000 */ |
| if(pirlData->ingressRate % 1000) |
| return GT_BAD_PARAM; |
| res->bktRateFactor = pirlData->ingressRate/64 + ((pirlData->ingressRate % 64)?1:0); |
| } |
| else if(pirlData->ingressRate <= 200000) /* less than or equal to 200Mbps */ |
| { |
| /* it should be divided by 10000 */ |
| if(pirlData->ingressRate % 10000) |
| return GT_BAD_PARAM; |
| res->bktRateFactor = pirlData->ingressRate/64 + ((pirlData->ingressRate % 64)?1:0); |
| } |
| else |
| return GT_BAD_PARAM; |
| |
| res->ebsLimit = RECOMMENDED_ESB_LIMIT(dev, pirlData->ingressRate); |
| res->cbsLimit = RECOMMENDED_CBS_LIMIT(dev, pirlData->ingressRate); |
| res->bktIncrement = RECOMMENDED_BUCKET_INCREMENT(dev, pirlData->ingressRate); |
| } |
| |
| switch(pirlData->bktRateType) |
| { |
| case BUCKET_TYPE_TRAFFIC_BASED: |
| res->bktRateType = pirlData->bktRateType; |
| |
| if (IS_IN_DEV_GROUP(dev,DEV_RESTRICTED_PIRL_RESOURCE)) |
| { |
| typeMask = 0xF; |
| } |
| else |
| { |
| typeMask = 0x7F; |
| } |
| |
| if (pirlData->bktTypeMask > typeMask) |
| { |
| return GT_BAD_PARAM; |
| } |
| else |
| { |
| res->bktTypeMask = pirlData->bktTypeMask; |
| } |
| |
| break; |
| |
| case BUCKET_TYPE_RATE_BASED: |
| if (IS_IN_DEV_GROUP(dev,DEV_RESTRICTED_PIRL_RESOURCE)) |
| return GT_BAD_PARAM; |
| res->bktRateType = pirlData->bktRateType; |
| res->bktTypeMask = 0; |
| break; |
| |
| default: |
| return GT_BAD_PARAM; |
| } |
| |
| switch(pirlData->byteTobeCounted) |
| { |
| case GT_PIRL_COUNT_ALL_LAYER1: |
| res->byteTobeCounted = 1; |
| break; |
| case GT_PIRL_COUNT_ALL_LAYER2: |
| res->byteTobeCounted = 2; |
| break; |
| case GT_PIRL_COUNT_ALL_LAYER3: |
| res->byteTobeCounted = 6; |
| break; |
| default: |
| return GT_BAD_PARAM; |
| } |
| |
| return GT_OK; |
| } |
| |
| /* |
| * convert PIRL Resource structure to PIRL Data structure. |
| */ |
| static GT_STATUS pirlResourceToData |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_PIRL_RESOURCE *res, |
| OUT GT_PIRL_DATA *pirlData |
| ) |
| { |
| GT_U32 rate; |
| GT_U32 factor; |
| |
| pirlData->accountQConf = res->accountQConf; |
| pirlData->accountFiltered = res->accountFiltered; |
| pirlData->ebsLimitAction = res->ebsLimitAction; |
| |
| pirlData->customSetup.isValid = GT_FALSE; |
| |
| FACTOR_FROM_BUCKET_INCREMENT(dev,res->bktIncrement,factor); |
| |
| rate = res->bktRateFactor * factor; |
| if(rate == 0) |
| { |
| pirlData->ingressRate = 0; |
| pirlData->customSetup.isValid = GT_TRUE; |
| pirlData->customSetup.ebsLimit = res->ebsLimit; |
| pirlData->customSetup.cbsLimit = res->cbsLimit; |
| pirlData->customSetup.bktIncrement = res->bktIncrement; |
| pirlData->customSetup.bktRateFactor = res->bktRateFactor; |
| } |
| else if(rate < 1000) |
| { |
| pirlData->ingressRate = rate; |
| } |
| else if(rate < 100000) |
| { |
| pirlData->ingressRate = rate - (rate % 1000); |
| } |
| else |
| { |
| pirlData->ingressRate = rate - (rate % 10000); |
| } |
| |
| pirlData->bktRateType = res->bktRateType; |
| pirlData->bktTypeMask = res->bktTypeMask; |
| |
| switch(res->byteTobeCounted) |
| { |
| case 1: |
| pirlData->byteTobeCounted = GT_PIRL_COUNT_ALL_LAYER1; |
| break; |
| case 2: |
| pirlData->byteTobeCounted = GT_PIRL_COUNT_ALL_LAYER2; |
| break; |
| case 6: |
| pirlData->byteTobeCounted = GT_PIRL_COUNT_ALL_LAYER3; |
| break; |
| default: |
| return GT_BAD_PARAM; |
| } |
| |
| return GT_OK; |
| } |
| |
| /******************************************************************************* |
| * pirlWriteResource |
| * |
| * DESCRIPTION: |
| * This function writes IRL Resource to BCM (Bucket Configuration Memory) |
| * |
| * INPUTS: |
| * irlUnit - resource unit to be accessed |
| * res - IRL Resource data |
| * |
| * OUTPUTS: |
| * Nont. |
| * |
| * RETURNS: |
| * GT_OK on success, |
| * GT_FAIL otherwise. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| static GT_STATUS pirlWriteResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_PIRL_RESOURCE *res |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_U16 data[8]; /* temporary Data storage */ |
| GT_PIRL_OPERATION op; |
| GT_PIRL_OP_DATA opData; |
| int i; |
| |
| op = PIRL_WRITE_RESOURCE; |
| |
| /* reg0 data */ |
| data[0] = (GT_U16)((res->bktRateType << 15) | /* Bit[15] : Bucket Rate Type */ |
| (res->bktTypeMask << 4 ) | /* Bit[14:4] : Traffic Type */ |
| res->byteTobeCounted ); /* Bit[3:0] : Bytes to be counted */ |
| |
| /* reg1 data */ |
| data[1] = (GT_U16)res->bktIncrement; /* Bit[11:0] : Bucket Increment */ |
| |
| /* reg2 data */ |
| data[2] = (GT_U16)res->bktRateFactor; /* Bit[15:0] : Bucket Rate Factor */ |
| |
| /* reg3 data */ |
| data[3] = (GT_U16)(res->cbsLimit & 0xFFF) << 4; /* Bit[15:4] : CBS Limit[11:0] */ |
| |
| /* reg4 data */ |
| data[4] = (GT_U16)(res->cbsLimit >> 12); /* Bit[11:0] : CBS Limit[23:12] */ |
| |
| /* reg5 data */ |
| data[5] = (GT_U16)(res->ebsLimit & 0xFFFF); /* Bit[15:0] : EBS Limit[15:0] */ |
| |
| /* reg6 data */ |
| data[6] = (GT_U16)((res->ebsLimit >> 16) | /* Bit[7:0] : EBS Limit[23:16] */ |
| (res->ebsLimitAction << 12) | /* Bit[12] : EBS Limit Action */ |
| (res->accountFiltered << 14)| /* Bit[14] : Account Filtered */ |
| (res->accountQConf << 15)); /* Bit[15] : Account QConf */ |
| /* reg7 data */ |
| data[7] = 0; /* Reserved */ |
| |
| for(i=0; i<8; i++) |
| { |
| opData.irlUnit = irlUnit; |
| opData.irlReg = i; |
| opData.irlData = data[i]; |
| |
| retVal = pirlOperationPerform(dev, op, &opData); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| } |
| |
| return GT_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * pirlReadResource |
| * |
| * DESCRIPTION: |
| * This function reads IRL Resource from BCM (Bucket Configuration Memory) |
| * |
| * INPUTS: |
| * irlUnit - resource unit to be accessed |
| * |
| * OUTPUTS: |
| * res - IRL Resource data |
| * |
| * RETURNS: |
| * GT_OK on success, |
| * GT_FAIL otherwise. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| static GT_STATUS pirlReadResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| OUT GT_PIRL_RESOURCE *res |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_U16 data[8]; /* temporary Data storage */ |
| GT_PIRL_OPERATION op; |
| GT_PIRL_OP_DATA opData; |
| int i; |
| |
| op = PIRL_READ_RESOURCE; |
| |
| for(i=0; i<8; i++) |
| { |
| opData.irlUnit = irlUnit; |
| opData.irlReg = i; |
| opData.irlData = 0; |
| |
| retVal = pirlOperationPerform(dev, op, &opData); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| |
| data[i] = (GT_U16)opData.irlData; |
| } |
| |
| |
| /* reg0 data */ |
| res->bktRateType = (data[0] >> 15) & 0x1; |
| res->bktTypeMask = (data[0] >> 4) & 0x7F; |
| |
| res->byteTobeCounted = data[0] & 0xF; |
| |
| /* reg1 data */ |
| res->bktIncrement = data[1] & 0xFFF; |
| |
| /* reg2 data */ |
| res->bktRateFactor = data[2] & 0xFFFF; |
| |
| /* reg3,4 data */ |
| res->cbsLimit = ((data[3] >> 4) & 0xFFF) | ((data[4] & 0xFFF) << 12); |
| |
| /* reg5,6 data */ |
| res->ebsLimit = data[5] | ((data[6] & 0xFF) << 16); |
| |
| /* reg6 data */ |
| res->ebsLimitAction = (data[6] >> 12) & 0x1; |
| res->accountFiltered = (data[6] >> 14) & 0x1; |
| res->accountQConf = (data[6] >> 15) & 0x1; |
| |
| return GT_OK; |
| } |
| |
| /******************************************************************************* |
| * pirlSetPortVec |
| * |
| * DESCRIPTION: |
| * This routine sets port list that share the bucket and resets ports that |
| * do not share the bucket. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used. |
| * portVec - the list of ports that share the bucket. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| static GT_STATUS pirlSetPortVec |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_U32 portVec |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value. */ |
| GT_LPORT port; |
| GT_U8 hwPort; /* Physical port. */ |
| GT_U16 data; |
| |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| if(GT_IS_PORT_SET(portVec,port)) |
| data = 1; |
| else |
| data = 0; |
| |
| hwPort = GT_LPORT_2_PORT(port); |
| |
| /* Set the resource vector. */ |
| retVal = hwSetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,(GT_U8)irlUnit,1,data); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| } |
| |
| DBG_INFO(("OK.\n")); |
| |
| return GT_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * pirlGetPortVec |
| * |
| * DESCRIPTION: |
| * This routine gets port list that share the bucket. |
| * |
| * INPUTS: |
| * irlUnit - bucket to be used. |
| * |
| * OUTPUTS: |
| * portVec - the list of ports that share the bucket. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| static GT_STATUS pirlGetPortVec |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| OUT GT_U32 *portVec |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value. */ |
| GT_LPORT port; |
| GT_U8 hwPort; /* Physical port. */ |
| GT_U16 data; |
| |
| *portVec = 0; |
| |
| for(port=0; port<dev->numOfPorts; port++) |
| { |
| hwPort = GT_LPORT_2_PORT(port); |
| |
| /* Set the resource vector. */ |
| retVal = hwGetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,(GT_U8)irlUnit,1,&data); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| |
| if(data == 1) |
| *portVec |= (1 << port); |
| } |
| |
| DBG_INFO(("OK.\n")); |
| |
| return GT_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * pirlSetFcMode |
| * |
| * DESCRIPTION: |
| * This routine gets Port Ingress Rate Limit Flow Control mode. |
| * When EBSLimitAction is programmed to generate a flow control message, |
| * the deassertion of flow control is controlled by this mode. |
| * GT_PIRL_FC_DEASSERT_EMPTY: |
| * De-assert when the ingress rate resource has become empty |
| * GT_PIRL_FC_DEASSERT_CBS_LIMIT |
| * De-assert when the ingress rate resource has enough room as |
| * specified by the CBSLimit. |
| * Please refer to GT_PIRL_RESOURCE structure for EBSLimitAction and |
| * CBSLimit. |
| * |
| * INPUTS: |
| * port - logical port number |
| * mode - GT_PIRL_FC_DEASSERT enum type |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * GT_OK - on success |
| * GT_FAIL - on error |
| * GT_NOT_SUPPORTED - if current device does not support this feature. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| static GT_STATUS pirlSetFcMode |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_LPORT port, |
| IN GT_PIRL_FC_DEASSERT mode |
| ) |
| { |
| GT_U16 data; |
| GT_STATUS retVal; /* Functions return value. */ |
| GT_U8 hwPort; /* Physical port. */ |
| |
| DBG_INFO(("pirlSetFcMode Called.\n")); |
| |
| hwPort = GT_LPORT_2_PORT(port); |
| |
| data = (GT_U16) mode; |
| |
| /* Set the PirlFcMode. */ |
| retVal = hwSetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,12,1,data); |
| if(retVal != GT_OK) |
| { |
| DBG_INFO(("Failed.\n")); |
| return retVal; |
| } |
| |
| DBG_INFO(("OK.\n")); |
| |
| return GT_OK; |
| } |
| |
| #define PIRL_DEBUG |
| #ifdef PIRL_DEBUG |
| /******************************************************************************* |
| * pirlDumpResource |
| * |
| * DESCRIPTION: |
| * This function dumps IRL Resource register values. |
| * |
| * INPUTS: |
| * irlUnit - resource unit to be accessed |
| * dataLen - data size. |
| * |
| * OUTPUTS: |
| * data - IRL Resource data |
| * |
| * RETURNS: |
| * GT_OK on success, |
| * GT_FAIL otherwise. |
| * |
| * COMMENTS: |
| * |
| *******************************************************************************/ |
| GT_STATUS pirlDumpResource |
| ( |
| IN GT_QD_DEV *dev, |
| IN GT_U32 irlUnit, |
| IN GT_U32 dataLen, |
| OUT GT_U16 *data |
| ) |
| { |
| GT_STATUS retVal; /* Functions return value */ |
| GT_PIRL_OPERATION op; |
| GT_PIRL_OP_DATA opData; |
| GT_U32 i; |
| |
| /* check if device supports this feature */ |
| if (!IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) |
| { |
| DBG_INFO(("GT_NOT_SUPPORTED\n")); |
| return GT_NOT_SUPPORTED; |
| } |
| |
| op = PIRL_READ_RESOURCE; |
| |
| for(i=0; i<dataLen; i++) |
| { |
| opData.irlUnit = irlUnit; |
| opData.irlReg = i; |
| opData.irlData = 0; |
| |
| retVal = pirlOperationPerform(dev, op, &opData); |
| if (retVal != GT_OK) |
| { |
| DBG_INFO(("PIRL OP Failed.\n")); |
| return retVal; |
| } |
| |
| data[i] = (GT_U16)opData.irlData; |
| } |
| |
| return GT_OK; |
| } |
| #endif /* PIRL_DEBUG */ |