l3.c (99611B)
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: l3.c 8 * Purpose: Tomahawk3 L3 function implementations 9 */ 10 11 #include <soc/defs.h> 12 #include <shared/bsl.h> 13 #if defined(INCLUDE_L3) && defined(BCM_TOMAHAWK3_SUPPORT) 14 #include <soc/drv.h> 15 #include <soc/tomahawk2.h> 16 #include <soc/profile_mem.h> 17 18 #include <bcm/vlan.h> 19 #include <bcm/error.h> 20 #include <bcm/l3.h> 21 #include <bcm/debug.h> 22 #include <bcm/error.h> 23 #include <bcm/stack.h> 24 25 #include <bcm_int/esw/firebolt.h> 26 #include <bcm_int/esw/stack.h> 27 #include <bcm_int/esw_dispatch.h> 28 #include <bcm_int/esw/tomahawk2.h> 29 #include <bcm_int/esw/tomahawk3.h> 30 31 #define WRITE_DLB_MEMBER_PORT_0_15(_unit, _i, _port_ent, _val, _intf_count) {\ 32 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, \ 33 _port_ent,\ 34 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 35 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, \ 36 _port_ent,\ 37 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 38 } 39 40 #define WRITE_DLB_MEMBER_PORT_16_31(_unit, _i, _port_ent, _val, _intf_count) {\ 41 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, \ 42 _port_ent, \ 43 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 44 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, \ 45 _port_ent, \ 46 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 47 } 48 49 #define WRITE_DLB_MEMBER_PORT_32_47(_unit, _i, _port_ent, _val, _intf_count) {\ 50 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, \ 51 _port_ent, \ 52 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 53 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, \ 54 _port_ent, \ 55 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 56 } 57 58 #define WRITE_DLB_MEMBER_PORT_48_63(_unit, _i, _port_ent, _val, _intf_count) {\ 59 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, \ 60 _port_ent, \ 61 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 62 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, \ 63 _port_ent, \ 64 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 65 } 66 67 #define WRITE_DLB_MEMBER_NHI_0_12(_unit, _i, _nhi_ent, _val, _intf_count) { \ 68 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent, \ 69 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 70 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent, \ 71 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 72 } 73 74 #define WRITE_DLB_MEMBER_NHI_13_25(_unit, _i, _nhi_ent, _val, _intf_count) { \ 75 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\ 76 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 77 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\ 78 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 79 } 80 81 #define WRITE_DLB_MEMBER_NHI_26_38(_unit, _i, _nhi_ent, _val, _intf_count) { \ 82 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\ 83 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 84 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\ 85 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 86 } 87 88 #define WRITE_DLB_MEMBER_NHI_39_51(_unit, _i, _nhi_ent, _val, _intf_count) { \ 89 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\ 90 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 91 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\ 92 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 93 } 94 95 #define WRITE_DLB_MEMBER_NHI_52_63(_unit, _i, _nhi_ent, _val, _intf_count) { \ 96 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\ 97 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 98 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\ 99 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 100 } 101 102 #define READ_DLB_MEMBER_PORT_0_15(_unit, _i, _port_ent, _val) {\ 103 _val = 0; \ 104 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, _port_ent,\ 105 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 106 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, _port_ent,\ 107 MEMBER_ ## _i ## _PORTf); \ 108 } \ 109 } 110 111 #define READ_DLB_MEMBER_PORT_16_31(_unit, _i, _port_ent, _val) {\ 112 _val = 0; \ 113 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, _port_ent,\ 114 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 115 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, _port_ent,\ 116 MEMBER_ ## _i ## _PORTf); \ 117 } \ 118 } 119 120 #define READ_DLB_MEMBER_PORT_32_47(_unit, _i, _port_ent, _val) {\ 121 _val = 0; \ 122 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, _port_ent,\ 123 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 124 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, _port_ent,\ 125 MEMBER_ ## _i ## _PORTf); \ 126 } \ 127 } 128 129 #define READ_DLB_MEMBER_PORT_48_63(_unit, _i, _port_ent, _val) {\ 130 _val = 0; \ 131 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, _port_ent,\ 132 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 133 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, _port_ent,\ 134 MEMBER_ ## _i ## _PORTf); \ 135 } \ 136 } 137 138 #define READ_DLB_MEMBER_ALT_PORT_0_15(_unit, _i, _port_ent, _val) {\ 139 _val = 0; \ 140 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, _port_ent,\ 141 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 142 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, _port_ent,\ 143 MEMBER_ ## _i ## _PORTf); \ 144 } \ 145 } 146 147 #define READ_DLB_MEMBER_ALT_PORT_16_31(_unit, _i, _port_ent, _val) {\ 148 _val = 0; \ 149 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, _port_ent,\ 150 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 151 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, _port_ent,\ 152 MEMBER_ ## _i ## _PORTf); \ 153 } \ 154 } 155 156 #define READ_DLB_MEMBER_ALT_PORT_32_47(_unit, _i, _port_ent, _val) {\ 157 _val = 0; \ 158 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, _port_ent,\ 159 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 160 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, _port_ent,\ 161 MEMBER_ ## _i ## _PORTf); \ 162 } \ 163 } 164 165 #define READ_DLB_MEMBER_ALT_PORT_48_63(_unit, _i, _port_ent, _val) {\ 166 _val = 0; \ 167 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, _port_ent,\ 168 MEMBER_ ## _i ## _PORT_VALIDf)) { \ 169 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, _port_ent,\ 170 MEMBER_ ## _i ## _PORTf); \ 171 } \ 172 } 173 174 #define READ_DLB_MEMBER_NHI_0_12(_unit, _i, _nhi_ent, _val) { \ 175 _val = 0; \ 176 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent,\ 177 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 178 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent,\ 179 MEMBER_ ## _i ## _NHIf); \ 180 } \ 181 } 182 183 #define READ_DLB_MEMBER_NHI_13_25(_unit, _i, _nhi_ent, _val) { \ 184 _val = 0; \ 185 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\ 186 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 187 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\ 188 MEMBER_ ## _i ## _NHIf); \ 189 } \ 190 } 191 192 #define READ_DLB_MEMBER_NHI_26_38(_unit, _i, _nhi_ent, _val) { \ 193 _val = 0; \ 194 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\ 195 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 196 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\ 197 MEMBER_ ## _i ## _NHIf); \ 198 } \ 199 } 200 201 #define READ_DLB_MEMBER_NHI_39_51(_unit, _i, _nhi_ent, _val) { \ 202 _val = 0; \ 203 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\ 204 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 205 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\ 206 MEMBER_ ## _i ## _NHIf); \ 207 } \ 208 } 209 210 #define READ_DLB_MEMBER_NHI_52_63(_unit, _i, _nhi_ent, _val) { \ 211 _val = 0; \ 212 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\ 213 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 214 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\ 215 MEMBER_ ## _i ## _NHIf); \ 216 } \ 217 } 218 219 #define READ_DLB_MEMBER_ALT_NHI_0_12(_unit, _i, _nhi_ent, _val) { \ 220 _val = 0; \ 221 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, _nhi_ent,\ 222 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 223 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, _nhi_ent,\ 224 MEMBER_ ## _i ## _NHIf); \ 225 } \ 226 } 227 228 #define READ_DLB_MEMBER_ALT_NHI_13_25(_unit, _i, _nhi_ent, _val) { \ 229 _val = 0; \ 230 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, _nhi_ent,\ 231 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 232 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, _nhi_ent,\ 233 MEMBER_ ## _i ## _NHIf); \ 234 } \ 235 } 236 237 #define READ_DLB_MEMBER_ALT_NHI_26_38(_unit, _i, _nhi_ent, _val) { \ 238 _val = 0; \ 239 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, _nhi_ent,\ 240 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 241 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, _nhi_ent,\ 242 MEMBER_ ## _i ## _NHIf); \ 243 } \ 244 } 245 246 #define READ_DLB_MEMBER_ALT_NHI_39_51(_unit, _i, _nhi_ent, _val) { \ 247 _val = 0; \ 248 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, _nhi_ent,\ 249 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 250 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, _nhi_ent,\ 251 MEMBER_ ## _i ## _NHIf); \ 252 } \ 253 } 254 255 #define READ_DLB_MEMBER_ALT_NHI_52_63(_unit, _i, _nhi_ent, _val) { \ 256 _val = 0; \ 257 if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, _nhi_ent,\ 258 MEMBER_ ## _i ## _NHI_VALIDf)) { \ 259 _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, _nhi_ent,\ 260 MEMBER_ ## _i ## _NHIf); \ 261 } \ 262 } 263 264 265 #define WRITE_DLB_MEMBER_ALT_PORT_0_15(_unit, _i, _port_ent, _val, \ 266 _intf_count) { \ 267 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, \ 268 _port_ent, \ 269 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 270 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, \ 271 _port_ent, \ 272 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 273 } 274 275 #define WRITE_DLB_MEMBER_ALT_PORT_16_31(_unit, _i, _port_ent, _val, \ 276 _intf_count) { \ 277 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, \ 278 _port_ent, \ 279 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 280 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, \ 281 _port_ent, \ 282 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 283 } 284 285 #define WRITE_DLB_MEMBER_ALT_PORT_32_47(_unit, _i, _port_ent, _val, \ 286 _intf_count) { \ 287 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, \ 288 _port_ent, \ 289 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 290 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, \ 291 _port_ent, \ 292 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 293 } 294 295 #define WRITE_DLB_MEMBER_ALT_PORT_48_63(_unit, _i, _port_ent, _val, \ 296 _intf_count) { \ 297 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, \ 298 _port_ent, \ 299 MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \ 300 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, \ 301 _port_ent, \ 302 MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \ 303 } 304 305 #define WRITE_DLB_MEMBER_ALT_NHI_0_12(_unit, _i, _nhi_ent, _val, \ 306 _intf_count) { \ 307 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, \ 308 _nhi_ent, \ 309 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 310 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, \ 311 _nhi_ent, \ 312 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 313 } 314 315 #define WRITE_DLB_MEMBER_ALT_NHI_13_25(_unit, _i, _nhi_ent, _val, \ 316 _intf_count) { \ 317 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, \ 318 _nhi_ent, \ 319 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 320 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, \ 321 _nhi_ent, \ 322 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 323 } 324 325 #define WRITE_DLB_MEMBER_ALT_NHI_26_38(_unit, _i, _nhi_ent, _val, \ 326 _intf_count) { \ 327 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, \ 328 _nhi_ent, \ 329 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 330 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, \ 331 _nhi_ent, \ 332 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 333 } 334 335 #define WRITE_DLB_MEMBER_ALT_NHI_39_51(_unit, _i, _nhi_ent, _val, \ 336 _intf_count) { \ 337 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, \ 338 _nhi_ent, \ 339 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 340 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, \ 341 _nhi_ent, \ 342 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 343 } 344 345 #define WRITE_DLB_MEMBER_ALT_NHI_52_63(_unit, _i, _nhi_ent, _val, \ 346 _intf_count) { \ 347 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, \ 348 _nhi_ent, \ 349 MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \ 350 soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, \ 351 _nhi_ent, \ 352 MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \ 353 } 354 355 #define _DLB_SET_GROUP_PTR_0_12(_M_) {\ 356 int port_index = 0; \ 357 READ_DLB_MEMBER_NHI_0_12(unit, _M_, dlb_nhi_members.entry_data, nh_index); \ 358 if (nh_index) { \ 359 READ_DLB_MEMBER_PORT_0_15(unit, _M_, dlb_port_members.entry_data, port_index); \ 360 if (port_index) {\ 361 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 362 } \ 363 } \ 364 READ_DLB_MEMBER_ALT_NHI_0_12(unit, _M_, dlb_alt_nhi_members.entry_data, nh_index); \ 365 if (nh_index) { \ 366 READ_DLB_MEMBER_ALT_PORT_0_15(unit, _M_, dlb_alt_port_members.entry_data, port_index); \ 367 if (port_index) { \ 368 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 369 } \ 370 } \ 371 } 372 373 #define _DLB_SET_GROUP_PTR_13_25(_M_) {\ 374 int port_index = 0; \ 375 READ_DLB_MEMBER_NHI_13_25(unit, _M_, dlb_nhi_members_13.entry_data, nh_index); \ 376 if (nh_index) { \ 377 if (_M_ <= 15) { \ 378 READ_DLB_MEMBER_PORT_0_15(unit, _M_, dlb_port_members.entry_data, port_index); \ 379 } else { \ 380 READ_DLB_MEMBER_PORT_16_31(unit, _M_, dlb_port_members_16.entry_data, port_index); \ 381 } \ 382 if (port_index) {\ 383 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 384 } \ 385 } \ 386 READ_DLB_MEMBER_ALT_NHI_13_25(unit, _M_, dlb_alt_nhi_members_13.entry_data, nh_index); \ 387 if (nh_index) { \ 388 if (_M_ <= 15) { \ 389 READ_DLB_MEMBER_ALT_PORT_0_15(unit, _M_, dlb_alt_port_members.entry_data, port_index); \ 390 } else { \ 391 READ_DLB_MEMBER_ALT_PORT_16_31(unit, _M_, dlb_alt_port_members_16.entry_data, port_index); \ 392 } \ 393 if (port_index) {\ 394 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 395 } \ 396 } \ 397 } 398 399 400 #define _DLB_SET_GROUP_PTR_26_38(_M_) {\ 401 int port_index = 0; \ 402 READ_DLB_MEMBER_NHI_26_38(unit, _M_, dlb_nhi_members_26.entry_data, nh_index); \ 403 if (nh_index) { \ 404 if (_M_ <= 31) { \ 405 READ_DLB_MEMBER_PORT_16_31(unit, _M_, dlb_port_members_16.entry_data, port_index); \ 406 } else { \ 407 READ_DLB_MEMBER_PORT_32_47(unit, _M_, dlb_port_members_32.entry_data, port_index); \ 408 } \ 409 if (port_index) {\ 410 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 411 } \ 412 } \ 413 READ_DLB_MEMBER_ALT_NHI_26_38(unit, _M_, dlb_alt_nhi_members_26.entry_data, nh_index); \ 414 if (nh_index) { \ 415 if (_M_ <= 31) { \ 416 READ_DLB_MEMBER_ALT_PORT_16_31(unit, _M_, dlb_alt_port_members_16.entry_data, port_index); \ 417 } else { \ 418 READ_DLB_MEMBER_ALT_PORT_32_47(unit, _M_, dlb_alt_port_members_32.entry_data, port_index); \ 419 } \ 420 if (port_index) {\ 421 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 422 } \ 423 } \ 424 } 425 426 427 #define _DLB_SET_GROUP_PTR_39_51(_M_) {\ 428 int port_index = 0; \ 429 READ_DLB_MEMBER_NHI_39_51(unit, _M_, dlb_nhi_members_39.entry_data, nh_index); \ 430 if (nh_index) { \ 431 if (_M_ <= 47) { \ 432 READ_DLB_MEMBER_PORT_32_47(unit, _M_, dlb_port_members_32.entry_data, port_index); \ 433 } else { \ 434 READ_DLB_MEMBER_PORT_48_63(unit, _M_, dlb_port_members_48.entry_data, port_index); \ 435 } \ 436 if (port_index) {\ 437 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 438 } \ 439 } \ 440 READ_DLB_MEMBER_ALT_NHI_39_51(unit, _M_, dlb_alt_nhi_members_39.entry_data, nh_index); \ 441 if (nh_index) { \ 442 if (_M_ <= 47) { \ 443 READ_DLB_MEMBER_ALT_PORT_32_47(unit, _M_, dlb_alt_port_members_32.entry_data, port_index); \ 444 } else { \ 445 READ_DLB_MEMBER_ALT_PORT_48_63(unit, _M_, dlb_alt_port_members_48.entry_data, port_index); \ 446 } \ 447 if (port_index) {\ 448 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 449 } \ 450 } \ 451 } 452 453 454 #define _DLB_SET_GROUP_PTR_52_63(_M_) {\ 455 int port_index = 0; \ 456 READ_DLB_MEMBER_NHI_52_63(unit, _M_, dlb_nhi_members_52.entry_data, nh_index); \ 457 if (nh_index) { \ 458 READ_DLB_MEMBER_PORT_48_63(unit, _M_, dlb_port_members_48.entry_data, port_index); \ 459 if (port_index) {\ 460 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 461 } \ 462 } \ 463 READ_DLB_MEMBER_ALT_NHI_52_63(unit, _M_, dlb_alt_nhi_members_52.entry_data, nh_index); \ 464 if (nh_index) { \ 465 READ_DLB_MEMBER_ALT_PORT_48_63(unit, _M_, dlb_alt_port_members_48.entry_data, port_index); \ 466 if (port_index) {\ 467 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \ 468 } \ 469 } \ 470 } 471 472 #define ECMP_DLB_INFO(_unit_) (_th2_ecmp_dlb_bk[_unit_]) 473 #define ECMP_DLB_PORT_INFO(_unit_, _idx_) \ 474 (_th2_ecmp_dlb_bk[_unit_]->ecmp_dlb_port_info[_idx_]) 475 #define ECMP_DLB_PORT_LIST(_unit_, _idx_) \ 476 ECMP_DLB_PORT_INFO(unit, _idx_).port_membership_list 477 478 #define _BCM_ECMP_DLB_FLOWSET_BLOCK_SIZE_SHIFT 8 479 #define _BCM_ECMP_DLB_FLOWSET_BLOCK_TEST_RANGE(_u_, _idx_, _count_, _result_) \ 480 SHR_BITTEST_RANGE(ECMP_DLB_INFO(_u_)->ecmp_dlb_flowset_block_bitmap, _idx_, _count_, _result_) 481 482 extern _th2_ecmp_dlb_bookkeeping_t *_th2_ecmp_dlb_bk[BCM_MAX_NUM_UNITS]; 483 484 /* 485 * Function: 486 * _bcm_th3_l3_ecmp_dlb_port_get 487 * Purpose: 488 * Get ports for each ECMP member. 489 * Parameters: 490 * unit - (IN) SOC unit number. 491 * ecmp - (IN) ECMP group info. 492 * dlb_id - (IN) DLB group ID. 493 * primary_count - (IN) ECMP primary count.. 494 * intf_count - (IN) Number of elements in intf_array. 495 * intf_array - (IN) Array of Egress forwarding objects. 496 * port_array - (OUT) Array of ports. 497 * ecmp_member_bitmap - (IN) ECMP DLB members. 498 * Returns: 499 * BCM_E_xxx 500 */ 501 int 502 _bcm_th3_l3_ecmp_dlb_port_get(int unit, bcm_l3_egress_ecmp_t *ecmp, 503 int dlb_id, int primary_count, int intf_count, 504 bcm_if_t *intf_array, int *port_array) 505 { 506 int rv = BCM_E_NONE; 507 int i; 508 ing_l3_next_hop_entry_t ing_nh_entry; 509 int port; 510 int nh_index; 511 512 for (i = 0; i < intf_count; i++) { 513 514 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, intf_array[i])) { 515 nh_index = intf_array[i] - BCM_XGS3_EGRESS_IDX_MIN(unit); 516 } else { 517 return BCM_E_PARAM; 518 } 519 520 /* Derive port from nh_index */ 521 rv = (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, 522 nh_index, &ing_nh_entry)); 523 if (BCM_FAILURE(rv)) { 524 return rv; 525 } 526 if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, Tf)) { 527 /* Next hop should correspond to a single physical port. */ 528 return BCM_E_CONFIG; 529 } 530 port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, 531 PORT_NUMf); 532 port_array[i] = port; 533 } 534 return rv; 535 } 536 /* 537 * Function: 538 * bcm_th3_l3_egress_ecmp_dlb_resource_validate 539 * Purpose: 540 * Checks for free resources for the Replace operation. Also, 541 * checks for the contiguous space based on the number of blocks 542 * used for the replacement ecmp dlb group. 543 * Parameters: 544 * unit - (IN) bcm device. 545 * ecmp - (IN) ECMP group info. 546 * dlb_id - (IN) ECMP DLB id. 547 * Returns: 548 * BCM_E_XXX 549 */ 550 int _bcm_th3_l3_egress_ecmp_dlb_resource_validate(int unit, bcm_l3_egress_ecmp_t *ecmp, 551 int dlb_id) 552 { 553 bcm_l3_egress_ecmp_t dlb_ecmp; 554 int dlb_ecmp_count = 0; 555 int num_blocks; 556 int block_base_ptr; 557 int occupied; 558 int total_blocks; 559 int max_block_base_ptr; 560 561 bcm_l3_egress_ecmp_t_init(&dlb_ecmp); 562 dlb_ecmp.ecmp_intf = ecmp->ecmp_intf; 563 BCM_IF_ERROR_RETURN( 564 _bcm_esw_l3_egress_ecmp_get(unit, &dlb_ecmp, 0, NULL, 565 &dlb_ecmp_count, TRUE)); 566 567 num_blocks = ecmp->dynamic_size >> _BCM_ECMP_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 568 total_blocks = soc_mem_index_count(unit, DLB_ECMP_FLOWSETm) >> 569 _BCM_ECMP_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 570 max_block_base_ptr = total_blocks - num_blocks; 571 572 /* Check if a free contiguous region of flow set table exists 573 * starting from (dlb_id+1) to (block_base_ptr + num_blocks - 1). 574 */ 575 for (block_base_ptr = dlb_id + 1; 576 block_base_ptr <= max_block_base_ptr; 577 block_base_ptr++) { 578 _BCM_ECMP_DLB_FLOWSET_BLOCK_TEST_RANGE(unit, block_base_ptr, num_blocks, 579 occupied); 580 if (!occupied) { 581 break; 582 } 583 } 584 if (block_base_ptr > max_block_base_ptr) { 585 /* A contiguous region of the desired size could not be found in 586 * flow set table. 587 */ 588 return BCM_E_RESOURCE; 589 } 590 591 return BCM_E_NONE; 592 } 593 594 /* 595 * Function: 596 * _bcm_th3_l3_ecmp_dlb_get_id 597 * Purpose: 598 * Get ECMP dlb id from ecmp group. 599 * Parameters: 600 * unit - (IN) SOC unit number. 601 * ecmp_grp_idx - (IN) ECMP group index. 602 * -1: free all DLB resources, 603 * others: will not disable DLB and free flowset. 604 * Returns: 605 * dlb_id - DLB group id. 606 */ 607 int 608 _bcm_th3_l3_ecmp_dlb_get_id(int unit, int ecmp_grp_idx) 609 { 610 int dlb_id = 0; 611 dlb_id = ecmp_grp_idx - BCM_TH3_L3_ECMP_DLB_START(unit); 612 613 return dlb_id; 614 } 615 616 /* 617 * Function: 618 * _bcm_th2_ecmp_dlb_port_member_set 619 * Purpose: 620 * Set dlb port numbers corresponding to each ecmp member NH. 621 * Parameters: 622 * unit - (IN) SOC unit number. 623 * port_array - (IN) port array for each NH. 624 * intf_count - (IN) INTF count. 625 * primary_count - (IN) Primary INTF count. 626 * dlb_id - (IN) DLB group id. 627 * Returns: 628 * BCM_E_xxx 629 */ 630 int 631 _bcm_th3_l3_ecmp_dlb_port_member_set(int unit, int *port_array, 632 int primary_count, int unique_intfs, int dlb_id) 633 { 634 int alt_nh_start; 635 int rv = BCM_E_NONE; 636 int alt_count = unique_intfs - primary_count; 637 638 dlb_ecmp_group_port_members_0_to_15_entry_t dlb_port_members; 639 dlb_ecmp_group_port_members_16_to_31_entry_t dlb_port_members_16; 640 dlb_ecmp_group_port_members_32_to_47_entry_t dlb_port_members_32; 641 dlb_ecmp_group_port_members_48_to_63_entry_t dlb_port_members_48; 642 dlb_ecmp_group_alt_port_members_0_to_15_entry_t dlb_alt_port_members; 643 dlb_ecmp_group_alt_port_members_16_to_31_entry_t dlb_alt_port_members_16; 644 dlb_ecmp_group_alt_port_members_32_to_47_entry_t dlb_alt_port_members_32; 645 dlb_ecmp_group_alt_port_members_48_to_63_entry_t dlb_alt_port_members_48; 646 647 sal_memset(&dlb_port_members, 0, 648 sizeof(dlb_ecmp_group_port_members_0_to_15_entry_t)); 649 sal_memset(&dlb_port_members_16, 0, 650 sizeof(dlb_ecmp_group_port_members_16_to_31_entry_t)); 651 sal_memset(&dlb_port_members_32, 0, 652 sizeof(dlb_ecmp_group_port_members_32_to_47_entry_t)); 653 sal_memset(&dlb_port_members_48, 0, 654 sizeof(dlb_ecmp_group_port_members_48_to_63_entry_t)); 655 WRITE_DLB_MEMBER_PORT_0_15(unit, 0, &dlb_port_members, 656 port_array[0], primary_count); 657 WRITE_DLB_MEMBER_PORT_0_15(unit, 1, &dlb_port_members, 658 port_array[1], primary_count); 659 WRITE_DLB_MEMBER_PORT_0_15(unit, 2, &dlb_port_members, 660 port_array[2], primary_count); 661 WRITE_DLB_MEMBER_PORT_0_15(unit, 3, &dlb_port_members, 662 port_array[3], primary_count); 663 WRITE_DLB_MEMBER_PORT_0_15(unit, 4, &dlb_port_members, 664 port_array[4], primary_count); 665 WRITE_DLB_MEMBER_PORT_0_15(unit, 5, &dlb_port_members, 666 port_array[5], primary_count); 667 WRITE_DLB_MEMBER_PORT_0_15(unit, 6, &dlb_port_members, 668 port_array[6], primary_count); 669 WRITE_DLB_MEMBER_PORT_0_15(unit, 7, &dlb_port_members, 670 port_array[7], primary_count); 671 WRITE_DLB_MEMBER_PORT_0_15(unit, 8, &dlb_port_members, 672 port_array[8], primary_count); 673 WRITE_DLB_MEMBER_PORT_0_15(unit, 9, &dlb_port_members, 674 port_array[9], primary_count); 675 WRITE_DLB_MEMBER_PORT_0_15(unit, 10, &dlb_port_members 676 , port_array[10], primary_count); 677 WRITE_DLB_MEMBER_PORT_0_15(unit, 11, &dlb_port_members, 678 port_array[11], primary_count); 679 WRITE_DLB_MEMBER_PORT_0_15(unit, 12, &dlb_port_members, 680 port_array[12], primary_count); 681 WRITE_DLB_MEMBER_PORT_0_15(unit, 13, &dlb_port_members, 682 port_array[13], primary_count); 683 WRITE_DLB_MEMBER_PORT_0_15(unit, 14, &dlb_port_members, 684 port_array[14], primary_count); 685 WRITE_DLB_MEMBER_PORT_0_15(unit, 15, &dlb_port_members, 686 port_array[15], primary_count); 687 rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, 688 MEM_BLOCK_ALL, (dlb_id), &dlb_port_members); 689 WRITE_DLB_MEMBER_PORT_16_31(unit, 16, &dlb_port_members_16, 690 port_array[16], primary_count); 691 WRITE_DLB_MEMBER_PORT_16_31(unit, 17, &dlb_port_members_16, 692 port_array[17], primary_count); 693 WRITE_DLB_MEMBER_PORT_16_31(unit, 18, &dlb_port_members_16, 694 port_array[18], primary_count); 695 WRITE_DLB_MEMBER_PORT_16_31(unit, 19, &dlb_port_members_16, 696 port_array[19], primary_count); 697 WRITE_DLB_MEMBER_PORT_16_31(unit, 20, &dlb_port_members_16, 698 port_array[20], primary_count); 699 WRITE_DLB_MEMBER_PORT_16_31(unit, 21, &dlb_port_members_16, 700 port_array[21], primary_count); 701 WRITE_DLB_MEMBER_PORT_16_31(unit, 22, &dlb_port_members_16, 702 port_array[22], primary_count); 703 WRITE_DLB_MEMBER_PORT_16_31(unit, 23, &dlb_port_members_16, 704 port_array[23], primary_count); 705 WRITE_DLB_MEMBER_PORT_16_31(unit, 24, &dlb_port_members_16, 706 port_array[24], primary_count); 707 WRITE_DLB_MEMBER_PORT_16_31(unit, 25, &dlb_port_members_16, 708 port_array[25], primary_count); 709 WRITE_DLB_MEMBER_PORT_16_31(unit, 26, &dlb_port_members_16, 710 port_array[26], primary_count); 711 WRITE_DLB_MEMBER_PORT_16_31(unit, 27, &dlb_port_members_16, 712 port_array[27], primary_count); 713 WRITE_DLB_MEMBER_PORT_16_31(unit, 28, &dlb_port_members_16, 714 port_array[28], primary_count); 715 WRITE_DLB_MEMBER_PORT_16_31(unit, 29, &dlb_port_members_16, 716 port_array[29], primary_count); 717 WRITE_DLB_MEMBER_PORT_16_31(unit, 30, &dlb_port_members_16, 718 port_array[30], primary_count); 719 WRITE_DLB_MEMBER_PORT_16_31(unit, 31, &dlb_port_members_16, 720 port_array[31], primary_count); 721 rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, 722 MEM_BLOCK_ALL, (dlb_id), &dlb_port_members_16); 723 WRITE_DLB_MEMBER_PORT_32_47(unit, 32, &dlb_port_members_32, 724 port_array[32], primary_count); 725 WRITE_DLB_MEMBER_PORT_32_47(unit, 33, &dlb_port_members_32, 726 port_array[33], primary_count); 727 WRITE_DLB_MEMBER_PORT_32_47(unit, 34, &dlb_port_members_32, 728 port_array[34], primary_count); 729 WRITE_DLB_MEMBER_PORT_32_47(unit, 35, &dlb_port_members_32, 730 port_array[35], primary_count); 731 WRITE_DLB_MEMBER_PORT_32_47(unit, 36, &dlb_port_members_32, 732 port_array[36], primary_count); 733 WRITE_DLB_MEMBER_PORT_32_47(unit, 37, &dlb_port_members_32, 734 port_array[37], primary_count); 735 WRITE_DLB_MEMBER_PORT_32_47(unit, 38, &dlb_port_members_32, 736 port_array[38], primary_count); 737 WRITE_DLB_MEMBER_PORT_32_47(unit, 39, &dlb_port_members_32, 738 port_array[39], primary_count); 739 WRITE_DLB_MEMBER_PORT_32_47(unit, 40, &dlb_port_members_32, 740 port_array[40], primary_count); 741 WRITE_DLB_MEMBER_PORT_32_47(unit, 41, &dlb_port_members_32, 742 port_array[41], primary_count); 743 WRITE_DLB_MEMBER_PORT_32_47(unit, 42, &dlb_port_members_32, 744 port_array[42], primary_count); 745 WRITE_DLB_MEMBER_PORT_32_47(unit, 43, &dlb_port_members_32, 746 port_array[43], primary_count); 747 WRITE_DLB_MEMBER_PORT_32_47(unit, 44, &dlb_port_members_32, 748 port_array[44], primary_count); 749 WRITE_DLB_MEMBER_PORT_32_47(unit, 45, &dlb_port_members_32, 750 port_array[45], primary_count); 751 WRITE_DLB_MEMBER_PORT_32_47(unit, 46, &dlb_port_members_32, 752 port_array[46], primary_count); 753 WRITE_DLB_MEMBER_PORT_32_47(unit, 47, &dlb_port_members_32, 754 port_array[47], primary_count); 755 rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, 756 MEM_BLOCK_ALL, (dlb_id), &dlb_port_members_32); 757 WRITE_DLB_MEMBER_PORT_48_63(unit, 48, &dlb_port_members_48, 758 port_array[48], primary_count); 759 WRITE_DLB_MEMBER_PORT_48_63(unit, 49, &dlb_port_members_48, 760 port_array[49], primary_count); 761 WRITE_DLB_MEMBER_PORT_48_63(unit, 50, &dlb_port_members_48, 762 port_array[50], primary_count); 763 WRITE_DLB_MEMBER_PORT_48_63(unit, 51, &dlb_port_members_48, 764 port_array[51], primary_count); 765 WRITE_DLB_MEMBER_PORT_48_63(unit, 52, &dlb_port_members_48, 766 port_array[52], primary_count); 767 WRITE_DLB_MEMBER_PORT_48_63(unit, 53, &dlb_port_members_48, 768 port_array[53], primary_count); 769 WRITE_DLB_MEMBER_PORT_48_63(unit, 54, &dlb_port_members_48, 770 port_array[54], primary_count); 771 WRITE_DLB_MEMBER_PORT_48_63(unit, 55, &dlb_port_members_48, 772 port_array[55], primary_count); 773 WRITE_DLB_MEMBER_PORT_48_63(unit, 56, &dlb_port_members_48, 774 port_array[56], primary_count); 775 WRITE_DLB_MEMBER_PORT_48_63(unit, 57, &dlb_port_members_48, 776 port_array[57], primary_count); 777 WRITE_DLB_MEMBER_PORT_48_63(unit, 58, &dlb_port_members_48, 778 port_array[58], primary_count); 779 WRITE_DLB_MEMBER_PORT_48_63(unit, 59, &dlb_port_members_48, 780 port_array[59], primary_count); 781 WRITE_DLB_MEMBER_PORT_48_63(unit, 60, &dlb_port_members_48, 782 port_array[60], primary_count); 783 WRITE_DLB_MEMBER_PORT_48_63(unit, 61, &dlb_port_members_48, 784 port_array[61], primary_count); 785 WRITE_DLB_MEMBER_PORT_48_63(unit, 62, &dlb_port_members_48, 786 port_array[62], primary_count); 787 WRITE_DLB_MEMBER_PORT_48_63(unit, 63, &dlb_port_members_48, 788 port_array[63], primary_count); 789 rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, 790 MEM_BLOCK_ALL, (dlb_id), &dlb_port_members_48); 791 if (alt_count <= 0) { 792 return rv; 793 } 794 alt_nh_start = primary_count; 795 sal_memset(&dlb_alt_port_members, 0, 796 sizeof(dlb_ecmp_group_alt_port_members_0_to_15_entry_t)); 797 sal_memset(&dlb_alt_port_members_16, 0, 798 sizeof(dlb_ecmp_group_alt_port_members_16_to_31_entry_t)); 799 sal_memset(&dlb_alt_port_members_32, 0, 800 sizeof(dlb_ecmp_group_alt_port_members_32_to_47_entry_t)); 801 sal_memset(&dlb_alt_port_members_48, 0, 802 sizeof(dlb_ecmp_group_alt_port_members_48_to_63_entry_t)); 803 804 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 0, &dlb_alt_port_members, 805 port_array[alt_nh_start], alt_count); 806 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 1, &dlb_alt_port_members, 807 port_array[alt_nh_start + 1], alt_count); 808 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 2, &dlb_alt_port_members, 809 port_array[alt_nh_start + 2], alt_count); 810 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 3, &dlb_alt_port_members, 811 port_array[alt_nh_start + 3], alt_count); 812 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 4, &dlb_alt_port_members, 813 port_array[alt_nh_start + 4], alt_count); 814 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 5, &dlb_alt_port_members, 815 port_array[alt_nh_start + 5], alt_count); 816 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 6, &dlb_alt_port_members, 817 port_array[alt_nh_start + 6], alt_count); 818 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 7, &dlb_alt_port_members, 819 port_array[alt_nh_start + 7], alt_count); 820 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 8, &dlb_alt_port_members, 821 port_array[alt_nh_start + 8], alt_count); 822 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 9, &dlb_alt_port_members, 823 port_array[alt_nh_start + 9], alt_count); 824 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 10, &dlb_alt_port_members, 825 port_array[alt_nh_start + 10], alt_count); 826 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 11, &dlb_alt_port_members, 827 port_array[alt_nh_start + 11], alt_count); 828 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 12, &dlb_alt_port_members, 829 port_array[alt_nh_start + 12], alt_count); 830 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 13, &dlb_alt_port_members, 831 port_array[alt_nh_start + 13], alt_count); 832 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 14, &dlb_alt_port_members, 833 port_array[alt_nh_start + 14], alt_count); 834 WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 15, &dlb_alt_port_members, 835 port_array[alt_nh_start + 15], alt_count); 836 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, 837 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members); 838 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 16, &dlb_alt_port_members_16, 839 port_array[alt_nh_start + 16], alt_count); 840 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 17, &dlb_alt_port_members_16, 841 port_array[alt_nh_start + 17], alt_count); 842 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 18, &dlb_alt_port_members_16, 843 port_array[alt_nh_start + 18], alt_count); 844 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 19, &dlb_alt_port_members_16, 845 port_array[alt_nh_start + 19], alt_count); 846 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 20, &dlb_alt_port_members_16, 847 port_array[alt_nh_start + 20], alt_count); 848 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 21, &dlb_alt_port_members_16, 849 port_array[alt_nh_start + 21], alt_count); 850 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 22, &dlb_alt_port_members_16, 851 port_array[alt_nh_start + 22], alt_count); 852 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 23, &dlb_alt_port_members_16, 853 port_array[alt_nh_start + 23], alt_count); 854 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 24, &dlb_alt_port_members_16, 855 port_array[alt_nh_start + 24], alt_count); 856 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 25, &dlb_alt_port_members_16, 857 port_array[alt_nh_start + 25], alt_count); 858 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 26, &dlb_alt_port_members_16, 859 port_array[alt_nh_start + 26], alt_count); 860 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 27, &dlb_alt_port_members_16, 861 port_array[alt_nh_start + 27], alt_count); 862 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 28, &dlb_alt_port_members_16, 863 port_array[alt_nh_start + 28], alt_count); 864 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 29, &dlb_alt_port_members_16, 865 port_array[alt_nh_start + 29], alt_count); 866 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 30, &dlb_alt_port_members_16, 867 port_array[alt_nh_start + 30], alt_count); 868 WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 31, &dlb_alt_port_members_16, 869 port_array[alt_nh_start + 31], alt_count); 870 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, 871 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members_16); 872 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 32, &dlb_alt_port_members_32, 873 port_array[alt_nh_start + 32], alt_count); 874 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 33, &dlb_alt_port_members_32, 875 port_array[alt_nh_start + 33], alt_count); 876 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 34, &dlb_alt_port_members_32, 877 port_array[alt_nh_start + 34], alt_count); 878 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 35, &dlb_alt_port_members_32, 879 port_array[alt_nh_start + 35], alt_count); 880 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 36, &dlb_alt_port_members_32, 881 port_array[alt_nh_start + 36], alt_count); 882 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 37, &dlb_alt_port_members_32, 883 port_array[alt_nh_start + 37], alt_count); 884 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 38, &dlb_alt_port_members_32, 885 port_array[alt_nh_start + 38], alt_count); 886 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 39, &dlb_alt_port_members_32, 887 port_array[alt_nh_start + 39], alt_count); 888 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 40, &dlb_alt_port_members_32, 889 port_array[alt_nh_start + 40], alt_count); 890 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 41, &dlb_alt_port_members_32, 891 port_array[alt_nh_start + 41], alt_count); 892 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 42, &dlb_alt_port_members_32, 893 port_array[alt_nh_start + 42], alt_count); 894 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 43, &dlb_alt_port_members_32, 895 port_array[alt_nh_start + 43], alt_count); 896 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 44, &dlb_alt_port_members_32, 897 port_array[alt_nh_start + 44], alt_count); 898 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 45, &dlb_alt_port_members_32, 899 port_array[alt_nh_start + 45], alt_count); 900 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 46, &dlb_alt_port_members_32, 901 port_array[alt_nh_start + 46], alt_count); 902 WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 47, &dlb_alt_port_members_32, 903 port_array[alt_nh_start + 47], alt_count); 904 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, 905 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members_32); 906 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 48, &dlb_alt_port_members_48, 907 port_array[alt_nh_start + 48], alt_count); 908 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 49, &dlb_alt_port_members_48, 909 port_array[alt_nh_start + 49], alt_count); 910 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 50, &dlb_alt_port_members_48, 911 port_array[alt_nh_start + 50], alt_count); 912 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 51, &dlb_alt_port_members_48, 913 port_array[alt_nh_start + 51], alt_count); 914 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 52, &dlb_alt_port_members_48, 915 port_array[alt_nh_start + 52], alt_count); 916 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 53, &dlb_alt_port_members_48, 917 port_array[alt_nh_start + 53], alt_count); 918 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 54, &dlb_alt_port_members_48, 919 port_array[alt_nh_start + 54], alt_count); 920 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 55, &dlb_alt_port_members_48, 921 port_array[alt_nh_start + 55], alt_count); 922 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 56, &dlb_alt_port_members_48, 923 port_array[alt_nh_start + 56], alt_count); 924 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 57, &dlb_alt_port_members_48, 925 port_array[alt_nh_start + 57], alt_count); 926 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 58, &dlb_alt_port_members_48, 927 port_array[alt_nh_start + 58], alt_count); 928 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 59, &dlb_alt_port_members_48, 929 port_array[alt_nh_start + 59], alt_count); 930 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 60, &dlb_alt_port_members_48, 931 port_array[alt_nh_start + 60], alt_count); 932 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 61, &dlb_alt_port_members_48, 933 port_array[alt_nh_start + 61], alt_count); 934 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 62, &dlb_alt_port_members_48, 935 port_array[alt_nh_start + 62], alt_count); 936 WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 63, &dlb_alt_port_members_48, 937 port_array[alt_nh_start + 63], alt_count); 938 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, 939 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members_48); 940 return rv; 941 } 942 943 /* 944 * Function: 945 * _bcm_th2_ecmp_dlb_nhi_member_set 946 * Purpose: 947 * Set dlb port numbers corresponding to each ecmp member NH. 948 * Parameters: 949 * unit - (IN) SOC unit number. 950 * intf_array - (IN) intf array for each NH. 951 * intf_count - (IN) INTF count. 952 * primary_count - (IN) Primary INTF count. 953 * dlb_id - (IN) DLB group id. 954 * Returns: 955 * BCM_E_xxx 956 */ 957 int 958 _bcm_th3_l3_ecmp_dlb_nhi_member_set(int unit, int *intf_array, int primary_count, int unique_intfs, int dlb_id) 959 { 960 int alt_nh_start; 961 int rv = BCM_E_NONE; 962 int alt_count = unique_intfs - primary_count; 963 964 dlb_ecmp_group_nhi_members_0_to_12_entry_t dlb_nhi_members; 965 dlb_ecmp_group_nhi_members_13_to_25_entry_t dlb_nhi_members_13; 966 dlb_ecmp_group_nhi_members_26_to_38_entry_t dlb_nhi_members_26; 967 dlb_ecmp_group_nhi_members_39_to_51_entry_t dlb_nhi_members_39; 968 dlb_ecmp_group_nhi_members_52_to_63_entry_t dlb_nhi_members_52; 969 970 dlb_ecmp_group_alt_nhi_members_0_to_12_entry_t dlb_alt_nhi_members; 971 dlb_ecmp_group_alt_nhi_members_13_to_25_entry_t dlb_alt_nhi_members_13; 972 dlb_ecmp_group_alt_nhi_members_26_to_38_entry_t dlb_alt_nhi_members_26; 973 dlb_ecmp_group_alt_nhi_members_39_to_51_entry_t dlb_alt_nhi_members_39; 974 dlb_ecmp_group_alt_nhi_members_52_to_63_entry_t dlb_alt_nhi_members_52; 975 976 sal_memset(&dlb_nhi_members, 0, 977 sizeof(dlb_ecmp_group_nhi_members_0_to_12_entry_t)); 978 sal_memset(&dlb_nhi_members_13, 0, 979 sizeof(dlb_ecmp_group_nhi_members_13_to_25_entry_t)); 980 sal_memset(&dlb_nhi_members_26, 0, 981 sizeof(dlb_ecmp_group_nhi_members_26_to_38_entry_t)); 982 sal_memset(&dlb_nhi_members_39, 0, 983 sizeof(dlb_ecmp_group_nhi_members_39_to_51_entry_t)); 984 sal_memset(&dlb_nhi_members_52, 0, 985 sizeof(dlb_ecmp_group_nhi_members_52_to_63_entry_t)); 986 987 WRITE_DLB_MEMBER_NHI_0_12(unit, 0, &dlb_nhi_members, 988 (intf_array[0] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 989 WRITE_DLB_MEMBER_NHI_0_12(unit, 1, &dlb_nhi_members, 990 (intf_array[1] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 991 WRITE_DLB_MEMBER_NHI_0_12(unit, 2, &dlb_nhi_members, 992 (intf_array[2] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 993 WRITE_DLB_MEMBER_NHI_0_12(unit, 3, &dlb_nhi_members, 994 (intf_array[3] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 995 WRITE_DLB_MEMBER_NHI_0_12(unit, 4, &dlb_nhi_members, 996 (intf_array[4] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 997 WRITE_DLB_MEMBER_NHI_0_12(unit, 5, &dlb_nhi_members, 998 (intf_array[5] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 999 WRITE_DLB_MEMBER_NHI_0_12(unit, 6, &dlb_nhi_members, 1000 (intf_array[6] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1001 WRITE_DLB_MEMBER_NHI_0_12(unit, 7, &dlb_nhi_members, 1002 (intf_array[7] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1003 WRITE_DLB_MEMBER_NHI_0_12(unit, 8, &dlb_nhi_members, 1004 (intf_array[8] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1005 WRITE_DLB_MEMBER_NHI_0_12(unit, 9, &dlb_nhi_members, 1006 (intf_array[9] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1007 WRITE_DLB_MEMBER_NHI_0_12(unit, 10, &dlb_nhi_members, 1008 (intf_array[10] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1009 WRITE_DLB_MEMBER_NHI_0_12(unit, 11, &dlb_nhi_members, 1010 (intf_array[11] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1011 WRITE_DLB_MEMBER_NHI_0_12(unit, 12, &dlb_nhi_members, 1012 (intf_array[12] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1013 rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, 1014 MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members); 1015 WRITE_DLB_MEMBER_NHI_13_25(unit, 13, &dlb_nhi_members_13, 1016 (intf_array[13] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1017 WRITE_DLB_MEMBER_NHI_13_25(unit, 14, &dlb_nhi_members_13, 1018 (intf_array[14] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1019 WRITE_DLB_MEMBER_NHI_13_25(unit, 15, &dlb_nhi_members_13, 1020 (intf_array[15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1021 WRITE_DLB_MEMBER_NHI_13_25(unit, 15, &dlb_nhi_members_13, 1022 (intf_array[15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1023 WRITE_DLB_MEMBER_NHI_13_25(unit, 16, &dlb_nhi_members_13, 1024 (intf_array[16] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1025 WRITE_DLB_MEMBER_NHI_13_25(unit, 17, &dlb_nhi_members_13, 1026 (intf_array[17] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1027 WRITE_DLB_MEMBER_NHI_13_25(unit, 18, &dlb_nhi_members_13, 1028 (intf_array[18] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1029 WRITE_DLB_MEMBER_NHI_13_25(unit, 19, &dlb_nhi_members_13, 1030 (intf_array[19] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1031 WRITE_DLB_MEMBER_NHI_13_25(unit, 20, &dlb_nhi_members_13, 1032 (intf_array[20] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1033 WRITE_DLB_MEMBER_NHI_13_25(unit, 21, &dlb_nhi_members_13, 1034 (intf_array[21] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1035 WRITE_DLB_MEMBER_NHI_13_25(unit, 22, &dlb_nhi_members_13, 1036 (intf_array[22] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1037 WRITE_DLB_MEMBER_NHI_13_25(unit, 23, &dlb_nhi_members_13, 1038 (intf_array[23] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1039 WRITE_DLB_MEMBER_NHI_13_25(unit, 24, &dlb_nhi_members_13, 1040 (intf_array[24] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1041 WRITE_DLB_MEMBER_NHI_13_25(unit, 25, &dlb_nhi_members_13, 1042 (intf_array[25] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1043 rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, 1044 MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_13); 1045 WRITE_DLB_MEMBER_NHI_26_38(unit, 26, &dlb_nhi_members_26, 1046 (intf_array[26] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1047 WRITE_DLB_MEMBER_NHI_26_38(unit, 27, &dlb_nhi_members_26, 1048 (intf_array[27] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1049 WRITE_DLB_MEMBER_NHI_26_38(unit, 28, &dlb_nhi_members_26, 1050 (intf_array[28] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1051 WRITE_DLB_MEMBER_NHI_26_38(unit, 29, &dlb_nhi_members_26, 1052 (intf_array[29] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1053 WRITE_DLB_MEMBER_NHI_26_38(unit, 30, &dlb_nhi_members_26, 1054 (intf_array[30] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1055 WRITE_DLB_MEMBER_NHI_26_38(unit, 31, &dlb_nhi_members_26, 1056 (intf_array[31] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1057 WRITE_DLB_MEMBER_NHI_26_38(unit, 32, &dlb_nhi_members_26, 1058 (intf_array[32] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1059 WRITE_DLB_MEMBER_NHI_26_38(unit, 33, &dlb_nhi_members_26, 1060 (intf_array[33] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1061 WRITE_DLB_MEMBER_NHI_26_38(unit, 34, &dlb_nhi_members_26, 1062 (intf_array[34] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1063 WRITE_DLB_MEMBER_NHI_26_38(unit, 35, &dlb_nhi_members_26, 1064 (intf_array[35] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1065 WRITE_DLB_MEMBER_NHI_26_38(unit, 36, &dlb_nhi_members_26, 1066 (intf_array[36] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1067 WRITE_DLB_MEMBER_NHI_26_38(unit, 37, &dlb_nhi_members_26, 1068 (intf_array[37] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1069 WRITE_DLB_MEMBER_NHI_26_38(unit, 38, &dlb_nhi_members_26, 1070 (intf_array[38] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1071 rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, 1072 MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_26); 1073 WRITE_DLB_MEMBER_NHI_39_51(unit, 39, &dlb_nhi_members_39, 1074 (intf_array[39] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1075 WRITE_DLB_MEMBER_NHI_39_51(unit, 40, &dlb_nhi_members_39, 1076 (intf_array[40] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1077 WRITE_DLB_MEMBER_NHI_39_51(unit, 41, &dlb_nhi_members_39, 1078 (intf_array[41] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1079 WRITE_DLB_MEMBER_NHI_39_51(unit, 42, &dlb_nhi_members_39, 1080 (intf_array[42] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1081 WRITE_DLB_MEMBER_NHI_39_51(unit, 43, &dlb_nhi_members_39, 1082 (intf_array[43] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1083 WRITE_DLB_MEMBER_NHI_39_51(unit, 44, &dlb_nhi_members_39, 1084 (intf_array[44] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1085 WRITE_DLB_MEMBER_NHI_39_51(unit, 45, &dlb_nhi_members_39, 1086 (intf_array[45] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1087 WRITE_DLB_MEMBER_NHI_39_51(unit, 46, &dlb_nhi_members_39, 1088 (intf_array[46] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1089 WRITE_DLB_MEMBER_NHI_39_51(unit, 47, &dlb_nhi_members_39, 1090 (intf_array[47] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1091 WRITE_DLB_MEMBER_NHI_39_51(unit, 48, &dlb_nhi_members_39, 1092 (intf_array[48] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1093 WRITE_DLB_MEMBER_NHI_39_51(unit, 49, &dlb_nhi_members_39, 1094 (intf_array[49] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1095 WRITE_DLB_MEMBER_NHI_39_51(unit, 50, &dlb_nhi_members_39, 1096 (intf_array[50] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1097 WRITE_DLB_MEMBER_NHI_39_51(unit, 51, &dlb_nhi_members_39, 1098 (intf_array[51] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1099 rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, 1100 MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_39); 1101 WRITE_DLB_MEMBER_NHI_52_63(unit, 52, &dlb_nhi_members_52, 1102 (intf_array[52] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1103 WRITE_DLB_MEMBER_NHI_52_63(unit, 53, &dlb_nhi_members_52, 1104 (intf_array[53] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1105 WRITE_DLB_MEMBER_NHI_52_63(unit, 54, &dlb_nhi_members_52, 1106 (intf_array[54] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1107 WRITE_DLB_MEMBER_NHI_52_63(unit, 55, &dlb_nhi_members_52, 1108 (intf_array[55] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1109 WRITE_DLB_MEMBER_NHI_52_63(unit, 56, &dlb_nhi_members_52, 1110 (intf_array[56] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1111 WRITE_DLB_MEMBER_NHI_52_63(unit, 57, &dlb_nhi_members_52, 1112 (intf_array[57] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1113 WRITE_DLB_MEMBER_NHI_52_63(unit, 58, &dlb_nhi_members_52, 1114 (intf_array[58] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1115 WRITE_DLB_MEMBER_NHI_52_63(unit, 59, &dlb_nhi_members_52, 1116 (intf_array[59] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1117 WRITE_DLB_MEMBER_NHI_52_63(unit, 60, &dlb_nhi_members_52, 1118 (intf_array[60] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1119 WRITE_DLB_MEMBER_NHI_52_63(unit, 61, &dlb_nhi_members_52, 1120 (intf_array[61] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1121 WRITE_DLB_MEMBER_NHI_52_63(unit, 62, &dlb_nhi_members_52, 1122 (intf_array[62] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1123 WRITE_DLB_MEMBER_NHI_52_63(unit, 63, &dlb_nhi_members_52, 1124 (intf_array[63] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count); 1125 rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, 1126 MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_52); 1127 1128 if (alt_count <= 0) { 1129 return rv; 1130 } 1131 alt_nh_start = primary_count; 1132 1133 sal_memset(&dlb_alt_nhi_members, 0, 1134 sizeof(dlb_ecmp_group_alt_nhi_members_0_to_12_entry_t)); 1135 sal_memset(&dlb_alt_nhi_members_13, 0, 1136 sizeof(dlb_ecmp_group_alt_nhi_members_13_to_25_entry_t)); 1137 sal_memset(&dlb_alt_nhi_members_26, 0, 1138 sizeof(dlb_ecmp_group_alt_nhi_members_26_to_38_entry_t)); 1139 sal_memset(&dlb_alt_nhi_members_39, 0, 1140 sizeof(dlb_ecmp_group_alt_nhi_members_39_to_51_entry_t)); 1141 sal_memset(&dlb_alt_nhi_members_52, 0, 1142 sizeof(dlb_ecmp_group_alt_nhi_members_52_to_63_entry_t)); 1143 1144 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 0, &dlb_alt_nhi_members, 1145 (intf_array[alt_nh_start] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1146 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 1, &dlb_alt_nhi_members, 1147 (intf_array[alt_nh_start + 1] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1148 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 2, &dlb_alt_nhi_members, 1149 (intf_array[alt_nh_start + 2] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1150 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 3, &dlb_alt_nhi_members, 1151 (intf_array[alt_nh_start + 3] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1152 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 4, &dlb_alt_nhi_members, 1153 (intf_array[alt_nh_start + 4] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1154 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 5, &dlb_alt_nhi_members, 1155 (intf_array[alt_nh_start + 5] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1156 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 6, &dlb_alt_nhi_members, 1157 (intf_array[alt_nh_start + 6] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1158 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 7, &dlb_alt_nhi_members, 1159 (intf_array[alt_nh_start + 7] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1160 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 8, &dlb_alt_nhi_members, 1161 (intf_array[alt_nh_start + 8] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1162 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 9, &dlb_alt_nhi_members, 1163 (intf_array[alt_nh_start + 9] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1164 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 10, &dlb_alt_nhi_members, 1165 (intf_array[alt_nh_start + 10] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1166 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 11, &dlb_alt_nhi_members, 1167 (intf_array[alt_nh_start + 11] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1168 WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 12, &dlb_alt_nhi_members, 1169 (intf_array[alt_nh_start + 12] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1170 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, 1171 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members); 1172 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 13, &dlb_alt_nhi_members_13, 1173 (intf_array[alt_nh_start + 13] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1174 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 14, &dlb_alt_nhi_members_13, 1175 (intf_array[alt_nh_start + 14] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1176 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 15, &dlb_alt_nhi_members_13, 1177 (intf_array[alt_nh_start + 15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1178 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 15, &dlb_alt_nhi_members_13, 1179 (intf_array[alt_nh_start + 15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1180 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 16, &dlb_alt_nhi_members_13, 1181 (intf_array[alt_nh_start + 16] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1182 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 17, &dlb_alt_nhi_members_13, 1183 (intf_array[alt_nh_start + 17] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1184 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 18, &dlb_alt_nhi_members_13, 1185 (intf_array[alt_nh_start + 18] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1186 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 19, &dlb_alt_nhi_members_13, 1187 (intf_array[alt_nh_start + 19] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1188 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 20, &dlb_alt_nhi_members_13, 1189 (intf_array[alt_nh_start + 20] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1190 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 21, &dlb_alt_nhi_members_13, 1191 (intf_array[alt_nh_start + 21] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1192 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 22, &dlb_alt_nhi_members_13, 1193 (intf_array[alt_nh_start + 22] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1194 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 23, &dlb_alt_nhi_members_13, 1195 (intf_array[alt_nh_start + 23] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1196 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 24, &dlb_alt_nhi_members_13, 1197 (intf_array[alt_nh_start + 24] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1198 WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 25, &dlb_alt_nhi_members_13, 1199 (intf_array[alt_nh_start + 25] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1200 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, 1201 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_13); 1202 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 26, &dlb_alt_nhi_members_26, 1203 (intf_array[alt_nh_start + 26] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1204 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 27, &dlb_alt_nhi_members_26, 1205 (intf_array[alt_nh_start + 27] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1206 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 28, &dlb_alt_nhi_members_26, 1207 (intf_array[alt_nh_start + 28] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1208 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 29, &dlb_alt_nhi_members_26, 1209 (intf_array[alt_nh_start + 29] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1210 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 30, &dlb_alt_nhi_members_26, 1211 (intf_array[alt_nh_start + 30] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1212 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 31, &dlb_alt_nhi_members_26, 1213 (intf_array[alt_nh_start + 31] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1214 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 32, &dlb_alt_nhi_members_26, 1215 (intf_array[alt_nh_start + 32] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1216 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 33, &dlb_alt_nhi_members_26, 1217 (intf_array[alt_nh_start + 33] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1218 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 34, &dlb_alt_nhi_members_26, 1219 (intf_array[alt_nh_start + 34] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1220 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 35, &dlb_alt_nhi_members_26, 1221 (intf_array[alt_nh_start + 35] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1222 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 36, &dlb_alt_nhi_members_26, 1223 (intf_array[alt_nh_start + 36] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1224 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 37, &dlb_alt_nhi_members_26, 1225 (intf_array[alt_nh_start + 37] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1226 WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 38, &dlb_alt_nhi_members_26, 1227 (intf_array[alt_nh_start + 38] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1228 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, 1229 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_26); 1230 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 39, &dlb_alt_nhi_members_39, 1231 (intf_array[alt_nh_start + 39] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1232 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 40, &dlb_alt_nhi_members_39, 1233 (intf_array[alt_nh_start + 40] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1234 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 41, &dlb_alt_nhi_members_39, 1235 (intf_array[alt_nh_start + 41] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1236 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 42, &dlb_alt_nhi_members_39, 1237 (intf_array[alt_nh_start + 42] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1238 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 43, &dlb_alt_nhi_members_39, 1239 (intf_array[alt_nh_start + 43] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1240 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 44, &dlb_alt_nhi_members_39, 1241 (intf_array[alt_nh_start + 44] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1242 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 45, &dlb_alt_nhi_members_39, 1243 (intf_array[alt_nh_start + 45] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1244 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 46, &dlb_alt_nhi_members_39, 1245 (intf_array[alt_nh_start + 46] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1246 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 47, &dlb_alt_nhi_members_39, 1247 (intf_array[alt_nh_start + 47] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1248 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 48, &dlb_alt_nhi_members_39, 1249 (intf_array[alt_nh_start + 48] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1250 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 49, &dlb_alt_nhi_members_39, 1251 (intf_array[alt_nh_start + 49] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1252 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 50, &dlb_alt_nhi_members_39, 1253 (intf_array[alt_nh_start + 50] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1254 WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 51, &dlb_alt_nhi_members_39, 1255 (intf_array[alt_nh_start + 51] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1256 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, 1257 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_39); 1258 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 52, &dlb_alt_nhi_members_52, 1259 (intf_array[alt_nh_start + 52] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1260 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 53, &dlb_alt_nhi_members_52, 1261 (intf_array[alt_nh_start + 53] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1262 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 54, &dlb_alt_nhi_members_52, 1263 (intf_array[alt_nh_start + 54] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1264 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 55, &dlb_alt_nhi_members_52, 1265 (intf_array[alt_nh_start + 55] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1266 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 56, &dlb_alt_nhi_members_52, 1267 (intf_array[alt_nh_start + 56] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1268 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 57, &dlb_alt_nhi_members_52, 1269 (intf_array[alt_nh_start + 57] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1270 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 58, &dlb_alt_nhi_members_52, 1271 (intf_array[alt_nh_start + 58] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1272 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 59, &dlb_alt_nhi_members_52, 1273 (intf_array[alt_nh_start + 59] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1274 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 60, &dlb_alt_nhi_members_52, 1275 (intf_array[alt_nh_start + 60] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1276 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 61, &dlb_alt_nhi_members_52, 1277 (intf_array[alt_nh_start + 61] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1278 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 62, &dlb_alt_nhi_members_52, 1279 (intf_array[alt_nh_start + 62] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1280 WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 63, &dlb_alt_nhi_members_52, 1281 (intf_array[alt_nh_start + 63] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count); 1282 rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, 1283 MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_52); 1284 1285 return rv; 1286 } 1287 1288 /* 1289 * Function: 1290 * _bcm_th3_l3_ecmp_dlb_scaling_factor_encode 1291 * Purpose: 1292 * Check valid scaling factors, and encode them. 1293 * Parameters: 1294 * unit - (IN) SOC unit number. 1295 * scaling_factor - (IN) Threshold scaling factor. 1296 * Returns: 1297 * 1: check success 1298 * 0: check fail 1299 */ 1300 int 1301 _bcm_th3_l3_ecmp_dlb_scaling_factor_encode(int unit, int scaling_factor, 1302 int *scaling_factor_hw) 1303 { 1304 int bcm_factors[] = {10, 25, 40, 50, 75, 100, 200, 400}; 1305 int hw_factors[] = { 0, 1, 2, 3, 4, 5, 6, 7}; 1306 int i; 1307 1308 for (i = 0; i < COUNTOF(bcm_factors); i++ ) { 1309 if (scaling_factor == bcm_factors[i]) { 1310 break; 1311 } 1312 } 1313 1314 if (i < COUNTOF(hw_factors)) { 1315 if (scaling_factor_hw) { 1316 *scaling_factor_hw = hw_factors[i]; 1317 } 1318 return 1; 1319 } 1320 return 0; 1321 } 1322 1323 1324 /* 1325 * Function: 1326 * _bcm_th3_l3_ecmp_dlb_scaling_factor_decode 1327 * Purpose: 1328 * Decode scaling factors. 1329 * Parameters: 1330 * unit - (IN) SOC unit number. 1331 * scaling_factor - (IN) Threshold scaling factor. 1332 * Returns: 1333 * BCM_E_xxx 1334 */ 1335 int 1336 _bcm_th3_l3_ecmp_dlb_scaling_factor_decode(int unit, int scaling_factor_hw, 1337 int *scaling_factor) 1338 { 1339 int bcm_factors[] = {10, 25, 40, 50, 75, 100, 200, 400}; 1340 int hw_factors[] = { 0, 1, 2, 3, 4, 5, 6, 7}; 1341 int i; 1342 1343 for (i = 0; i < COUNTOF(hw_factors); i++ ) { 1344 if (scaling_factor_hw == hw_factors[i]) { 1345 break; 1346 } 1347 } 1348 1349 if (i == COUNTOF(hw_factors)) { 1350 return BCM_E_INTERNAL; 1351 } 1352 1353 *scaling_factor = bcm_factors[i]; 1354 return BCM_E_NONE; 1355 } 1356 1357 /* 1358 * Function: 1359 * bcm_th3_l3_ecmp_dlb_mon_config_set 1360 * Purpose: 1361 * This function configures DLB flow monitoring parameters for a DLB id 1362 * derived from ECMP group id (the second argument). Property 1363 * spn_DLB_FLOW_MONITOR_EN must be enabled before invoking this function. 1364 * See Notes. 1365 * Parameters: 1366 * unit : (IN) Device's unit number 1367 * ecmp_intf : (IN) ECMP interface id obtained from bcm_l3_ecmp_create or 1368 * bcm_l3_egress_ecmp_create 1369 * dlb_mon_cfg : (IN) DLB flow monitoring configuration 1370 * Returns: 1371 * BCM_E_XXX 1372 * Notes: 1373 * If 'sample_rate' is specified as 0, monitoring will not be enabled, 1374 * irrespective of 'enable' setting in 'dlb_mon_cfg'. 1375 */ 1376 int 1377 bcm_th3_l3_ecmp_dlb_mon_config_set(int unit, 1378 bcm_if_t ecmp_intf, 1379 bcm_l3_ecmp_dlb_mon_cfg_t *dlb_mon_cfg) 1380 { 1381 int dlb_id; 1382 int dlb_mode; 1383 uint64 dlb_en_bitmap; 1384 uint32 dlb_enabled; 1385 dlb_ecmp_group_control_entry_t dlb_ecmp_group_control_entry; 1386 uint32 threshold = 0; 1387 uint32 enable = 0; 1388 uint32 copy_to_cpu = 0; 1389 uint32 mirror = 0; 1390 dlb_ecmp_group_monitor_control_entry_t mon_ctrl; 1391 int max_val; 1392 int ecmp_group_idx; 1393 1394 /* If application has not defined this feature, or not enabled this feature, 1395 * return error 1396 */ 1397 if (!soc_property_get(unit, spn_DLB_FLOW_MONITOR_EN, 0)) { 1398 return BCM_E_UNAVAIL; 1399 } 1400 1401 if (dlb_mon_cfg == NULL) { 1402 return BCM_E_PARAM; 1403 } 1404 1405 ecmp_group_idx = ecmp_intf - BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 1406 if (ecmp_group_idx < BCM_TH3_L3_ECMP_DLB_START(unit)) { 1407 return BCM_E_CONFIG; 1408 } 1409 1410 /* Get the DLB id associated with the Ecmp group */ 1411 dlb_id = _bcm_th3_l3_ecmp_dlb_get_id(unit, ecmp_group_idx); 1412 1413 /* DLB id of 0 is not supported for DLB flow monitoring. If we obtained 1414 * it (0), return error 1415 */ 1416 if (dlb_id == 0) { 1417 return BCM_E_INTERNAL; 1418 } 1419 1420 /* Check if the DLB obtained is in enabled state */ 1421 if (dlb_id < soc_reg_field_length(unit, DLB_ID_0_TO_63_ENABLEr, BITMAPf)) { 1422 SOC_IF_ERROR_RETURN( \ 1423 READ_DLB_ID_0_TO_63_ENABLEr(unit, &dlb_en_bitmap)); 1424 dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id); 1425 } else { 1426 SOC_IF_ERROR_RETURN( \ 1427 READ_DLB_ID_64_TO_127_ENABLEr(unit, &dlb_en_bitmap)); 1428 dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id - 1429 (soc_reg_field_length(unit, 1430 DLB_ID_64_TO_127_ENABLEr, BITMAPf))); 1431 } 1432 1433 if (!dlb_enabled) { 1434 return BCM_E_CONFIG; 1435 } 1436 1437 /* Get DLB operational mode */ 1438 BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_CONTROLm(unit, MEM_BLOCK_ANY, 1439 dlb_id, &dlb_ecmp_group_control_entry)); 1440 1441 dlb_mode = soc_DLB_ECMP_GROUP_CONTROLm_field32_get(unit, 1442 &dlb_ecmp_group_control_entry, PORT_ASSIGNMENT_MODEf); 1443 1444 /* If DLB group is in PACKET_SPRAY mode, return error. Refer arch doc 1445 * for details 1446 */ 1447 if (dlb_mode == 2) { 1448 return BCM_E_CONFIG; 1449 } 1450 1451 /* Validate configuration info passed */ 1452 if ((dlb_mon_cfg->action < BCM_L3_ECMP_DLB_MON_COPY_TO_CPU) || 1453 (dlb_mon_cfg->action > BCM_L3_ECMP_DLB_MON_ACTION_NONE)) { 1454 return BCM_E_PARAM; 1455 } 1456 1457 1458 max_val = (1 << soc_mem_field_length(unit, DLB_ECMP_GROUP_MONITOR_CONTROLm, 1459 SAMPLE_THRESHOLDf)); 1460 1461 enable = dlb_mon_cfg->enable ? 1 : 0; 1462 1463 /* Program h/w only if user is enabling DLB id monitoring, and a non-zero 1464 * rate is specified. Rate of 0 means 'do not sample', which means 1465 * effectively disabling monitoring 1466 */ 1467 if ((enable) && (dlb_mon_cfg->sample_rate > 0)) { 1468 1469 /* Calculate threshold based on sampling rate provided. We complement 1470 * the value calculated since packet sampling happens when h/w's 1471 * random number generator is >= the programmed threshold 1472 * (In case of sflow, sampling happens if RNG value <= threshold) 1473 */ 1474 1475 /* Rate of 1 means sample each packet. In this case we need to adjust 1476 * value to be the max value that can be fitted in SAMPLE_THRESHOLDf 1477 */ 1478 if (dlb_mon_cfg->sample_rate == 1) { 1479 max_val = max_val - 1; 1480 } 1481 1482 threshold = max_val / dlb_mon_cfg->sample_rate; 1483 1484 /* Complement the value */ 1485 /* Note 'max_val - 1' is used here as mask to zero out bits 31:29 */ 1486 threshold = ~threshold & (max_val - 1); 1487 } else { 1488 enable = 0; 1489 threshold = 0; 1490 } 1491 1492 BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_MONITOR_CONTROLm(unit, 1493 MEM_BLOCK_ANY, 1494 dlb_id, 1495 &mon_ctrl)); 1496 1497 /* Set Monitor enable and threshold fields */ 1498 soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl, 1499 MONITOR_ENf, enable); 1500 1501 soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl, 1502 SAMPLE_THRESHOLDf, 1503 threshold); 1504 1505 /* If application is enabling monitoring, only then program actions 1506 * passed by the application, else reset the action 1507 */ 1508 if (enable) { 1509 /* Set Copy to CPU and/or Mirror bit(s) */ 1510 switch (dlb_mon_cfg->action) { 1511 case BCM_L3_ECMP_DLB_MON_COPY_TO_CPU: 1512 copy_to_cpu = 1; 1513 mirror = 0; 1514 break; 1515 1516 case BCM_L3_ECMP_DLB_MON_MIRROR: 1517 copy_to_cpu = 0; 1518 mirror = 1; 1519 break; 1520 1521 case BCM_L3_ECMP_DLB_MON_COPY_TO_CPU_AND_MIRROR: 1522 copy_to_cpu = 1; 1523 mirror = 1; 1524 break; 1525 1526 case BCM_L3_ECMP_DLB_MON_ACTION_NONE: 1527 copy_to_cpu = 0; 1528 mirror = 0; 1529 break; 1530 1531 default: 1532 /* This case should not be reached */ 1533 return BCM_E_CONFIG; 1534 break; 1535 } 1536 } else { 1537 copy_to_cpu = 0; 1538 mirror = 0; 1539 } 1540 1541 soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl, 1542 COPY_TO_CPUf, copy_to_cpu); 1543 1544 soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl, 1545 MIRRORf, mirror); 1546 1547 BCM_IF_ERROR_RETURN(WRITE_DLB_ECMP_GROUP_MONITOR_CONTROLm(unit, 1548 MEM_BLOCK_ANY, 1549 dlb_id, 1550 &mon_ctrl)); 1551 1552 return BCM_E_NONE; 1553 } 1554 1555 /* 1556 * Function: 1557 * bcm_th3_l3_ecmp_dlb_mon_config_get 1558 * Purpose: 1559 * This function reads DLB monitoring parameters from hardware, for a DLB id 1560 * derived from ECMP group id. Property spn_DLB_FLOW_MONITOR_EN must be 1561 * enabled before invoking this function. See Notes. 1562 * Parameters: 1563 * unit : (IN) Device's unit number 1564 * ecmp_intf : (IN) ECMP interface id obtained from bcm_l3_ecmp_create or, 1565 * bcm_l3_egress_ecmp_create 1566 * dlb_mon_cfg : (OUT) DLB flow monitoring configuration read from h/w for 1567 * specified DLB 1568 * Returns: 1569 * BCM_E_XXX 1570 * Notes: 1571 * 1. Sample rates are calculated only if MONITOR_EN is set for a DLB id. 1572 * 2. Sample rate calculated from threshold may not exactly match the sample 1573 * rate programmed via config_set API. This is because we do integer division 1574 * to calculate the threhold in the config_set, and store the value obtained 1575 * in the threshold field. And in this function, we perform integer division 1576 * again. 1577 */ 1578 int bcm_th3_l3_ecmp_dlb_mon_config_get(int unit, 1579 bcm_if_t ecmp_intf, 1580 bcm_l3_ecmp_dlb_mon_cfg_t *dlb_mon_cfg) 1581 { 1582 int dlb_id; 1583 int dlb_mode; 1584 uint64 dlb_en_bitmap; 1585 uint32 dlb_enabled; 1586 dlb_ecmp_group_control_entry_t dlb_ecmp_group_control_entry; 1587 uint32 threshold = 0; 1588 uint32 enable = 0; 1589 uint32 copy_to_cpu = 0; 1590 uint32 mirror = 0; 1591 dlb_ecmp_group_monitor_control_entry_t mon_ctrl; 1592 int max_val; 1593 int ecmp_group_idx; 1594 1595 /* If application has not defined this feature, or not enabled this feature, 1596 * return error 1597 */ 1598 if (!soc_property_get(unit, spn_DLB_FLOW_MONITOR_EN, 0)) { 1599 return BCM_E_UNAVAIL; 1600 } 1601 1602 if (dlb_mon_cfg == NULL) { 1603 return BCM_E_PARAM; 1604 } 1605 1606 ecmp_group_idx = ecmp_intf - BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 1607 if (ecmp_group_idx < BCM_TH3_L3_ECMP_DLB_START(unit)) { 1608 return BCM_E_CONFIG; 1609 } 1610 1611 /* Get the DLB id associated with the Ecmp group */ 1612 dlb_id = _bcm_th3_l3_ecmp_dlb_get_id(unit, ecmp_group_idx); 1613 1614 /* DLB id of 0 is not supported for DLB flow monitoring. If we obtained 1615 * it (0), return error 1616 */ 1617 if (dlb_id == 0) { 1618 return BCM_E_INTERNAL; 1619 } 1620 1621 /* Check if the DLB obtained is in enabled state */ 1622 if (dlb_id < soc_reg_field_length(unit, DLB_ID_0_TO_63_ENABLEr, BITMAPf)) { 1623 SOC_IF_ERROR_RETURN( \ 1624 READ_DLB_ID_0_TO_63_ENABLEr(unit, &dlb_en_bitmap)); 1625 dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id); 1626 } else { 1627 SOC_IF_ERROR_RETURN( \ 1628 READ_DLB_ID_64_TO_127_ENABLEr(unit, &dlb_en_bitmap)); 1629 dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id - 1630 (soc_reg_field_length(unit, 1631 DLB_ID_64_TO_127_ENABLEr, BITMAPf))); 1632 } 1633 1634 if (!dlb_enabled) { 1635 return BCM_E_CONFIG; 1636 } 1637 1638 /* Get DLB operational mode */ 1639 BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_CONTROLm(unit, MEM_BLOCK_ANY, 1640 dlb_id, &dlb_ecmp_group_control_entry)); 1641 1642 dlb_mode = soc_DLB_ECMP_GROUP_CONTROLm_field32_get(unit, 1643 &dlb_ecmp_group_control_entry, PORT_ASSIGNMENT_MODEf); 1644 1645 /* If DLB group is in PACKET_SPRAY mode, return error. Refer arch doc 1646 * for details 1647 */ 1648 if (dlb_mode == 2) { 1649 return BCM_E_CONFIG; 1650 } 1651 1652 BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_MONITOR_CONTROLm(unit, MEM_BLOCK_ANY, dlb_id, &mon_ctrl)); 1653 1654 enable = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, MONITOR_ENf); 1655 1656 threshold = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, SAMPLE_THRESHOLDf); 1657 1658 copy_to_cpu = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, COPY_TO_CPUf); 1659 1660 mirror = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, MIRRORf); 1661 1662 dlb_mon_cfg->enable = enable; 1663 1664 if (enable) { 1665 if (copy_to_cpu && mirror) { 1666 dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_COPY_TO_CPU_AND_MIRROR; 1667 } else { 1668 if (copy_to_cpu) { 1669 dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_COPY_TO_CPU; 1670 } else { 1671 if (mirror) { 1672 dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_MIRROR; 1673 } else { 1674 dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_ACTION_NONE; 1675 } 1676 } 1677 } 1678 1679 max_val = (1 << soc_mem_field_length(unit, 1680 DLB_ECMP_GROUP_MONITOR_CONTROLm, 1681 SAMPLE_THRESHOLDf)); 1682 1683 /* Calculate sample_rate from sample threshold */ 1684 /* 'max_val - 1' is used as mask here */ 1685 threshold = ~threshold & (max_val - 1); 1686 1687 if (threshold == 0) { 1688 dlb_mon_cfg->sample_rate = max_val; 1689 } else { 1690 dlb_mon_cfg->sample_rate = max_val / threshold; 1691 } 1692 } else { 1693 dlb_mon_cfg->sample_rate = 0; 1694 dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_ACTION_NONE; 1695 } 1696 1697 return BCM_E_NONE; 1698 } 1699 1700 int _bcm_th3_set_port_list(int unit, int port, int dlb_id, int nh_index) 1701 { 1702 1703 _th2_ecmp_dlb_port_membership_t *current_ptr, *first_ptr; 1704 _th2_ecmp_dlb_port_membership_t *membership; 1705 /* now have nh_index (ecmp_member[k]), port (port), dlb_id */ 1706 /* find it nexthop exists in specific port list*/ 1707 current_ptr = ECMP_DLB_PORT_LIST(unit, port); 1708 first_ptr = NULL; 1709 while (current_ptr) { 1710 if (current_ptr->nh_index != nh_index) { 1711 current_ptr = current_ptr->next; 1712 continue; 1713 } 1714 1715 if (dlb_id == current_ptr->dlb_id) { 1716 current_ptr->ref_count++; 1717 break; 1718 } 1719 if (first_ptr == NULL) { 1720 first_ptr = current_ptr; 1721 } 1722 1723 current_ptr = current_ptr->next; 1724 } 1725 1726 if (current_ptr == NULL) { 1727 /* Insert member ID and group to the next hop's linked list of member 1728 * IDs and groups. 1729 */ 1730 membership = sal_alloc(sizeof(_th2_ecmp_dlb_port_membership_t), 1731 "ecmp dlb nh membership"); 1732 if (NULL == membership) { 1733 return BCM_E_MEMORY; 1734 } 1735 sal_memset(membership, 0, sizeof(_th2_ecmp_dlb_port_membership_t)); 1736 membership->nh_index = nh_index; 1737 membership->ref_count = 1; 1738 membership->dlb_id = dlb_id; 1739 1740 if (first_ptr != NULL) { 1741 /* didnt find exact same node(nh_index, dlb_id) , 1742 * but find same nh_index (A). 1743 * create B after A. 1744 * first_ptr points to A. 1745 */ 1746 membership->next = first_ptr->next; 1747 first_ptr->next = membership; 1748 ECMP_DLB_PORT_INFO(unit, port).dlb_count++; 1749 } else { 1750 /* didnt find same nh_index*/ 1751 /* this is new nh_index, insert it at head */ 1752 membership->next = ECMP_DLB_PORT_LIST(unit, port); 1753 ECMP_DLB_PORT_LIST(unit, port) = membership; 1754 ECMP_DLB_PORT_INFO(unit, port).nh_count++; 1755 ECMP_DLB_PORT_INFO(unit, port).dlb_count++; 1756 } 1757 } 1758 return BCM_E_NONE; 1759 } 1760 /* 1761 * Function: 1762 * _bcm_th3_ecmp_dlb_member_recover 1763 * Purpose: 1764 * Recover ECMP DLB ports usage and the next hop indices associated 1765 * with the ports. 1766 * Parameters: 1767 * unit - (IN) SOC unit number. 1768 * Returns: 1769 * BCM_E_XXX 1770 */ 1771 int 1772 _bcm_th3_ecmp_dlb_member_recover(int unit) 1773 { 1774 int rv = BCM_E_NONE; 1775 int port_map_width; 1776 int alloc_size_port_map; 1777 SHR_BITDCL *port_map = NULL; 1778 SHR_BITDCL *port_map2 = NULL; 1779 int dlb_id; 1780 dlb_ecmp_group_membership_entry_t group_membership_entry; 1781 int ecmp_count = 0; /* Next hop count in the group. */ 1782 bcm_if_t *ecmp_member = NULL; /* Ecmp group from hw. */ 1783 dlb_ecmp_group_control_entry_t group_control_entry; 1784 int j; 1785 int membership_pointer; 1786 int offset; 1787 int count; 1788 int nh_index; 1789 bcm_l3_egress_ecmp_t tmp_ecmp; 1790 uint64 dlb_en_bitmap; 1791 1792 dlb_ecmp_group_nhi_members_0_to_12_entry_t dlb_nhi_members; 1793 dlb_ecmp_group_nhi_members_13_to_25_entry_t dlb_nhi_members_13; 1794 dlb_ecmp_group_nhi_members_26_to_38_entry_t dlb_nhi_members_26; 1795 dlb_ecmp_group_nhi_members_39_to_51_entry_t dlb_nhi_members_39; 1796 dlb_ecmp_group_nhi_members_52_to_63_entry_t dlb_nhi_members_52; 1797 1798 dlb_ecmp_group_alt_nhi_members_0_to_12_entry_t dlb_alt_nhi_members; 1799 dlb_ecmp_group_alt_nhi_members_13_to_25_entry_t dlb_alt_nhi_members_13; 1800 dlb_ecmp_group_alt_nhi_members_26_to_38_entry_t dlb_alt_nhi_members_26; 1801 dlb_ecmp_group_alt_nhi_members_39_to_51_entry_t dlb_alt_nhi_members_39; 1802 dlb_ecmp_group_alt_nhi_members_52_to_63_entry_t dlb_alt_nhi_members_52; 1803 1804 dlb_ecmp_group_port_members_0_to_15_entry_t dlb_port_members; 1805 dlb_ecmp_group_port_members_16_to_31_entry_t dlb_port_members_16; 1806 dlb_ecmp_group_port_members_32_to_47_entry_t dlb_port_members_32; 1807 dlb_ecmp_group_port_members_48_to_63_entry_t dlb_port_members_48; 1808 1809 dlb_ecmp_group_alt_port_members_0_to_15_entry_t dlb_alt_port_members; 1810 dlb_ecmp_group_alt_port_members_16_to_31_entry_t dlb_alt_port_members_16; 1811 dlb_ecmp_group_alt_port_members_32_to_47_entry_t dlb_alt_port_members_32; 1812 dlb_ecmp_group_alt_port_members_48_to_63_entry_t dlb_alt_port_members_48; 1813 1814 /* Allocate port map */ 1815 port_map_width = soc_mem_field_length(unit, 1816 DLB_ECMP_GROUP_MEMBERSHIPm, PORT_MAPf); 1817 alloc_size_port_map = SHR_BITALLOCSIZE(port_map_width); 1818 port_map = sal_alloc(alloc_size_port_map, "DLB ECMP port map"); 1819 if (NULL == port_map) { 1820 rv = BCM_E_MEMORY; 1821 goto cleanup; 1822 } 1823 1824 port_map2 = sal_alloc(alloc_size_port_map, "DLB ECMP port map 2"); 1825 if (NULL == port_map2) { 1826 rv = BCM_E_MEMORY; 1827 goto cleanup; 1828 } 1829 1830 /* Allocate ECMP group members */ 1831 ecmp_member = sal_alloc(128 * sizeof(bcm_if_t), 1832 "ecmp member array"); 1833 if (NULL == ecmp_member) { 1834 rv = BCM_E_MEMORY; 1835 goto cleanup; 1836 } 1837 1838 for (dlb_id = 0; dlb_id < 128; dlb_id++) { 1839 /* Enable bits for the first 64 groups are in 1840 DLB_ID_0_TO_63_ENABLE register and the next 64 are in 1841 DLB_ID_64_TO_127_ENABLE. */ 1842 if (dlb_id < soc_reg_field_length(unit, 1843 DLB_ID_0_TO_63_ENABLEr, BITMAPf)) { 1844 rv = READ_DLB_ID_0_TO_63_ENABLEr(unit, &dlb_en_bitmap); 1845 if (rv < 0) { 1846 goto cleanup; 1847 } 1848 if (!(COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id))) { 1849 continue; 1850 } 1851 } else { 1852 rv = READ_DLB_ID_64_TO_127_ENABLEr(unit, &dlb_en_bitmap); 1853 if (rv < 0) { 1854 goto cleanup; 1855 } 1856 if (!(COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id - 1857 soc_reg_field_length(unit, DLB_ID_0_TO_63_ENABLEr, BITMAPf)))) { 1858 continue; 1859 } 1860 } 1861 1862 rv = READ_DLB_ECMP_GROUP_CONTROLm(unit, MEM_BLOCK_ANY, dlb_id, 1863 &group_control_entry); 1864 if (BCM_FAILURE(rv)) { 1865 goto cleanup; 1866 } 1867 membership_pointer = soc_DLB_ECMP_GROUP_CONTROLm_field32_get(unit, 1868 &group_control_entry, GROUP_MEMBERSHIP_POINTERf); 1869 1870 rv = READ_DLB_ECMP_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ANY, 1871 membership_pointer, 1872 &group_membership_entry); 1873 if (BCM_FAILURE(rv)) { 1874 goto cleanup; 1875 } 1876 /* We have the DLB_ID here, 1877 * now there are 2 ways to recover these info from hw to sw: 1878 * 1) Use the DLB_ID to get port_map, 1879 * the port map will indicate how many port2member entries are set. 1880 * traverse the valid port2member entries via port map. 1881 * Each port2member entry can be parsed to get the valid bits and then 1882 * the nexthops. Got the nexthop, the DLB_ID, the port. It's enough 1883 * to recover the sw state. 1884 * 2) The first method has a side effect, which is traverse all valid 1885 * port2member entries, and then traverse the valid bits of each. 1886 * That's portnumber * 64 loops in total. 1887 * An alternative way is to get the ecmp members (64 members at most) 1888 * Parse the entries and then get the ports. Same as above, we got 1889 * all the needed info: nexthop, DLB_ID, port. 1890 * 1891 * Actually, the port2member entries are not necessary, if DLB can 1892 * traverse the ecmp member table and get all nexthops pointing 1893 * to the chosen port, it's done. In fact, port2member is just another 1894 * angle of ecmp member table. 1895 */ 1896 1897 /* Get port map */ 1898 sal_memset(port_map, 0, alloc_size_port_map); 1899 soc_DLB_ECMP_GROUP_MEMBERSHIPm_field_get(unit, 1900 &group_membership_entry, PORT_MAPf, port_map); 1901 1902 sal_memset(port_map2, 0, alloc_size_port_map); 1903 soc_DLB_ECMP_GROUP_MEMBERSHIPm_field_get(unit, 1904 &group_membership_entry, PORT_MAP_ALTERNATEf, port_map2); 1905 1906 /* Get ECMP members */ 1907 /* Check if the ECMP group is DLB enabled. */ 1908 bcm_l3_egress_ecmp_t_init(&tmp_ecmp); 1909 tmp_ecmp.ecmp_intf = dlb_id + BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit) + BCM_TH3_L3_ECMP_DLB_START(unit); 1910 /* 1911 * Increase entry reference count to avoid the failure of calling 1912 * ecmp_get since the reference count of ecmp group is recovered along 1913 * with hash value after the recovery of DLB info. 1914 */ 1915 BCM_XGS3_L3_ENT_REF_CNT_INC( 1916 BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE); 1917 rv = _bcm_esw_l3_egress_ecmp_get(unit, &tmp_ecmp, 0, 1918 NULL, &ecmp_count, TRUE); 1919 BCM_XGS3_L3_ENT_REF_CNT_DEC( 1920 BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE); 1921 if (BCM_FAILURE(rv)) { 1922 goto cleanup; 1923 } 1924 if (tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_NORMAL && 1925 tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_ASSIGNED && 1926 tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_OPTIMAL && 1927 tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_DGM) { 1928 rv = BCM_E_INTERNAL; 1929 goto cleanup; 1930 } 1931 1932 if (ecmp_count > 128) { 1933 rv = BCM_E_INTERNAL; 1934 goto cleanup; 1935 } 1936 1937 sal_memset(ecmp_member, 0, 128 * sizeof(bcm_if_t)); 1938 /* 1939 * Increase entry reference count to avoid the failure of calling 1940 * ecmp_get since the reference count of ecmp group is recovered along 1941 * with hash value after the recovery of DLB info. 1942 */ 1943 BCM_XGS3_L3_ENT_REF_CNT_INC( 1944 BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE); 1945 rv = _bcm_esw_l3_egress_ecmp_get(unit, &tmp_ecmp, ecmp_count, 1946 ecmp_member, &count, TRUE); 1947 BCM_XGS3_L3_ENT_REF_CNT_DEC( 1948 BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE); 1949 if (BCM_FAILURE(rv)) { 1950 goto cleanup; 1951 } 1952 1953 for (j = 0; j < ecmp_count; j++) { 1954 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, ecmp_member[j])) { 1955 offset = BCM_XGS3_EGRESS_IDX_MIN(unit); 1956 } else { 1957 rv = BCM_E_PARAM; 1958 goto cleanup; 1959 } 1960 ecmp_member[j] -= offset; 1961 } 1962 1963 SHR_BITOR_RANGE(port_map, port_map2, 0, port_map_width, port_map); 1964 1965 rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, 1966 SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members); 1967 1968 rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, 1969 SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_13); 1970 1971 rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, 1972 SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_26); 1973 1974 rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, 1975 SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_39); 1976 1977 rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, 1978 SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_52); 1979 1980 rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, 1981 SOC_BLOCK_ANY, (dlb_id), &dlb_port_members); 1982 1983 rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, 1984 SOC_BLOCK_ANY, (dlb_id), &dlb_port_members_16); 1985 1986 rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, 1987 SOC_BLOCK_ANY, (dlb_id), &dlb_port_members_32); 1988 1989 rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, 1990 SOC_BLOCK_ANY, (dlb_id), &dlb_port_members_48); 1991 1992 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, 1993 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members); 1994 1995 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, 1996 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members_16); 1997 1998 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, 1999 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members_32); 2000 2001 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, 2002 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members_48); 2003 2004 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, 2005 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members); 2006 2007 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, 2008 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_13); 2009 2010 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, 2011 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_26); 2012 2013 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, 2014 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_39); 2015 2016 rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, 2017 SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_52); 2018 2019 _DLB_SET_GROUP_PTR_0_12(0); 2020 _DLB_SET_GROUP_PTR_0_12(1); 2021 _DLB_SET_GROUP_PTR_0_12(2); 2022 _DLB_SET_GROUP_PTR_0_12(3); 2023 _DLB_SET_GROUP_PTR_0_12(4); 2024 _DLB_SET_GROUP_PTR_0_12(5); 2025 _DLB_SET_GROUP_PTR_0_12(6); 2026 _DLB_SET_GROUP_PTR_0_12(7); 2027 _DLB_SET_GROUP_PTR_0_12(8); 2028 _DLB_SET_GROUP_PTR_0_12(9); 2029 _DLB_SET_GROUP_PTR_0_12(10); 2030 _DLB_SET_GROUP_PTR_0_12(11); 2031 _DLB_SET_GROUP_PTR_0_12(12); 2032 2033 _DLB_SET_GROUP_PTR_13_25(13); 2034 _DLB_SET_GROUP_PTR_13_25(14); 2035 _DLB_SET_GROUP_PTR_13_25(15); 2036 _DLB_SET_GROUP_PTR_13_25(16); 2037 _DLB_SET_GROUP_PTR_13_25(17); 2038 _DLB_SET_GROUP_PTR_13_25(18); 2039 _DLB_SET_GROUP_PTR_13_25(19); 2040 _DLB_SET_GROUP_PTR_13_25(20); 2041 _DLB_SET_GROUP_PTR_13_25(21); 2042 _DLB_SET_GROUP_PTR_13_25(22); 2043 _DLB_SET_GROUP_PTR_13_25(23); 2044 _DLB_SET_GROUP_PTR_13_25(24); 2045 _DLB_SET_GROUP_PTR_13_25(25); 2046 2047 _DLB_SET_GROUP_PTR_26_38(26); 2048 _DLB_SET_GROUP_PTR_26_38(27); 2049 _DLB_SET_GROUP_PTR_26_38(28); 2050 _DLB_SET_GROUP_PTR_26_38(29); 2051 _DLB_SET_GROUP_PTR_26_38(30); 2052 _DLB_SET_GROUP_PTR_26_38(31); 2053 _DLB_SET_GROUP_PTR_26_38(32); 2054 _DLB_SET_GROUP_PTR_26_38(33); 2055 _DLB_SET_GROUP_PTR_26_38(34); 2056 _DLB_SET_GROUP_PTR_26_38(35); 2057 _DLB_SET_GROUP_PTR_26_38(36); 2058 _DLB_SET_GROUP_PTR_26_38(37); 2059 _DLB_SET_GROUP_PTR_26_38(38); 2060 2061 _DLB_SET_GROUP_PTR_39_51(39); 2062 _DLB_SET_GROUP_PTR_39_51(40); 2063 _DLB_SET_GROUP_PTR_39_51(41); 2064 _DLB_SET_GROUP_PTR_39_51(42); 2065 _DLB_SET_GROUP_PTR_39_51(43); 2066 _DLB_SET_GROUP_PTR_39_51(44); 2067 _DLB_SET_GROUP_PTR_39_51(45); 2068 _DLB_SET_GROUP_PTR_39_51(46); 2069 _DLB_SET_GROUP_PTR_39_51(47); 2070 _DLB_SET_GROUP_PTR_39_51(48); 2071 _DLB_SET_GROUP_PTR_39_51(49); 2072 _DLB_SET_GROUP_PTR_39_51(50); 2073 _DLB_SET_GROUP_PTR_39_51(51); 2074 2075 _DLB_SET_GROUP_PTR_52_63(52); 2076 _DLB_SET_GROUP_PTR_52_63(53); 2077 _DLB_SET_GROUP_PTR_52_63(54); 2078 _DLB_SET_GROUP_PTR_52_63(55); 2079 _DLB_SET_GROUP_PTR_52_63(56); 2080 _DLB_SET_GROUP_PTR_52_63(57); 2081 _DLB_SET_GROUP_PTR_52_63(58); 2082 _DLB_SET_GROUP_PTR_52_63(59); 2083 _DLB_SET_GROUP_PTR_52_63(60); 2084 _DLB_SET_GROUP_PTR_52_63(61); 2085 _DLB_SET_GROUP_PTR_52_63(62); 2086 _DLB_SET_GROUP_PTR_52_63(63); 2087 2088 } 2089 2090 cleanup: 2091 if (port_map) { 2092 sal_free(port_map); 2093 } 2094 if (port_map2) { 2095 sal_free(port_map2); 2096 } 2097 if (ecmp_member) { 2098 sal_free(ecmp_member); 2099 } 2100 return BCM_E_NONE; 2101 } 2102 2103 2104 #endif