/* * Copyright (C) 2009 Realtek Semiconductor Corp. * All Rights Reserved. * * This program is the proprietary software of Realtek Semiconductor * Corporation and/or its licensors, and only be used, duplicated, * modified or distributed under the authorized license from Realtek. * * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. * * $Revision: 1.1 $ * $Date: 2011/04/11 13:34:56 $ * * Purpose : RTL8370 switch high-level API for RTL8367B * Feature : * */ #include <rtl8370_asicdrv_scheduling.h> /* @func ret_t | rtl8370_setAsicLeakyBucketParameter | Set Leaky Bucket Paramters. @parm uint32 | tick | Tick is used for time slot size unit. @parm uint32 | token | Token is used for adding budget in each time slot. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_TICK | Invalid TICK. @rvalue RT_ERR_TOKEN | Invalid TOKEN. @comm The API can set leaky bucket parameters as token and tick. The default suggesting values of (tick, token) are (0x77, 0x62). */ ret_t rtl8370_setAsicLeakyBucketParameter(uint32 tick, uint32 token) { ret_t retVal; if(tick > 0xFF) return RT_ERR_TICK; if(token > 0xFF) return RT_ERR_TOKEN; retVal = rtl8370_setAsicRegBits(RTL8370_LEAKY_BUCKET_TICK_REG, RTL8370_LEAKY_BUCKET_TICK_MASK, tick); if(retVal != RT_ERR_OK) return retVal; retVal = rtl8370_setAsicRegBits(RTL8370_LEAKY_BUCKET_TOKEN_REG, RTL8370_LEAKY_BUCKET_TOKEN_MASK, token); return retVal; } /* @func ret_t | rtl8370_getAsicLeakyBucketParameter | Set Leaky Bucket Paramters. @parm uint32* | tick | Tick is used for time slot size unit. @parm uint32* | token | Token is used for adding budget in each time slot. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_TICK | Invalid TICK. @rvalue RT_ERR_TOKEN | Invalid TOKEN. @comm The API can set leaky bucket parameters as token and tick. The default suggesting values of (tick, token) are (0x77, 0x62). */ ret_t rtl8370_getAsicLeakyBucketParameter(uint32 *tick, uint32 *token) { ret_t retVal; retVal = rtl8370_getAsicRegBits(RTL8370_LEAKY_BUCKET_TICK_REG, RTL8370_LEAKY_BUCKET_TICK_MASK, tick); if(retVal != RT_ERR_OK) return retVal; retVal = rtl8370_getAsicRegBits(RTL8370_LEAKY_BUCKET_TOKEN_REG, RTL8370_LEAKY_BUCKET_TOKEN_MASK, token); return retVal; } /* @func ret_t | rtl8370_setAsicAprMeter | Set per-port per-queue APR shared meter index @parm uint32 | port | The port number @parm uint32 | qid | Queue id. @parm uint32 | apridx | dedicated shared meter index for APR (0~7). @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QUEUE_ID | Invalid queue id. @rvalue RT_ERR_FILTER_METER_ID | Invalid meter @comm The API can set APR shared meter index. Each port has dedicated shared meter usage range. Port 0 & 8 ARP 7~0 Port 1 & 9 ARP 15~8 Port 2 & 10 ARP 23~16 : Port 7 & 15 ARP 63~56 */ ret_t rtl8370_setAsicAprMeter(uint32 port, uint32 qid, uint32 apridx) { ret_t retVal; if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(qid > RTL8370_QIDMAX) return RT_ERR_QUEUE_ID; if(apridx > RTL8370_PORT_QUEUE_METER_INDEX_MAX) return RT_ERR_FILTER_METER_ID; retVal = rtl8370_setAsicRegBits(RTL8370_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8370_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); return retVal; } /* @func ret_t | rtl8370_getAsicAprMeter | Get per-port per-queue APR shared meter index @parm uint32 | port | The port number @parm uint32 | qid | Queue id. @parm uint32* | apridx | shared meter index for APR. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QUEUE_ID | Invalid queue id. @rvalue RT_ERR_FILTER_METER_ID | Invalid meter @comm The API can get APR shared meter index. Each port has dedicated shared meter usage range. */ ret_t rtl8370_getAsicAprMeter(uint32 port, uint32 qid, uint32 *apridx) { ret_t retVal; if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(qid > RTL8370_QIDMAX) return RT_ERR_QUEUE_ID; retVal = rtl8370_getAsicRegBits(RTL8370_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8370_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); return retVal; } /* @func ret_t | rtl8370_setAsicAprEnable | Set per-port APR enable. @parm uint32 | port | The port number @parm uint32 | aprEnable | APR enable seting 1:enable 0:disable. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_ENABLE | Invalid enable parameter. @comm The API can set per-port APR enable setting */ ret_t rtl8370_setAsicAprEnable(uint32 port, uint32 aprEnable) { ret_t retVal; if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if((aprEnable != 0) && (aprEnable != 1)) return RT_ERR_ENABLE; retVal = rtl8370_setAsicRegBit(RTL8370_SCHEDULE_APR_CRTL_REG, RTL8370_SCHEDULE_APR_CRTL_OFFSET(port), aprEnable); return retVal; } /* @func ret_t | rtl8370_getAsicAprEnable | Set per-port APR enable. @parm uint32 | port | The port number @parm uint32* | aprEnable | APR enable seting 1:enable 0:disable. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @comm The API can get per-port APR enable setting */ ret_t rtl8370_getAsicAprEnable(uint32 port, uint32 *aprEnable) { ret_t retVal; if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; retVal = rtl8370_getAsicRegBit(RTL8370_SCHEDULE_APR_CRTL_REG, RTL8370_SCHEDULE_APR_CRTL_OFFSET(port), aprEnable); return retVal; } /* @func ret_t | rtl8370_setAsicWFQWeight | Set weight of a queue. @parm uint32 | port | The port number. @parm uint32 | qid | The queue ID wanted to set. @parm uint32 | qWeight | The weight value wanted to set (valid:0~127). @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QUEUE_ID | Invalid queue id. @rvalue RT_ERR_QOS_QUEUE_WEIGHT | Invalid queue weight. @comm The API can set weight of the specified queue. Parameter 'qweight' is only used in queueType = strict priority. If queue type is strict priority, the parameter 'qweight' can be ignored. */ ret_t rtl8370_setAsicWFQWeight(uint32 port, uint32 qid, uint32 qWeight) { ret_t retVal; /* Invalid input parameter */ if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(qid > RTL8370_QIDMAX) return RT_ERR_QUEUE_ID; if(qWeight > RTL8370_QWEIGHTMAX) return RT_ERR_QOS_QUEUE_WEIGHT; retVal = rtl8370_setAsicReg(RTL8370_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); return retVal; } /* @func ret_t | rtl8370_getAsicWFQWeight | Get weight of WFQ. @parm uint32 | port | The port number. @parm uint32 | qid | The queue ID wanted to set. @parm uint32* | qWeight | Pointer to the returned weight value. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QUEUE_ID | Invalid queue id. @comm The API can get weight of the specified queue. Parameter 'qweight' is only used in queueType = strict priority. If queue type is strict priority, the parameter 'qweight' can be ignored. */ ret_t rtl8370_getAsicWFQWeight(uint32 port, uint32 qid, uint32 *qWeight) { ret_t retVal; /* Invalid input parameter */ if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(qid > RTL8370_QIDMAX) return RT_ERR_QUEUE_ID; retVal = rtl8370_getAsicReg(RTL8370_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); return retVal; } /* @func ret_t | rtl8370_setAsicWFQBurstSize | Set WFQ leaky bucket burst size. @parm uint32 | burstsize | Leaky bucket burst size, unit byte @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @comm The API can set WFQ leaky bucket burst size(aka high threshold) */ ret_t rtl8370_setAsicWFQBurstSize(uint32 burstsize) { ret_t retVal; retVal = rtl8370_setAsicReg(RTL8370_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); return retVal; } /* @func ret_t | rtl8370_getAsicWFQBurstSize | Set WFQ leaky bucket burst size. @parm uint32* | burstsize | Leaky bucket burst size, unit byte @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @comm The API can set WFQ leaky bucket burst size(aka high threshold) */ ret_t rtl8370_getAsicWFQBurstSize(uint32 *burstsize) { ret_t retVal; retVal = rtl8370_getAsicReg(RTL8370_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); return retVal; } /* @func ret_t | rtl8370_setAsicQueueType | Set type of a queue. @parm uint32 | port | The port number. @parm uint32 | qid | The queue ID wanted to set. @parm uint32 | queueType | The specified queue type. 0b0: Strict priority, 0b1: WFQ. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QUEUE_ID | Invalid queue id. @rvalue RT_ERR_QOS_SCHE_TYPE | Invalid queue type. @comm The API can set type, strict priority or weight fair queue (WFQ), of the specified queue. */ ret_t rtl8370_setAsicQueueType(uint32 port, uint32 qid, uint32 queueType) { ret_t retVal; /* Invalid input parameter */ if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(qid > RTL8370_QIDMAX) return RT_ERR_QUEUE_ID; if((queueType != QTYPE_WFQ) && (queueType != QTYPE_STRICT)) return RT_ERR_QOS_SCHE_TYPE; /* Set Related Registers */ retVal = rtl8370_setAsicRegBit(RTL8370_SCHEDULE_QUEUE_TYPE_REG(port), RTL8370_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); return retVal; } /* @func ret_t | rtl8370_getAsicQueueType | Get type of WFQ. @parm uint32 | port | The port number. @parm uint32 | qid | The queue ID wanted to set. @parm uint32* | queueType | Pointer to the returned queue type. @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QUEUE_ID | Invalid queue id. @comm The API can get type, strict priority or weight fair queue (WFQ), of the specified queue. */ ret_t rtl8370_getAsicQueueType(uint32 port, uint32 qid, uint32 *queueType) { ret_t retVal; /* Invalid input parameter */ if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(qid > RTL8370_QIDMAX) return RT_ERR_QUEUE_ID; retVal = rtl8370_getAsicRegBit(RTL8370_SCHEDULE_QUEUE_TYPE_REG(port), RTL8370_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); return retVal; } /* @func ret_t | rtl8370_setAsicPortEgressRate | Set per-port egress rate @parm uint32 | port | The port number. @parm uint32 | rate | Egress rate @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @rvalue RT_ERR_QOS_EBW_RATE | Invalid egress bandwidth/rate @comm The API can set per-port egress rate */ ret_t rtl8370_setAsicPortEgressRate(uint32 port, uint32 rate) { ret_t retVal; uint32 regAddr, regData; if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; if(rate > RTL8370_QOS_GRANULARTY_MAX) return RT_ERR_QOS_EBW_RATE; regAddr = RTL8370_PORT_EGRESSBW_LSB_REG(port); regData = RTL8370_QOS_GRANULARTY_LSB_MASK & rate; retVal = rtl8370_setAsicReg(regAddr, regData); if(retVal != RT_ERR_OK) return retVal; regAddr = RTL8370_PORT_EGRESSBW_MSB_REG(port); regData = (RTL8370_QOS_GRANULARTY_MSB_MASK & rate) >> RTL8370_QOS_GRANULARTY_MSB_OFFSET; return rtl8370_setAsicRegBit(regAddr, RTL8370_PORT_EGRESSBW_MSB_OFFSET, regData); } /* @func ret_t | rtl8370_getAsicPortEgressRate | Set per-port egress rate @parm uint32 | port | The port number. @parm uint32* | rate | Egress rate @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_PORT_ID | Invalid port number. @comm The API can set per-port egress rate. */ ret_t rtl8370_getAsicPortEgressRate(uint32 port, uint32 *rate) { ret_t retVal; uint32 regAddr, regData,regData2; if(port > RTL8370_PORTIDMAX) return RT_ERR_PORT_ID; regAddr = RTL8370_PORT_EGRESSBW_LSB_REG(port); retVal = rtl8370_getAsicReg(regAddr, ®Data); if(retVal != RT_ERR_OK) return retVal; regAddr = RTL8370_PORT_EGRESSBW_MSB_REG(port); retVal = rtl8370_getAsicRegBit(regAddr, RTL8370_PORT_EGRESSBW_MSB_OFFSET, ®Data2); if(retVal != RT_ERR_OK) return retVal; *rate = regData | (regData2 << RTL8370_QOS_GRANULARTY_MSB_OFFSET); return RT_ERR_OK; } /* @func ret_t | rtl8370_setAsicPortEgressRateIfg | Set per-port egress rate calculate include/exclude IFG @parm uint32 | ifg | 1:include IFG 0:exclude IFG @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @rvalue RT_ERR_INPUT | Invalid input parameter. @comm The API can set egress rate with IFG or not. */ ret_t rtl8370_setAsicPortEgressRateIfg(uint32 ifg) { if(ifg > 1) return RT_ERR_INPUT; return rtl8370_setAsicRegBit(RTL8370_REG_SCHEDULE_WFQ_CTRL, RTL8370_WFQ_IFG_OFFSET, ifg); } /* @func ret_t | rtl8370_getAsicPortEgressRateIfg | Get per-port egress rate calculate include/exclude IFG @parm uint32* | ifg | 1:include IFG 0:exclude IFG @rvalue RT_ERR_OK | Success. @rvalue RT_ERR_SMI | SMI access error. @comm The API can get egress rate with IFG or not. */ ret_t rtl8370_getAsicPortEgressRateIfg(uint32 *ifg) { return rtl8370_getAsicRegBit(RTL8370_REG_SCHEDULE_WFQ_CTRL, RTL8370_WFQ_IFG_OFFSET, ifg); }