cosq.c (6635B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * COS Queue Management 8 * Purpose: API to set different cosq, priorities, and scheduler registers. 9 */ 10 11 #include <soc/defs.h> 12 #include <soc/drv.h> 13 #include <soc/debug.h> 14 15 #include <bcm/error.h> 16 #include <bcm/cosq.h> 17 18 #define HR2_PKT_REFRESH_MAX 0xfffff 19 #define HR2_PKT_THD_MAX 0xfff 20 21 STATIC int 22 _bcm_hr2_cosq_port_packet_bandwidth_set(int unit, bcm_port_t port, 23 bcm_cos_queue_t cosq, 24 int pps, int burst) 25 { 26 uint32 regval; 27 soc_reg_t maxbucket_config_reg, maxbucket_reg; 28 soc_field_t refresh_f, thd_sel_f, bucket_f; 29 30 if (cosq < 0) { 31 maxbucket_config_reg = PKTPORTMAXBUCKETCONFIGr; 32 maxbucket_reg = PKTPORTMAXBUCKETr; 33 refresh_f = PKT_PORT_MAX_REFRESHf; 34 thd_sel_f = PKT_PORT_MAX_THD_SELf; 35 bucket_f = PKT_PORT_MAX_BUCKETf; 36 cosq = 0; 37 } else { 38 maxbucket_config_reg = PKTMAXBUCKETCONFIGr; 39 maxbucket_reg = PKTMAXBUCKETr; 40 refresh_f = PKT_MAX_REFRESHf; 41 thd_sel_f = PKT_MAX_THD_SELf; 42 bucket_f = PKT_MAX_BUCKETf; 43 } 44 45 /* 46 * To set the new Bandwidth settings, the procedure adopted is 47 * a. reset MAXBUCKETCONFIG and MAXBUCKET 48 * b. update MAXBUCKETCONFIG with new values passed 49 * c. if MISCCONFIG.METERING_CLK_EN not set before, enable it. 50 */ 51 52 /* Disable egress metering */ 53 BCM_IF_ERROR_RETURN 54 (soc_reg32_get(unit, maxbucket_config_reg, REG_PORT_ANY, cosq, ®val)); 55 soc_reg_field_set(unit, maxbucket_config_reg, ®val, refresh_f, 0); 56 soc_reg_field_set(unit, maxbucket_config_reg, ®val, thd_sel_f, 0); 57 BCM_IF_ERROR_RETURN 58 (soc_reg32_set(unit, maxbucket_config_reg, REG_PORT_ANY, cosq, regval)); 59 60 /* reset the MAXBUCKET register*/ 61 BCM_IF_ERROR_RETURN 62 (soc_reg32_get(unit, maxbucket_reg, REG_PORT_ANY, cosq, ®val)); 63 soc_reg_field_set(unit, maxbucket_reg, ®val, bucket_f, 0); 64 soc_reg_field_set(unit, maxbucket_reg, ®val, IN_PROFILE_FLAGf, 0); 65 BCM_IF_ERROR_RETURN 66 (soc_reg32_set(unit, maxbucket_reg, REG_PORT_ANY, cosq, regval)); 67 68 /* Check packets-per second upper limit */ 69 if (pps > HR2_PKT_REFRESH_MAX) { 70 pps = HR2_PKT_REFRESH_MAX; 71 } 72 73 /* Check burst upper limit */ 74 if (burst > HR2_PKT_THD_MAX) { 75 burst = HR2_PKT_THD_MAX; 76 } 77 78 BCM_IF_ERROR_RETURN 79 (soc_reg32_get(unit, maxbucket_config_reg, REG_PORT_ANY, cosq, ®val)); 80 soc_reg_field_set(unit, maxbucket_config_reg, ®val, refresh_f, pps); 81 soc_reg_field_set(unit, maxbucket_config_reg, 82 ®val, thd_sel_f, burst); 83 BCM_IF_ERROR_RETURN 84 (soc_reg32_set(unit, maxbucket_config_reg, REG_PORT_ANY, cosq, regval)); 85 86 /* MISCCONFIG.METERING_CLK_EN is set by chip init */ 87 88 SOC_IF_ERROR_RETURN(READ_PKTSHAPECONFIGr(unit, ®val)); 89 if (soc_reg_field_get(unit, PKTSHAPECONFIGr, regval, ENABLEf) == 0) { 90 soc_reg_field_set(unit, PKTSHAPECONFIGr, ®val, ENABLEf, 1); 91 SOC_IF_ERROR_RETURN(WRITE_PKTSHAPECONFIGr(unit, regval)); 92 } 93 94 return BCM_E_NONE; 95 } 96 97 STATIC int 98 _bcm_hr2_cosq_port_packet_bandwidth_get(int unit, bcm_port_t port, 99 bcm_cos_queue_t cosq, 100 int *pps, int *burst) 101 { 102 uint32 regval; 103 soc_reg_t maxbucket_config_reg; 104 soc_field_t refresh_f, thd_sel_f; 105 106 if (cosq < 0) { 107 maxbucket_config_reg = PKTPORTMAXBUCKETCONFIGr; 108 refresh_f = PKT_PORT_MAX_REFRESHf; 109 thd_sel_f = PKT_PORT_MAX_THD_SELf; 110 cosq = 0; 111 } else { 112 maxbucket_config_reg = PKTMAXBUCKETCONFIGr; 113 refresh_f = PKT_MAX_REFRESHf; 114 thd_sel_f = PKT_MAX_THD_SELf; 115 } 116 117 /* Disable egress metering */ 118 BCM_IF_ERROR_RETURN 119 (soc_reg32_get(unit, maxbucket_config_reg, REG_PORT_ANY, cosq, ®val)); 120 *pps = soc_reg_field_get(unit, maxbucket_config_reg, regval, refresh_f); 121 *burst = soc_reg_field_get(unit, maxbucket_config_reg, 122 regval, thd_sel_f); 123 124 return BCM_E_NONE; 125 } 126 127 int 128 bcm_hr2_cosq_port_pps_set(int unit, bcm_port_t port, 129 bcm_cos_queue_t cosq, int pps) 130 { 131 int temp_pps, burst; 132 133 if (!IS_CPU_PORT(unit, port)) { 134 return BCM_E_PORT; 135 } else if (cosq >= NUM_CPU_COSQ(unit)) { 136 return BCM_E_PARAM; 137 } else if (pps < 0) { 138 return BCM_E_PARAM; 139 } 140 141 /* Get the current PPS and BURST settings */ 142 BCM_IF_ERROR_RETURN 143 (_bcm_hr2_cosq_port_packet_bandwidth_get(unit, port, cosq, 144 &temp_pps, &burst)); 145 146 /* Replace the current PPS setting, keep BURST the same */ 147 return _bcm_hr2_cosq_port_packet_bandwidth_set(unit, port, cosq, 148 pps, burst); 149 } 150 151 int 152 bcm_hr2_cosq_port_pps_get(int unit, bcm_port_t port, 153 bcm_cos_queue_t cosq, int *pps) 154 { 155 int burst; 156 157 if (!IS_CPU_PORT(unit, port)) { 158 return BCM_E_PORT; 159 } else if (cosq >= NUM_CPU_COSQ(unit)) { 160 return BCM_E_PARAM; 161 } 162 163 return _bcm_hr2_cosq_port_packet_bandwidth_get(unit, port, cosq, 164 pps, &burst); 165 } 166 167 int 168 bcm_hr2_cosq_port_burst_set(int unit, bcm_port_t port, 169 bcm_cos_queue_t cosq, int burst) 170 { 171 int pps, temp_burst; 172 173 if (!IS_CPU_PORT(unit, port)) { 174 return BCM_E_PORT; 175 } else if (cosq >= NUM_CPU_COSQ(unit)) { 176 return BCM_E_PARAM; 177 } else if (burst < 0) { 178 return BCM_E_PARAM; 179 } 180 181 /* Get the current PPS and BURST settings */ 182 BCM_IF_ERROR_RETURN 183 (_bcm_hr2_cosq_port_packet_bandwidth_get(unit, port, cosq, 184 &pps, &temp_burst)); 185 186 /* Replace the current BURST setting, keep PPS the same */ 187 return _bcm_hr2_cosq_port_packet_bandwidth_set(unit, port, cosq, 188 pps, burst); 189 } 190 191 int 192 bcm_hr2_cosq_port_burst_get(int unit, bcm_port_t port, 193 bcm_cos_queue_t cosq, int *burst) 194 { 195 int pps; 196 197 if (!IS_CPU_PORT(unit, port)) { 198 return BCM_E_PORT; 199 } else if (cosq >= NUM_CPU_COSQ(unit)) { 200 return BCM_E_PARAM; 201 } 202 203 return _bcm_hr2_cosq_port_packet_bandwidth_get(unit, port, cosq, 204 &pps, burst); 205 }