preemption.c (7378B)
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 #include <soc/drv.h> 8 #include <soc/greyhound2.h> 9 #include <bcm/error.h> 10 #include <bcm/types.h> 11 #include <shared/bsl.h> 12 #include <bcm_int/esw_dispatch.h> 13 14 #if defined(BCM_GREYHOUND2_SUPPORT) 15 STATIC int 16 bcmi_gh2_preemption_port_check(int unit, bcm_port_t port) 17 { 18 if (!IS_XL_PORT(unit, port) && !IS_GE_PORT(unit, port)) { 19 return BCM_E_UNAVAIL; 20 } else { 21 return BCM_E_NONE; 22 } 23 } 24 25 int 26 bcmi_gh2_preemption_capability_set(int unit, bcm_port_t port, 27 uint32 arg) 28 { 29 soc_info_t *si = &SOC_INFO(unit); 30 int phy_port = si->port_l2p_mapping[port]; 31 int link_up; 32 33 BCM_IF_ERROR_RETURN( 34 bcm_esw_port_link_status_get(unit, port, &link_up)); 35 if (1 == link_up) { 36 LOG_ERROR(BSL_LS_BCMAPI_PORT, 37 (BSL_META_U(unit, 38 "This needs to be setup during link down\n"))); 39 return BCM_E_CONFIG; 40 } 41 42 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 43 BCM_IF_ERROR_RETURN( 44 soc_reg_field32_modify(unit, 45 MMU_PORT_PREEMPTION_CONFIGr, 46 port, 47 PREEMPTION_MODEf, 48 arg ? 1 : 0)); 49 BCM_IF_ERROR_RETURN( 50 soc_mem_field32_modify(unit, 51 EGR_EDB_XMIT_CTRLm, 52 phy_port, 53 EP_PORT_PORT_PREEMPT_MODEf, 54 arg ? 1 : 0)); 55 return BCM_E_NONE; 56 } 57 58 int 59 bcmi_gh2_preemption_queue_bitmap_set(int unit, bcm_port_t port, 60 uint32 arg) 61 { 62 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 63 BCM_IF_ERROR_RETURN( 64 soc_reg_field_validate(unit, 65 MMU_PORT_PREEMPTION_CONFIGr, 66 PREEMPTION_Q_BITMAPf, 67 arg)); 68 BCM_IF_ERROR_RETURN( 69 soc_reg_field32_modify(unit, 70 MMU_PORT_PREEMPTION_CONFIGr, 71 port, 72 PREEMPTION_Q_BITMAPf, 73 arg)); 74 return BCM_E_NONE; 75 } 76 77 int 78 bcmi_gh2_preemption_hold_request_mode_set(int unit, bcm_port_t port, 79 uint32 arg) 80 { 81 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 82 BCM_IF_ERROR_RETURN( 83 soc_reg_field32_modify(unit, 84 MMU_PORT_PREEMPTION_CONFIGr, 85 port, 86 HOLD_REQ_CNT_MODEf, 87 arg ? 1 : 0)); 88 return BCM_E_NONE; 89 } 90 91 int 92 bcmi_gh2_preemption_frag_config_tx_set(int unit, bcm_port_t port, 93 int is_final, 94 uint32 value) 95 { 96 uint32 hw_value; 97 soc_info_t *si = &SOC_INFO(unit); 98 int phy_port = si->port_l2p_mapping[port]; 99 100 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 101 102 if(value > 512 || value < 64) { 103 return BCM_E_PARAM; 104 } 105 if (IS_GE_PORT(unit, port)) { 106 if (value % 16) { 107 return BCM_E_PARAM; 108 } 109 } else if (IS_XL_PORT(unit, port)) { 110 if (value % 32) { 111 return BCM_E_PARAM; 112 } 113 } else { 114 return BCM_E_INTERNAL; /* should not happen */ 115 } 116 117 if (512 == value) { 118 /* The size for is max(32N, hw_value*4) 119 * because the there is only 7 bits in hw_value 120 * set hw_value to 127 for the size 512 121 */ 122 hw_value = 127; 123 } else { 124 hw_value = value / 4; 125 } 126 return soc_mem_field32_modify(unit, EGR_EDB_XMIT_CTRLm, phy_port, 127 (is_final ? MIN_FINAL_FRAG_SIZEf: 128 MIN_NON_FINAL_FRAG_SIZEf), 129 hw_value); 130 } 131 132 133 int 134 bcmi_gh2_preemption_capability_get(int unit, bcm_port_t port, 135 uint32* arg) 136 { 137 uint32 regval; 138 139 if (NULL == arg) { 140 return SOC_E_PARAM; 141 } 142 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 143 BCM_IF_ERROR_RETURN( 144 READ_MMU_PORT_PREEMPTION_CONFIGr(unit, port, 145 ®val)); 146 *arg = soc_reg_field_get(unit, 147 MMU_PORT_PREEMPTION_CONFIGr, 148 regval, PREEMPTION_MODEf); 149 return BCM_E_NONE; 150 } 151 152 int 153 bcmi_gh2_preemption_queue_bitmap_get(int unit, bcm_port_t port, 154 uint32* arg) 155 { 156 uint32 regval; 157 158 if (NULL == arg) { 159 return SOC_E_PARAM; 160 } 161 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 162 BCM_IF_ERROR_RETURN( 163 READ_MMU_PORT_PREEMPTION_CONFIGr(unit, port, 164 ®val)); 165 *arg = soc_reg_field_get(unit, 166 MMU_PORT_PREEMPTION_CONFIGr, 167 regval, PREEMPTION_Q_BITMAPf); 168 return BCM_E_NONE; 169 } 170 171 int 172 bcmi_gh2_preemption_hold_request_mode_get(int unit, bcm_port_t port, 173 uint32* arg) 174 { 175 uint32 regval; 176 177 if (NULL == arg) { 178 return SOC_E_PARAM; 179 } 180 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 181 BCM_IF_ERROR_RETURN( 182 READ_MMU_PORT_PREEMPTION_CONFIGr(unit, port, 183 ®val)); 184 *arg = soc_reg_field_get(unit, 185 MMU_PORT_PREEMPTION_CONFIGr, 186 regval, HOLD_REQ_CNT_MODEf); 187 return BCM_E_NONE; 188 } 189 190 int 191 bcmi_gh2_preemption_frag_config_tx_get(int unit, bcm_port_t port, 192 int is_final, 193 uint32* value) 194 { 195 egr_edb_xmit_ctrl_entry_t entry; 196 soc_info_t *si = &SOC_INFO(unit); 197 int phy_port = si->port_l2p_mapping[port]; 198 uint32 hw_value, remainder, base; 199 200 if (NULL == value) { 201 return SOC_E_PARAM; 202 } 203 204 BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port)); 205 BCM_IF_ERROR_RETURN( 206 soc_mem_read(unit, EGR_EDB_XMIT_CTRLm, MEM_BLOCK_ANY, 207 phy_port, &entry)); 208 if (IS_GE_PORT(unit, port)) { 209 base = 16; 210 } else if (IS_XL_PORT(unit, port)) { 211 base = 32; 212 } else { 213 return BCM_E_INTERNAL; /* should not happen */ 214 } 215 216 /* For GE port : 217 * size is the max(16N, hw_value*4), 218 * so need to round up as multiple of 16 219 * For XL port : 220 * size is the max(32N, hw_value*4), 221 * so need to round up as multiple of 32 222 */ 223 hw_value = soc_mem_field32_get(unit, 224 EGR_EDB_XMIT_CTRLm, 225 &entry, 226 (is_final ? MIN_FINAL_FRAG_SIZEf: 227 MIN_NON_FINAL_FRAG_SIZEf)); 228 229 remainder = (hw_value * 4) % base; 230 if (remainder == 0) { 231 *value = hw_value * 4; 232 } else { 233 *value = (hw_value * 4) + base - remainder; 234 } 235 236 return BCM_E_NONE; 237 } 238 #endif /* BCM_GREYHOUND2_SUPPORT */