pfc.c (11705B)
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 * PFC implemenation for Tomahawk3 8 */ 9 #if defined(BCM_TOMAHAWK3_SUPPORT) 10 #include <bcm_int/esw/pfc.h> 11 #include <bcm_int/esw/port.h> 12 #include <soc/pfc.h> 13 #include <soc/feature.h> 14 #include <soc/drv.h> 15 #include <soc/types.h> 16 #include <soc/scache.h> 17 #include <soc/profile_mem.h> 18 #include <soc/debug.h> 19 #include <soc/tomahawk.h> 20 #include <soc/dma.h> 21 #include <soc/mmu_config.h> 22 #include <soc/init/tomahawk3_idb_init.h> 23 24 #define TH3_PFC_PRIORITY_GROUP_ID_MIN 0 25 #define TH3_PFC_PRIORITY_GROUP_ID_MAX 7 26 #define TH3_PORT_PG_ENABLE_MASK 0xff 27 28 29 30 /* 31 * Function: 32 * bcm_th3_port_priority_group_config_set 33 * Purpose: 34 * Set the port priority group configuration. 35 * Parameters: 36 * unit - (IN) device id. 37 * gport - (IN) generic port. 38 * priority_group - (IN) priority group id. 39 * prigrp_config - (IN) structure describes port PG configuration. 40 * Returns: 41 * BCM_E_XXX 42 */ 43 int 44 bcm_th3_port_priority_group_config_set(int unit, bcm_gport_t gport, 45 int priority_group, bcm_port_priority_group_config_t *prigrp_config) 46 { 47 bcm_port_t port; 48 uint32 rval, pri_bmp; 49 50 if(!soc_feature(unit, soc_feature_priority_flow_control)) { 51 return BCM_E_UNAVAIL; 52 } 53 if ((priority_group < TH3_PFC_PRIORITY_GROUP_ID_MIN) || 54 (priority_group > TH3_PFC_PRIORITY_GROUP_ID_MAX)) { 55 return BCM_E_PARAM; 56 } 57 if (prigrp_config == NULL) { 58 return BCM_E_PARAM; 59 } 60 /* The following fields should not used in TH3 */ 61 if (prigrp_config->shared_pool_xoff_enable || 62 prigrp_config->shared_pool_discard_enable || 63 prigrp_config->priority_enable_vector_mask) { 64 return BCM_E_UNAVAIL; 65 } 66 67 BCM_IF_ERROR_RETURN(_bcm_th3_cosq_localport_resolve(unit, gport, &port)); 68 if (!SOC_PORT_VALID(unit, port)) { 69 return BCM_E_PORT; 70 } 71 72 SOC_IF_ERROR_RETURN(READ_MMU_THDI_ING_PORT_CONFIGr(unit, port, &rval)); 73 pri_bmp = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval, 74 PFC_PG_ENABLEf); 75 76 if (prigrp_config->pfc_transmit_enable) { 77 pri_bmp |= (1 << priority_group); 78 } else { 79 pri_bmp &= ~(1 << priority_group); 80 } 81 82 soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 83 PFC_PG_ENABLEf, pri_bmp); 84 BCM_IF_ERROR_RETURN(WRITE_MMU_THDI_ING_PORT_CONFIGr(unit, port, rval)); 85 return BCM_E_NONE; 86 } 87 88 /* 89 * Function: 90 * bcm_th3_port_priority_group_config_get 91 * Purpose: 92 * Get the port priority group configuration. 93 * Parameters: 94 * unit - (IN) device id. 95 * gport - (IN) generic port. 96 * priority_group - (IN) priority group id. 97 * prigrp_config - (OUT) structure describes port PG configuration. 98 * Returns: 99 * BCM_E_XXX 100 */ 101 int 102 bcm_th3_port_priority_group_config_get(int unit, bcm_gport_t gport, 103 int priority_group, bcm_port_priority_group_config_t *prigrp_config) 104 { 105 bcm_port_t port; 106 uint32 rval, pri_bmp; 107 108 if (!soc_feature(unit, soc_feature_priority_flow_control)) { 109 return BCM_E_UNAVAIL; 110 } 111 if ((priority_group < TH3_PFC_PRIORITY_GROUP_ID_MIN) || 112 (priority_group > TH3_PFC_PRIORITY_GROUP_ID_MAX)) { 113 return BCM_E_PARAM; 114 } 115 if (prigrp_config == NULL) { 116 return BCM_E_PARAM; 117 } 118 119 BCM_IF_ERROR_RETURN(_bcm_th3_cosq_localport_resolve(unit, gport, &port)); 120 if (!SOC_PORT_VALID(unit, port)) { 121 return BCM_E_PORT; 122 } 123 124 SOC_IF_ERROR_RETURN(READ_MMU_THDI_ING_PORT_CONFIGr(unit, port, &rval)); 125 pri_bmp = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval, 126 PFC_PG_ENABLEf); 127 if (pri_bmp & (1U << priority_group)) { 128 prigrp_config->pfc_transmit_enable = 1; 129 } else { 130 prigrp_config->pfc_transmit_enable = 0; 131 } 132 133 return BCM_E_NONE; 134 } 135 /* 136 * Function: 137 bcm_th3_mmu_pfc_tx_config_set 138 * Purpose: 139 * Enable/diable PFC tx. 140 * Parameters: 141 * unit - (IN) device id. 142 * port - (IN) logical port number. 143 * pfc_enable - (IN) PFC enable, 0: disable, 1: enable. 144 * pri_bmp - (OUT) priority Group Bitmap. 145 * Returns: 146 * BCM_E_XXX 147 */ 148 149 int 150 bcm_th3_mmu_pfc_tx_config_set(int unit, bcm_port_t port, int pfc_enable, 151 uint32 pri_bmp) 152 { 153 soc_reg_t reg = INVALIDr; 154 uint32 rval; 155 156 /* only 8 bits are needed, higher-position bits are masked out */ 157 pri_bmp = pri_bmp & TH3_PORT_PG_ENABLE_MASK; 158 reg = MMU_THDI_ING_PORT_CONFIGr; 159 160 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 161 162 soc_reg_field_set(unit, reg, &rval, PFC_PG_ENABLEf, 163 pfc_enable ? pri_bmp : 0); 164 165 soc_reg_field_set(unit, reg, &rval, PAUSE_ENABLEf, 166 pfc_enable ? 0 : 1); 167 168 SOC_IF_ERROR_RETURN 169 (soc_reg32_set(unit, reg, port, 0, rval)); 170 171 if (IS_CD_PORT(unit, port)) { 172 soc_info_t *si = &SOC_INFO(unit); 173 uint64 rval64; 174 int pipe, pm_num, phy_port, subp; 175 const soc_reg_t obm_fc_config_regs[_TH3_PIPES_PER_DEV] 176 [_TH3_PBLKS_PER_PIPE] = 177 {{IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r, 178 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r}, 179 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r, 180 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r}, 181 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r, 182 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r}, 183 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r, 184 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r}, 185 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE4r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE4r, 186 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE4r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE4r}, 187 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE5r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE5r, 188 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE5r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE5r}, 189 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE6r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE6r, 190 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE6r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE6r}, 191 {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE7r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE7r, 192 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE7r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE7r}, 193 }; 194 195 phy_port = si->port_l2p_mapping[port]; 196 pipe = soc_tomahawk3_get_pipe_from_phy_port(phy_port); 197 pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port); 198 subp = soc_tomahawk3_get_subp_from_phy_port(phy_port); 199 reg = obm_fc_config_regs[pipe][pm_num]; 200 COMPILER_64_SET(rval64, 0, 0); 201 SOC_IF_ERROR_RETURN 202 (soc_reg_rawport_get(unit, reg, REG_PORT_ANY, 203 subp, &rval64)); 204 soc_reg64_field32_set(unit, reg, 205 &rval64, FC_TYPEf, pfc_enable); 206 SOC_IF_ERROR_RETURN 207 (soc_reg_rawport_set(unit, reg, REG_PORT_ANY, 208 subp, rval64)); 209 } 210 return BCM_E_NONE; 211 } 212 213 /* 214 * Function: 215 bcm_th3_mmu_pfc_rx_config_set 216 * Purpose: 217 * Enable/diable PFC rx. 218 * Parameters: 219 * unit - (IN) device id. 220 * port - (IN) logical port number. 221 * pfc_enable - (IN) PFC enable, 0: disable, 1: enable. 222 * Returns: 223 * BCM_E_XXX 224 */ 225 int 226 bcm_th3_mmu_pfc_rx_config_set(int unit, bcm_port_t port, int pfc_enable) 227 { 228 uint32 rval; 229 soc_reg_t reg = MMU_INTFI_EGR_PORT_CFGr; 230 231 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 232 233 soc_reg_field_set(unit, reg, &rval, DISABLE_Q_FCf, 234 pfc_enable ? 0 : 1); 235 236 SOC_IF_ERROR_RETURN 237 (soc_reg32_set(unit, reg, port, 0, rval)); 238 return BCM_E_NONE; 239 } 240 241 /* 242 * Function: 243 bcm_tomahawk3_cosq_pfc_class_config_profile_get 244 * Purpose: 245 * Get an entire PFC class (RX) profile, tomahawk3 dispatch function 246 * Parameters: 247 * unit - (IN) device id. 248 * profile_id - (IN) Profile ID. 249 * max_count - (IN) Maximum number of elements in config array 250 * config_array - (OUT) PFC class config array 251 * count - (OUT) actual size of array 252 * Returns: 253 * BCM_E_XXX 254 */ 255 256 int 257 bcm_tomahawk3_cosq_pfc_class_config_profile_get( 258 int unit, 259 int profile_id, 260 int max_count, 261 bcm_cosq_pfc_class_map_config_t *config_array, 262 int *count) 263 { 264 return (soc_th3_pfc_rx_priority_mapping_profile_get 265 (unit, profile_id, max_count, 266 (soc_cosq_pfc_class_map_config_t *) config_array, count)); 267 } 268 269 /* 270 * Function: 271 bcm_tomahawk3_cosq_pfc_class_config_profile_set 272 * Purpose: 273 * Set an entire PFC class (RX) profile, tomahawk3 dispatch function. 274 * Parameters: 275 * unit - (IN) device id. 276 * profile_id - (IN) Profile ID. 277 * count - (IN) actual size of array 278 * config_array - (IN) PFC class config array 279 * Returns: 280 * BCM_E_XXX 281 */ 282 283 int 284 bcm_tomahawk3_cosq_pfc_class_config_profile_set( 285 int unit, 286 int profile_id, 287 int count, 288 bcm_cosq_pfc_class_map_config_t *config_array) 289 { 290 291 return (soc_th3_pfc_rx_priority_mapping_profile_set 292 (unit, profile_id, 293 (soc_cosq_pfc_class_map_config_t *) config_array, count)); 294 } 295 296 /* 297 * Function: 298 bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_get 299 * Purpose: 300 * Get a PFC-tx priority to PG mapping profile, tomahawk3 dispatch function 301 * Parameters: 302 * unit - (IN) device id. 303 * profile_id - (IN) Profile ID. 304 * array_max - (IN) Maximum number of elements in PG array 305 * config_array - (OUT) PG array, indexed by PFC priority 306 * array_count - (OUT) actual size of array 307 * Returns: 308 * BCM_E_XXX 309 */ 310 int 311 bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_get( 312 int unit, 313 int profile_id, 314 int array_max, 315 int *pg_array, 316 int *array_count) 317 { 318 return (soc_th3_pfc_tx_priority_mapping_profile_op(unit, profile_id, 319 array_max, SOC_TH3_PFC_PROFILE_OP_GET, array_count, pg_array)); 320 } 321 322 /* 323 * Function: 324 bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_set 325 * Purpose: 326 * Set a PFC-tx priority to PG mapping profile, tomahawk3 dispatch function 327 * Parameters: 328 * unit - (IN) device id. 329 * profile_id - (IN) Profile ID. 330 * array_count - (IN) actual size of array 331 * config_array - (IN) PG array, indexed by PFC priority 332 333 * Returns: 334 * BCM_E_XXX 335 */ 336 int 337 bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_set( 338 int unit, 339 int profile_id, 340 int array_count, 341 int *pg_array) 342 { 343 return (soc_th3_pfc_tx_priority_mapping_profile_op(unit, profile_id, 344 0, SOC_TH3_PFC_PROFILE_OP_SET, &array_count, pg_array)); 345 } 346 347 348 /* 349 * Function: 350 bcm_tomahawk3_cosq_port_optimized_pfc_group_num_get 351 * Purpose: 352 * Get number of optimized PFC groups on a port, tomahawk3 dispatch function 353 * Parameters: 354 * unit - (IN) device id. 355 * port - (IN) logical port number. 356 * count - (OUT) number of optimized PFC groups supported. 357 * 358 * Returns: 359 * BCM_E_XXX 360 */ 361 int 362 bcm_tomahawk3_cosq_port_optimized_pfc_group_num_get( 363 int unit, 364 bcm_port_t port, 365 int *count) 366 { 367 return (soc_th3_pfc_num_optimized_group_get(unit, port, count)); 368 } 369 #endif