port.c (8946B)
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 * File: port.c 8 * Purpose: Port Management 9 */ 10 11 #include <soc/defs.h> 12 #if defined(BCM_TOMAHAWK_SUPPORT) 13 #include <soc/drv.h> 14 #include <soc/tomahawk.h> 15 #include <bcm/port.h> 16 #include <bcm/error.h> 17 #include <bcm_int/esw/port.h> 18 #include <bcm_int/esw/trident.h> 19 #include <bcm_int/esw/tomahawk.h> 20 #include <bcm_int/common/lock.h> 21 #include <bcm_int/esw_dispatch.h> 22 #include <bcm_int/esw/portctrl.h> 23 24 /* 25 * Function: 26 * bcm_th_port_rate_egress_set 27 * Purpose: 28 * Set egress metering information 29 * Parameters: 30 * unit - (IN) Unit number 31 * port - (IN) Port number 32 * bandwidth - (IN) Kilobits per second or packets per second 33 * zero if rate limiting is disabled 34 * burst - (IN) Maximum burst size in kilobits or packets 35 * mode - (IN) _BCM_PORT_RATE_BYTE_MODE or _BCM_PORT_RATE_PPS_MODE 36 * Returns: 37 * BCM_E_XXX 38 */ 39 int 40 bcm_th_port_rate_egress_set(int unit, bcm_port_t port, uint32 bandwidth, 41 uint32 burst, uint32 mode) 42 { 43 soc_info_t *si; 44 int phy_port, mmu_port, index, pipe; 45 soc_mem_t mem = MMU_MTRO_EGRMETERINGCONFIG_MEMm; 46 uint32 rval, itu_mode_sel; 47 mmu_mtro_egrmeteringconfig_mem_0_entry_t entry; 48 uint32 refresh_rate, bucketsize, granularity, flags; 49 int refresh_bitsize, bucket_bitsize; 50 51 si = &SOC_INFO(unit); 52 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 53 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 54 55 sal_memset(&entry, 0, sizeof(entry)); 56 57 index = mmu_port & 0x3f; 58 pipe = si->port_pipe[port]; 59 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe]; 60 61 /* If metering is disabled on this ingress port we are done. */ 62 if (!bandwidth || !burst) { 63 SOC_IF_ERROR_RETURN 64 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 65 return BCM_E_NONE; 66 } 67 if((bandwidth < _BCM_PORT_RATE_MIN_KILOBITS || 68 bandwidth > _BCM_PORT_RATE_MAX_KILOBITS) || 69 (burst < _BCM_PORT_BURST_MIN_KILOBITS || 70 burst > _BCM_PORT_BURST_MAX_KILOBITS)){ 71 return BCM_E_PARAM; 72 } 73 flags = mode == _BCM_PORT_RATE_PPS_MODE ? 74 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 75 76 #ifdef BCM_TOMAHAWK2_SUPPORT 77 if (soc_feature(unit, soc_feature_mmu_sed)) { 78 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_MISCCONFIGr(unit, &rval)); 79 if (soc_reg_field_get(unit, MMU_SEDCFG_MISCCONFIGr, rval, ITU_MODE_SELf)) { 80 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 81 } 82 } else 83 #endif 84 { 85 BCM_IF_ERROR_RETURN(READ_MMU_SCFG_MISCCONFIGr(unit, &rval)); 86 itu_mode_sel = 87 soc_reg_field_get(unit, MMU_SCFG_MISCCONFIGr, rval, ITU_MODE_SELf); 88 89 if (itu_mode_sel) { 90 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 91 } 92 } 93 94 95 refresh_bitsize = soc_mem_field_length(unit, mem, REFRESHf); 96 bucket_bitsize = soc_mem_field_length(unit, mem, THD_SELf); 97 BCM_IF_ERROR_RETURN 98 (_bcm_td_rate_to_bucket_encoding(unit, bandwidth, burst, flags, 99 refresh_bitsize, bucket_bitsize, 100 &refresh_rate, &bucketsize, 101 &granularity)); 102 soc_mem_field32_set(unit, mem, &entry, MODEf, 103 mode == _BCM_PORT_RATE_PPS_MODE ? 1 : 0); 104 soc_mem_field32_set(unit, mem, &entry, METER_GRANf, granularity); 105 soc_mem_field32_set(unit, mem, &entry, REFRESHf, refresh_rate); 106 soc_mem_field32_set(unit, mem, &entry, THD_SELf, bucketsize); 107 108 SOC_IF_ERROR_RETURN 109 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 110 111 return BCM_E_NONE; 112 } 113 114 /* 115 * Function: 116 * bcm_th_port_rate_egress_get 117 * Purpose: 118 * Get egress metering information 119 * Parameters: 120 * unit - (IN) Unit number 121 * port - (IN) Port number 122 * bandwidth - (OUT) Kilobits per second or packets per second 123 * zero if rate limiting is disabled 124 * burst - (OUT) Maximum burst size in kilobits or packets 125 * mode - (OUT) _BCM_PORT_RATE_BYTE_MODE or _BCM_PORT_RATE_PPS_MODE 126 * Returns: 127 * BCM_E_XXX 128 */ 129 int 130 bcm_th_port_rate_egress_get(int unit, bcm_port_t port, uint32 *bandwidth, 131 uint32 *burst, uint32 *mode) 132 { 133 soc_info_t *si; 134 int phy_port, mmu_port, index, pipe; 135 soc_mem_t mem; 136 uint32 rval, itu_mode_sel; 137 mmu_mtri_bkpmeteringconfig_mem_0_entry_t entry; 138 uint32 refresh_rate, bucketsize, granularity, flags; 139 140 if (bandwidth == NULL || burst == NULL) { 141 return BCM_E_PARAM; 142 } 143 144 si = &SOC_INFO(unit); 145 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 146 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 147 148 index = mmu_port & 0x3f; 149 pipe = si->port_pipe[port]; 150 151 #ifdef BCM_TOMAHAWK3_SUPPORT 152 if (soc_mem_is_valid(unit, MMU_MTRO_EGRMETERINGCONFIGm)) { 153 mem = MMU_MTRO_EGRMETERINGCONFIGm; 154 } else 155 #endif 156 { 157 mem = MMU_MTRO_EGRMETERINGCONFIG_MEMm; 158 } 159 160 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe]; 161 162 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &entry)); 163 164 refresh_rate = soc_mem_field32_get(unit, mem, &entry, REFRESHf); 165 bucketsize = soc_mem_field32_get(unit, mem, &entry, THD_SELf); 166 granularity = soc_mem_field32_get(unit, mem, &entry, METER_GRANf); 167 168 #ifdef BCM_TOMAHAWK3_SUPPORT 169 if (soc_mem_field_valid(unit, mem, PACKET_SHAPINGf)) { 170 flags = soc_mem_field32_get(unit, mem, &entry, PACKET_SHAPINGf) ? 171 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 172 } else 173 #endif 174 { 175 flags = soc_mem_field32_get(unit, mem, &entry, MODEf) ? 176 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 177 } 178 179 #ifdef BCM_TOMAHAWK2_SUPPORT 180 if (soc_feature(unit, soc_feature_mmu_sed)) { 181 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_MISCCONFIGr(unit, &rval)); 182 if (soc_reg_field_get(unit, MMU_SEDCFG_MISCCONFIGr, rval, ITU_MODE_SELf)) { 183 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 184 } 185 } else 186 #endif 187 { 188 BCM_IF_ERROR_RETURN(READ_MMU_SCFG_MISCCONFIGr(unit, &rval)); 189 itu_mode_sel = 190 soc_reg_field_get(unit, MMU_SCFG_MISCCONFIGr, rval, ITU_MODE_SELf); 191 192 if (itu_mode_sel) { 193 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 194 } 195 } 196 197 BCM_IF_ERROR_RETURN 198 (_bcm_td_bucket_encoding_to_rate(unit, refresh_rate, bucketsize, 199 granularity, flags, bandwidth, 200 burst)); 201 *mode = flags & _BCM_TD_METER_FLAG_PACKET_MODE ? 202 _BCM_PORT_RATE_PPS_MODE : _BCM_PORT_RATE_BYTE_MODE; 203 204 return BCM_E_NONE; 205 } 206 207 int bcm_th_port_drain_cells(int unit, int port) 208 { 209 mac_driver_t *macd; 210 int rv = BCM_E_NONE; 211 212 /* Call Port Control module */ 213 if (SOC_USE_PORTCTRL(unit)) { 214 return bcmi_esw_portctrl_egress_queue_drain(unit, port); 215 } 216 217 if (IS_CPU_PORT(unit, port)) { 218 return BCM_E_PORT; 219 } 220 221 PORT_LOCK(unit); 222 rv = soc_mac_probe(unit, port, &macd); 223 224 if (BCM_SUCCESS(rv)) { 225 rv = MAC_CONTROL_SET(macd, unit, port, SOC_MAC_CONTROL_EGRESS_DRAIN, 1); 226 227 } 228 PORT_UNLOCK(unit); 229 return rv; 230 } 231 232 /* 233 * Function : _bcm_th_port_speed_supported 234 * Description : Helper function for bcm_esw_port_speed_set, used 235 * to determine whether a requested speed can be 236 * supported by the current port lane config 237 * Parameters : 238 * unit (IN) 239 * port (IN) 240 * speed (IN) 241 * supported (OUT) 242 * Returns : BCM_E_XXX 243 * Note : Caller needs to ensure soc_feature_flexport_based_speed_set 244 * is defined 245 */ 246 bcm_error_t 247 _bcm_th_port_speed_supported(int unit, bcm_port_t port, int speed) 248 { 249 SOC_IF_ERROR_RETURN(soc_th_port_speed_supported(unit, port, speed)); 250 return BCM_E_NONE; 251 } 252 253 int bcm_th_phy_lb_check(int unit, bcm_port_t port, int loopback) { 254 uint16 dev_id = 0; 255 uint8 rev_id = 0; 256 soc_cm_get_id(unit, &dev_id, &rev_id); 257 if ((BCM56963_DEVICE_ID == dev_id) || (BCM56967_DEVICE_ID == dev_id)) { 258 if(SOC_PBMP_MEMBER(loopback_disable[unit], port)) { 259 if(loopback != BCM_PORT_LOOPBACK_PHY) { 260 return BCM_E_UNAVAIL; 261 } 262 } 263 } 264 return BCM_E_NONE; 265 } 266 267 int bcm_th_phy_lb_set(int unit) { 268 uint16 dev_id = 0; 269 uint8 rev_id = 0; 270 int port; 271 soc_cm_get_id(unit, &dev_id, &rev_id); 272 if ((BCM56963_DEVICE_ID == dev_id) || (BCM56967_DEVICE_ID == dev_id)){ 273 PBMP_ITER(loopback_disable[unit], port) { 274 BCM_IF_ERROR_RETURN 275 (bcm_esw_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_PHY)); 276 } 277 } 278 return BCM_E_NONE; 279 } 280 281 282 #endif /* BCM_TOMAHAWK_SUPPORT */