asf.c (139339B)
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: asf.c 8 * Purpose: ASF feature support for Tomahawk SKUs 9 * Requires: soc/tomahawk.h 10 */ 11 12 #include <soc/tomahawk.h> 13 14 #if defined(BCM_TOMAHAWK_SUPPORT) 15 16 #include <appl/diag/system.h> 17 #include <soc/drv.h> 18 #include <soc/ll.h> 19 #include <soc/property.h> 20 #include <shared/bsl.h> 21 #ifdef BCM_WARM_BOOT_SUPPORT 22 #include <soc/scache.h> 23 #endif 24 #include <bcm/link.h> 25 #include <soc/esw/portctrl.h> 26 27 /* Linkscan/PHY control Declarations */ 28 extern int bcm_esw_linkscan_register(int, bcm_linkscan_handler_t); 29 extern int bcm_esw_linkscan_unregister(int, bcm_linkscan_handler_t); 30 extern int bcm_esw_port_phy_control_get(int,bcm_port_t,bcm_port_phy_control_t,uint32 *); 31 32 #define _SOC_TH_ASF_QUERY 0xfe 33 #define _SOC_TH_ASF_RETRV 0xff 34 35 #define _SOC_TH_CT_CLASS_TO_SPEED_MAP(ct_class) \ 36 _soc_th_asf_cfg_tbl[(ct_class)].speed 37 38 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 39 40 #define _SOC_TH_PORT_ASF_XMIT_START_COUNT_INIT \ 41 soc_th_port_asf_xmit_start_count_set 42 43 #define _SOC_TH_PORT_ASF_REINIT \ 44 soc_th_port_asf_init 45 46 #define _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, floor) \ 47 if (!(((class) >= (floor)) && ((class) <= 12))) \ 48 return SOC_E_PARAM; 49 50 #define _SOC_TH_ASF_PORT_VALIDATE(unit, port) \ 51 if (IS_CPU_PORT(((unit)), (port)) || IS_LB_PORT(((unit)), (port)) || \ 52 SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) \ 53 return SOC_E_UNAVAIL; 54 55 56 /* EP credit accumulation */ 57 typedef struct _soc_th_ep_credit_acc_s { 58 uint8 line_rate; /* Line-rate profile */ 59 uint8 oversub; /* General profile */ 60 } _soc_th_ep_credit_acc_t; 61 62 /* MMU EP Credit Thresholds */ 63 typedef struct _soc_th_mmu_ep_credit_s { 64 uint8 base_cells; /* Baseline cells */ 65 uint8 pfc_op_cells; /* PFC Optimized cells */ 66 } _soc_th_mmu_ep_credit_t; 67 68 /* EP Credits Outstanding */ 69 typedef struct _soc_th_egr_mmu_cell_credit_s { 70 uint8 base_cells; /* Baseline cells */ 71 uint8 pfc_op_cells; /* PFC Optimized cells */ 72 } _soc_th_egr_mmu_cell_credit_t; 73 74 /* Transmit Start Count */ 75 typedef struct _soc_th_egr_xmit_start_count_s { 76 uint8 saf; /* Store-And-Forward */ 77 uint8 oversub_2_1; /* 2:1 Oversub */ 78 uint8 oversub_3_2; /* 3:2 Oversub */ 79 uint8 line_rate; /* Line-rate */ 80 } _soc_th_egr_xmit_start_count_t; 81 82 /* ASF core config */ 83 typedef struct _soc_th_asf_core_cfg_s { 84 int speed; 85 uint8 min_sp; /* Min. Src. Port Speed */ 86 uint8 max_sp; /* Max. Src. Port Speed */ 87 uint8 min_src_port_xmit_cnt; /* MMU prebuffer */ 88 _soc_th_ep_credit_acc_t ep_credit_acc; /* EP Credit Accumulation */ 89 uint8 encap_acc; /* Encap Accumulation */ 90 uint8 mmu_prebuf_depth; /* Extra MMU Prebuffer depth */ 91 uint8 fast_to_slow_acc; /* Fast to slow CT Accumulation */ 92 _soc_th_mmu_ep_credit_t mmu_ep_credit; /* MMU EP credit thresholds */ 93 _soc_th_egr_mmu_cell_credit_t egr_mmu_credit; /* EGR MMU cell credits */ 94 _soc_th_egr_xmit_start_count_t xmit_cnt_l2_latency; /* L2 Latency Mode */ 95 _soc_th_egr_xmit_start_count_t xmit_cnt_l3_full_latency; /* L3 & Full Latency Modes */ 96 /* NOTE: DON'T ALTER FIELD ORDER */ 97 } _soc_th_asf_core_cfg_t; 98 #ifdef BCM_TOMAHAWK2_SUPPORT 99 /* CT FIFO Threshold and Depth */ 100 typedef struct _soc_th2_ct_fifo_profile_s { 101 uint8 line_rate; /* Line-rate profile */ 102 uint8 oversub; /* General profile */ 103 } _soc_th2_ct_fifo_profile_t; 104 typedef struct _soc_th2_ct_fifo_s { 105 _soc_th2_ct_fifo_profile_t ss; /* Same-Speed */ 106 _soc_th2_ct_fifo_profile_t sf; /* Slow-to-Fast */ 107 _soc_th2_ct_fifo_profile_t fs; /* Fast-to-Slow */ 108 }_soc_th2_ct_fifo_t; 109 110 /* Bubble MOP */ 111 typedef struct _soc_th2_mop_s { 112 uint8 line_rate[SOC_SWITCH_BYPASS_MODE_LOW + 1]; /* Line-rate profile */ 113 uint8 oversub[SOC_SWITCH_BYPASS_MODE_LOW + 1]; /* Oversub profile */ 114 } _soc_th2_mop_t; 115 116 /* EDB Prebuffer */ 117 typedef struct _soc_th2_edb_prebuf_profile_s { 118 uint8 saf; /* prebuffer for store-and-forward */ 119 uint8 ct[SOC_SWITCH_BYPASS_MODE_LOW + 1]; /* prebuffer for cut-through, latency none/L3/L2 */ 120 } _soc_th2_edb_prebuf_profile_t; 121 typedef struct _soc_th2_edb_prebuf_s { 122 _soc_th2_edb_prebuf_profile_t line_rate; 123 _soc_th2_edb_prebuf_profile_t oversub_3_2; /* 3:2 Oversub */ 124 _soc_th2_edb_prebuf_profile_t oversub_2_1; /* 2:1 Oversub */ 125 } _soc_th2_edb_prebuf_t; 126 127 /* MMU Credit Thresholds */ 128 typedef struct _soc_th2_mmu_credit_threshold_profile_s { 129 uint8 lo; /* MMU High Credit Threshold */ 130 uint8 hi; /* MMU Low Credit Threshold */ 131 } _soc_th2_mmu_credit_threshold_profile_t; 132 typedef struct _soc_th2_mmu_credit_threshold_s { 133 _soc_th2_mmu_credit_threshold_profile_t lr_os_1_5; /* line-rate and os ratio <= 3:2 */ 134 _soc_th2_mmu_credit_threshold_profile_t os_2_1; /* os ratio > 3:2 */ 135 } _soc_th2_mmu_credit_threshold_t; 136 137 /* IFSAF Threshold */ 138 typedef struct _soc_th2_ifsaf_threshold_s { 139 uint8 ct; 140 uint8 saf; 141 }_soc_th2_ifsaf_threshold_t; 142 143 /* ASF core config */ 144 typedef struct _soc_th2_asf_core_cfg_s { 145 int speed; 146 uint8 min_sp; /* Min. Src. Port Speed */ 147 uint8 max_sp; /* Max. Src. Port Speed */ 148 uint8 mmu_prebuffer; /* MMU prebuffer */ 149 _soc_th2_ct_fifo_t ct_fifo_threshold; /* Same-speed CT FIFO Threshold */ 150 _soc_th2_ct_fifo_t ct_fifo_depth; /* Same-speed CT FIFO Depth */ 151 uint8 fast_to_slow_acc; /* Fast to slow CT Accumulation */ 152 _soc_th2_mop_t mop_enable; /* Bubble MOP enable */ 153 _soc_th2_edb_prebuf_t edb_prebuffer; /* EDB prebuffer */ 154 _soc_th2_mmu_credit_threshold_t mmu_credit_threshold; /* MMU Credit Threshold */ 155 _soc_th_egr_mmu_cell_credit_t ep_credit; /* EP Credit */ 156 _soc_th2_ifsaf_threshold_t ifsaf_threshold; /* IFSAF Threshold */ 157 /* NOTE: DON'T ALTER FIELD ORDER */ 158 } _soc_th2_asf_core_cfg_t; 159 #endif 160 161 /* ASF ctrl */ 162 typedef struct _soc_th_asf_ctrl_s { 163 uint8 init; 164 pbmp_t asf_ports; 165 pbmp_t pause_restore; 166 pbmp_t asf_ss; 167 pbmp_t asf_sf; 168 pbmp_t asf_fs; 169 soc_th_asf_mem_profile_e asf_mem_profile; 170 int latency; 171 } _soc_th_asf_ctrl_t; 172 173 #ifdef BCM_WARM_BOOT_SUPPORT 174 /* ASF Warmboot */ 175 typedef struct _soc_th_asf_wb_s { 176 int unit; 177 _soc_th_asf_ctrl_t asf_ctrl; 178 } _soc_th_asf_wb_t; 179 #endif 180 181 /* ASF Core Config Table */ 182 static const _soc_th_asf_core_cfg_t 183 _soc_th_asf_cfg_tbl[] = { 184 { -1, 1, 1, 0, {0, 0}, 0, 0, 0, { 0, 0}, { 0, 0}, {18, 0, 0, 0}, {18, 0, 0, 0}}, /* SAF */ 185 { 10000, 1, 10, 6, {2, 8}, 6, 10, 38, { 9, 8}, {13, 11}, {18, 51, 42, 30}, {18, 60, 48, 27}}, /* 10GE */ 186 { 11000, 1, 10, 6, {2, 8}, 6, 10, 38, { 9, 8}, {13, 11}, {18, 51, 42, 30}, {18, 60, 48, 27}}, /* HG[11] */ 187 { 20000, 3, 10, 7, {2, 8}, 7, 11, 29, {13, 12}, {18, 16}, {18, 63, 48, 30}, {18, 54, 42, 21}}, /* 20GE */ 188 { 21000, 3, 10, 7, {2, 8}, 7, 11, 29, {13, 12}, {18, 16}, {18, 63, 48, 30}, {18, 54, 42, 21}}, /* HG[21] */ 189 { 25000, 5, 10, 7, {3, 8}, 6, 11, 25, {12, 11}, {16, 15}, {18, 60, 48, 27}, {18, 51, 36, 18}}, /* 25GE */ 190 { 27000, 5, 10, 7, {3, 8}, 6, 11, 25, {12, 11}, {16, 15}, {18, 60, 48, 27}, {18, 51, 36, 18}}, /* HG[27] */ 191 { 40000, 7, 12, 7, {3, 12}, 8, 11, 29, {18, 14}, {25, 19}, {18, 57, 45, 24}, {18, 42, 30, 12}}, /* 40GE */ 192 { 42000, 7, 12, 7, {3, 12}, 8, 11, 29, {18, 14}, {25, 19}, {18, 57, 45, 24}, {18, 42, 30, 12}}, /* HG[42] */ 193 { 50000, 7, 12, 20, {1, 12}, 8, 31, 25, {20, 17}, {27, 23}, {18, 54, 42, 21}, {18, 33, 27, 12}}, /* 50GE */ 194 { 53000, 7, 12, 7, {1, 12}, 8, 11, 25, {20, 17}, {27, 23}, {18, 54, 42, 21}, {18, 33, 27, 12}}, /* HG[53] */ 195 {100000, 11, 12, 6, {3, 3}, 8, 10, 3, {33, 27}, {44, 36}, {18, 48, 36, 18}, {18, 33, 27, 15}}, /* 100GE */ 196 {106000, 11, 12, 6, {3, 3}, 8, 10, 3, {33, 27}, {44, 36}, {18, 48, 36, 18}, {18, 33, 27, 15}} /* HG[106] */ 197 }; 198 #ifdef BCM_TOMAHAWK2_SUPPORT 199 static const _soc_th2_asf_core_cfg_t 200 _soc_th2_asf_cfg_tbl[] = { 201 { -1, 0, 0, 0, {{0, 0}, { 0, 0}, {0, 0}}, {{0, 0}, { 0, 0}, { 0, 0}}, 0, {{0, 0, 0}, {0, 0, 0}}, {{0, { 0, 0, 0}}, { 0, { 0, 0, 0}}, { 0, { 0, 0, 0}}}, {{0, 0}, { 0, 0}}, {10, 8}, {12, 12}}, /* SAF */ 202 { 10000, 1, 10, 0, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1, 5}, { 1, 7}}, {10, 9}, {12, 12}}, /* 10GE */ 203 { 11000, 1, 10, 6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1, 5}, { 1, 7}}, {10, 9}, {12, 12}}, /* HG[11] */ 204 { 20000, 3, 10, 0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1, 7}, { 3, 12}}, {17, 11}, {12, 12}}, /* 20GE */ 205 { 21000, 3, 10, 7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1, 7}, { 3, 12}}, {17, 11}, {12, 12}}, /* HG[21] */ 206 { 25000, 5, 10, 0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 23}, {15, 26}, {33, 48}}, 25, {{1, 1, 0}, {1, 0, 0}}, {{7, {25, 35, 30}}, {12, {47, 41, 41}}, {16, {56, 49, 49}}}, {{2, 8}, { 3, 12}}, {17, 13}, {18, 18}}, /* 25GE */ 207 { 27000, 5, 10, 7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 23}, {15, 26}, {33, 48}}, 25, {{1, 1, 0}, {1, 0, 0}}, {{7, {25, 35, 30}}, {12, {47, 41, 41}}, {16, {56, 49, 49}}}, {{2, 8}, { 3, 12}}, {17, 13}, {18, 18}}, /* HG[27] */ 208 { 40000, 7, 12, 0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}}, /* 40GE */ 209 { 42000, 7, 12, 7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}}, /* HG[42] */ 210 { 50000, 9, 12, 0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 27}, {15, 26}, {33, 52}}, 25, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 14, 38}}, {12, {24, 52, 50}}, {16, {39, 62, 59}}}, {{3, 14}, { 6, 22}}, {28, 19}, {18, 18}}, /* 50GE */ 211 { 53000, 9, 12, 7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 27}, {15, 26}, {33, 52}}, 25, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 14, 38}}, {12, {24, 52, 50}}, {16, {39, 62, 59}}}, {{3, 14}, { 6, 22}}, {28, 19}, {18, 18}}, /* HG[53] */ 212 {100000, 11, 12, 0, {{3, 10}, {11, 18}, {3, 10}}, {{8, 34}, {16, 27}, {11, 37}}, 3, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, {18, 18}}, /* 100GE */ 213 {106000, 11, 12, 8, {{3, 10}, {11, 18}, {3, 10}}, {{8, 34}, {16, 27}, {11, 37}}, 0, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, {18, 18}} /* HG[106] */ 214 }; 215 #endif 216 217 /* ASF Core Config Table with FEC/CL91 enabled */ 218 static const _soc_th_asf_core_cfg_t 219 _soc_th_asf_cfg_tbl_fec[] = { 220 { -1, 1, 1, 0, {0, 0}, 0, 0, 0, { 0, 0}, { 0, 0}, {18, 0, 0, 0}, {18, 0, 0, 0}}, /* SAF */ 221 { 10000, 1, 10, 6, {2, 8}, 6, 10, 38, { 9, 8}, {13, 11}, {18, 51, 42, 30}, {18, 60, 48, 27}}, /* 10GE */ 222 { 11000, 1, 10, 6, {2, 8}, 6, 10, 38, { 9, 8}, {13, 11}, {18, 51, 42, 30}, {18, 60, 48, 27}}, /* HG[11] */ 223 { 20000, 3, 10, 7, {2, 8}, 7, 11, 29, {13, 12}, {18, 16}, {18, 63, 48, 30}, {18, 54, 42, 21}}, /* 20GE */ 224 { 21000, 3, 10, 7, {2, 8}, 7, 11, 29, {13, 12}, {18, 16}, {18, 63, 48, 30}, {18, 54, 42, 21}}, /* HG[21] */ 225 { 25000, 5, 10, 7, {3, 8}, 6, 11, 25, {12, 12}, {16, 16}, {18, 95, 83, 62}, {18, 86, 71, 53}}, /* 25GE */ 226 { 27000, 5, 10, 7, {3, 8}, 6, 11, 25, {12, 12}, {16, 16}, {18, 95, 83, 62}, {18, 86, 71, 53}}, /* HG[27] */ 227 { 40000, 7, 12, 7, {3, 12}, 8, 11, 29, {18, 14}, {25, 19}, {18, 57, 45, 24}, {18, 42, 30, 12}}, /* 40GE */ 228 { 42000, 7, 12, 7, {3, 12}, 8, 11, 29, {18, 14}, {25, 19}, {18, 57, 45, 24}, {18, 42, 30, 12}}, /* HG[42] */ 229 { 50000, 7, 12, 20, {1, 12}, 8, 31, 25, {20, 17}, {30, 24}, {18, 94, 82, 61}, {18, 73, 67, 52}}, /* 50GE */ 230 { 53000, 7, 12, 7, {1, 12}, 8, 11, 25, {20, 17}, {30, 24}, {18, 94, 82, 61}, {18, 73, 67, 52}}, /* HG[53] */ 231 {100000, 11, 12, 6, {3, 3}, 8, 10, 3, {33, 27}, {44, 36}, {18, 48, 36, 18}, {18, 33, 27, 15}}, /* 100GE */ 232 {106000, 11, 12, 6, {3, 3}, 8, 10, 3, {33, 27}, {44, 36}, {18, 48, 36, 18}, {18, 33, 27, 15}} /* HG[106] */ 233 }; 234 #ifdef BCM_TOMAHAWK2_SUPPORT 235 static const _soc_th2_asf_core_cfg_t 236 _soc_th2_asf_cfg_tbl_fec[] = { 237 { -1, 0, 0, 0, {{0, 0}, { 0, 0}, {0, 0}}, {{ 0, 0}, { 0, 0}, { 0, 0}}, 0, {{0, 0, 0}, {0, 0, 0}}, {{0, { 0, 0, 0}}, { 0, { 0, 0, 0}}, { 0, { 0, 0, 0}}}, {{0, 0}, { 0, 0}}, {10, 8}, {12, 12}}, /* SAF */ 238 { 10000, 1, 10, 0, {{3, 10}, { 9, 16}, {3, 10}}, {{ 8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1, 5}, { 1, 7}}, {10, 9}, {12, 12}}, /* 10GE */ 239 { 11000, 1, 10, 6, {{3, 10}, { 9, 16}, {3, 10}}, {{ 8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1, 5}, { 1, 7}}, {10, 9}, {12, 12}}, /* HG[11] */ 240 { 20000, 3, 10, 0, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1, 7}, { 3, 12}}, {17, 11}, {12, 12}}, /* 20GE */ 241 { 21000, 3, 10, 7, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1, 7}, { 3, 12}}, {17, 11}, {12, 12}}, /* HG[21] */ 242 { 25000, 5, 10, 0, {{3, 12}, {13, 20}, {3, 12}}, {{10, 27}, {20, 31}, {35, 50}}, 25, {{0, 0, 0}, {0, 0, 0}}, {{7, {64, 64, 64}}, {12, {75, 75, 75}}, {16, {83, 83, 83}}}, {{3, 10}, { 2, 12}}, {18, 16}, {10, 18}}, /* 25GE */ 243 { 27000, 5, 10, 7, {{3, 12}, {13, 20}, {3, 12}}, {{10, 27}, {20, 31}, {35, 50}}, 25, {{0, 0, 0}, {0, 0, 0}}, {{7, {64, 64, 64}}, {12, {75, 75, 75}}, {16, {83, 83, 83}}}, {{3, 10}, { 2, 12}}, {18, 16}, {10, 18}}, /* HG[27] */ 244 { 40000, 7, 12, 0, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}}, /* 40GE */ 245 { 42000, 7, 12, 7, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}}, /* HG[42] */ 246 { 50000, 9, 12, 0, {{3, 12}, {13, 20}, {3, 12}}, {{ 8, 29}, {20, 31}, {35, 54}}, 25, {{1, 0, 0}, {0, 0, 0}}, {{7, {78, 72, 72}}, {12, {83, 83, 83}}, {16, {91, 91, 91}}}, {{4, 14}, { 7, 24}}, {32, 22}, { 6, 18}}, /* 50GE */ 247 { 53000, 9, 12, 7, {{3, 12}, {13, 20}, {3, 12}}, {{ 8, 29}, {20, 31}, {35, 54}}, 25, {{1, 0, 0}, {0, 0, 0}}, {{7, {78, 72, 72}}, {12, {83, 83, 83}}, {16, {91, 91, 91}}}, {{4, 14}, { 7, 24}}, {32, 22}, { 6, 18}}, /* HG[53] */ 248 {100000, 11, 12, 0, {{3, 12}, {11, 20}, {3, 12}}, {{ 8, 36}, {18, 29}, {11, 39}}, 3, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, { 6, 18}}, /* 100GE */ 249 {106000, 11, 12, 8, {{3, 12}, {11, 20}, {3, 12}}, {{ 8, 36}, {18, 29}, {11, 39}}, 0, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, { 6, 18}} /* HG[106] */ 250 }; 251 252 /* Use FEC cfg only */ 253 #define _SOC_TH2_ASF_CFG_TBL(unit, cl91) (_soc_th2_asf_cfg_tbl_fec) 254 #endif 255 256 /* ASF Control */ 257 static _soc_th_asf_ctrl_t* 258 _soc_th_asf_ctrl[SOC_MAX_NUM_DEVICES] = {NULL}; 259 260 /* ASF profile billboard */ 261 static const char *asf_profile_str[3] = 262 {"removed of cut-thru capability", 263 "capable of limited speed range cut-thru", 264 "capable of extended speed range cut-thru"}; 265 266 /* Linkscan callback routine */ 267 /* Reconfigures ASF settings on 25G/50G ports when FEC91/FEC108 is enabled */ 268 STATIC void 269 soc_th_asf_linkscan_callback(int unit, soc_port_t port, bcm_port_info_t *info) 270 { 271 soc_th_asf_mode_e mode; 272 int port_speed; 273 274 if (info->linkstatus != BCM_PORT_LINK_STATUS_UP) { 275 return; 276 } 277 port_speed = info->speed; 278 279 if (_soc_th_asf_ctrl[unit] == NULL) { 280 LOG_CLI((BSL_META_U(unit, 281 "!!! error: _soc_th_asf_ctrl[%d] is NULL pointer !!!\n"), 282 unit)); 283 return; 284 } 285 286 /* Reconfigure ASF settings for 25G/50G ports if CL91/CL108 is enabled on the ports */ 287 if (_soc_th_asf_ctrl[unit]->init) { 288 if ((port_speed == 25000) || (port_speed == 27000) || 289 (port_speed == 50000) || (port_speed == 53000) || 290 (port_speed == 100000) || (port_speed == 106000)) { 291 if (SOC_E_NONE == soc_th_port_asf_mode_get(unit, port, port_speed, &mode)) { 292 soc_th_port_asf_mode_set(unit, port, port_speed, mode); 293 } 294 } 295 } 296 return; 297 } 298 299 /* 300 * Cut-through class encoding: 301 * 0 - SAF 302 * 1 - 10GE 303 * 2 - HG[11] 304 * 3 - 20GE 305 * 4 - 21[HG} 306 * 5 - 25GE 307 * 6 - HG[27] 308 * 7 - 40GE 309 * 8 - HG[42] 310 * 9 - 50GE 311 * 10 - HG[53] 312 * 11 - 100GE 313 * 12 - HG[106] 314 */ 315 STATIC int 316 _soc_th_speed_to_ct_class_map(int speed) 317 { 318 int ct_class; 319 320 if (1000 == speed) { /* 1G ports always in SAF, use same setting as 10G ports */ 321 speed = 10000; 322 } 323 324 for (ct_class = 0; ct_class <= 12; ct_class++) { 325 if (_soc_th_asf_cfg_tbl[ct_class].speed == speed) { 326 return ct_class; 327 } 328 } 329 330 return SOC_E_PARAM; 331 } 332 333 /****************************************************************************** 334 * Name: _soc_th_port_asf_class_get * 335 * Description: * 336 * Get Cut-through class configured for the specified port * 337 * IN params: * 338 * - Unit * 339 * - Logical Port * 340 * - Port Speed * 341 * OUT params: * 342 * - CT class * 343 * Returns: * 344 * - SOC_E_NONE on success * 345 * - SOC_E_PARAM on invalid parameter * 346 */ 347 STATIC int 348 _soc_th_port_asf_class_get( 349 int unit, 350 soc_port_t port, 351 OUT int* const class) 352 { 353 egr_ip_cut_thru_class_entry_t entry; 354 355 if (!class) { 356 return SOC_E_PARAM; 357 } 358 359 sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t)); 360 SOC_IF_ERROR_RETURN 361 (READ_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry)); 362 *class = soc_mem_field32_get(unit, EGR_IP_CUT_THRU_CLASSm, &entry, 363 CUT_THRU_CLASSf); 364 365 return SOC_E_NONE; 366 } 367 368 /****************************************************************************** 369 * Name: _soc_th_port_asf_class_init * 370 * Description: * 371 * Initialize Cut-through class for the specified port * 372 * IN params: * 373 * - Unit * 374 * - Logical Port * 375 * - CT class * 376 * Returns: * 377 * - SOC_E_NONE on success * 378 * - SOC_E_PARAM on invalid parameter * 379 */ 380 STATIC int 381 _soc_th_port_asf_class_init( 382 int unit, 383 soc_port_t port, 384 int ct_class) 385 { 386 egr_ip_cut_thru_class_entry_t entry; 387 388 sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t)); 389 soc_mem_field32_set(unit, EGR_IP_CUT_THRU_CLASSm, &entry, 390 CUT_THRU_CLASSf, ct_class); 391 SOC_IF_ERROR_RETURN 392 (WRITE_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry)); 393 394 return SOC_E_NONE; 395 } 396 397 /****************************************************************************** 398 * Name: _soc_th_port_asf_port_cl91_get * 399 * Description: * 400 * Retreives the cl91 fec state for given port * 401 * IN params: * 402 * - Unit * 403 * - Logical Port * 404 * OUT params: * 405 * - port_cl91_state : 1 if FEC CL91 is enabled on the port * 406 * Returns: * 407 * - SOC_E_NONE on success * 408 * - SOC_E_PARAM on invalid parameter * 409 * - SOC_E_INTERNAL on init/soc errors * 410 */ 411 STATIC int 412 _soc_th_port_asf_port_cl91_get( 413 int unit, 414 soc_port_t port, 415 uint32 *port_cl91_state) 416 { 417 int retVal; 418 419 *port_cl91_state = 0; 420 421 if ((!_soc_th_asf_ctrl[unit]) || 422 (IS_CPU_PORT(unit, port)) || (IS_LB_PORT(unit, port))) { 423 return SOC_E_NONE; 424 } 425 426 retVal = bcm_esw_port_phy_control_get(unit, port, BCM_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91, 427 port_cl91_state); 428 429 if ((retVal != SOC_E_NONE) && (retVal != SOC_E_INIT) && (retVal != SOC_E_UNAVAIL)) { 430 return retVal; 431 } 432 433 return SOC_E_NONE; 434 } 435 436 437 #ifdef BCM_TOMAHAWK2_SUPPORT 438 /****************************************************************************** 439 * Name: _soc_th2_port_asf_xmit_start_count_get * 440 * Description: * 441 * Query or retrieve the XMIT Start Count for the specified source class * 442 * of the port depending on the magic number passed in xmit_cnt * 443 * IN params: * 444 * - Unit * 445 * - Logical Port * 446 * - Source Port's Class * 447 * - Destination Port's CT Class * 448 * - ASF Mode * 449 * IN/OUT params: * 450 * - xmit_cnt : IN: carries magic number for query / retrieve * 451 * - xmit_cnt : OUT: contains a valid XMIT START COUNT for the * 452 * source port class, on success * 453 * Returns: * 454 * - SOC_E_NONE on success * 455 * - SOC_E_PARAM on invalid parameter * 456 * - SOC_E_INTERNAL on init/soc errors * 457 */ 458 STATIC int 459 _soc_th2_port_asf_xmit_start_count_get( 460 int unit, 461 soc_port_t port, 462 int sc, 463 int dc, 464 soc_th_asf_mode_e mode, 465 IN_OUT uint8* const xmit_cnt) 466 { 467 soc_info_t *si; 468 egr_xmit_start_count_entry_t entry; 469 int ovs_ratio, port_idx; 470 soc_pbmp_t th_ports, line_rate_ports, ovs_3_2_ports; 471 soc_port_t th_port; 472 int latency = SOC_SWITCH_BYPASS_MODE_NONE; 473 int speed; 474 int class; 475 int pipe; 476 soc_mem_t config_mem = INVALIDm; 477 uint32 port_cl91_state; 478 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 479 480 _SOC_TH_UNIT_VALIDATE(unit); 481 482 if (!(si = &SOC_INFO(unit))) { 483 return SOC_E_INTERNAL; 484 } 485 486 pipe = si->port_pipe[port]; 487 config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe]; 488 489 if (_SOC_TH_ASF_MODE_CFG_UPDATE == mode) { /* translate to valid mode */ 490 /* reverse map speed class to speed, to surmount speed deficit */ 491 SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class)); 492 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0); 493 speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class); 494 SOC_IF_ERROR_RETURN(soc_th_port_asf_mode_get(unit, port, speed, &mode)); 495 } 496 if (!xmit_cnt || 497 !((mode >= _SOC_TH_ASF_MODE_SAF) && 498 (mode <= _SOC_TH_ASF_MODE_FAST_TO_SLOW))) { 499 return SOC_E_PARAM; 500 } 501 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(sc, 0); 502 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(dc, 0); 503 504 if (_SOC_TH_ASF_RETRV == *xmit_cnt) { 505 *xmit_cnt = 0; 506 port_idx = ((port % 34) * 16) + sc; 507 508 sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t)); 509 SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, 510 port_idx, &entry)); 511 *xmit_cnt = soc_mem_field32_get(unit, config_mem, 512 &entry, THRESHOLDf); 513 } else if (_SOC_TH_ASF_QUERY == *xmit_cnt) { 514 *xmit_cnt = 0; 515 SOC_PBMP_CLEAR(th_ports); 516 SOC_PBMP_ASSIGN(th_ports, PBMP_E_ALL(unit)); 517 SOC_PBMP_OR(th_ports, PBMP_HG_ALL(unit)); 518 SOC_PBMP_REMOVE(th_ports, PBMP_MANAGEMENT(unit)); 519 SOC_PBMP_CLEAR(line_rate_ports); 520 SOC_PBMP_CLEAR(ovs_3_2_ports); 521 522 PBMP_ITER(th_ports, th_port) { 523 if (SOC_PBMP_MEMBER(si->oversub_pbm, th_port)) { 524 SOC_IF_ERROR_RETURN( 525 soc_th_port_oversub_ratio_get(unit, th_port, &ovs_ratio)); 526 if (ovs_ratio <= 1500) { /* oversub ratio <= 3:2 */ 527 SOC_PBMP_PORT_ADD(ovs_3_2_ports, th_port); 528 } 529 } 530 else { /* Line-rate */ 531 SOC_PBMP_PORT_ADD(line_rate_ports, th_port); 532 } 533 } 534 535 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 536 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 537 538 /* Get current switch latency mode & set xmit_cnt accordingly */ 539 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 540 541 /* if sc < dc, use SAF setting; else, use CT setting */ 542 if (SOC_PBMP_EQ(th_ports, line_rate_ports)) { 543 *xmit_cnt = (sc < dc) ? 544 _soc_th2_asf_cfg_table[dc].edb_prebuffer.line_rate.saf : 545 _soc_th2_asf_cfg_table[dc].edb_prebuffer.line_rate.ct[latency]; 546 } else if (SOC_PBMP_EQ(th_ports, ovs_3_2_ports)) { 547 *xmit_cnt = (sc < dc) ? 548 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_3_2.saf : 549 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_3_2.ct[latency]; 550 } else { 551 *xmit_cnt = (sc < dc) ? 552 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_2_1.saf : 553 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_2_1.ct[latency]; 554 } 555 556 } 557 558 return SOC_E_NONE; 559 } 560 561 /****************************************************************************** 562 * Name: _soc_th2_port_asf_mmu_prebuf_get * 563 * Description: * 564 * Query or retrieve MMU Prebuffer (Min Source Port XMIT Count) for the * 565 * specified port depending on the magic number passed in mmu_prebuf * 566 * IN params: * 567 * - Unit * 568 * - Logical Port * 569 * - Port Speed * 570 * - ASF Mode * 571 * IN/OUT params: * 572 * - mmu_prebuf : IN: carries magic number for query / retrieve * 573 * - mmu_prebuf : OUT: contains a valid Min Source Port XMIT Count on * 574 * success * 575 * Returns: * 576 * - SOC_E_NONE on success * 577 * - SOC_E_PARAM on invalid parameter * 578 * - SOC_E_INTERNAL on init/soc errors * 579 */ 580 STATIC int 581 _soc_th2_port_asf_mmu_prebuf_get( 582 int unit, 583 soc_port_t port, 584 int port_speed, 585 int min_sp, 586 IN_OUT uint8* const mmu_prebuf) 587 { 588 uint32 rval; 589 int speed_encoding; 590 uint32 port_cl91_state; 591 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 592 593 _SOC_TH_UNIT_VALIDATE(unit); 594 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 595 if (!mmu_prebuf) { 596 return SOC_E_PARAM; 597 } 598 599 if (_SOC_TH_ASF_RETRV == *mmu_prebuf) { 600 *mmu_prebuf = 0; 601 602 if (!_soc_th_asf_ctrl[unit]->init) { 603 return SOC_E_INTERNAL; 604 } 605 606 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 607 *mmu_prebuf = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 608 MIN_SRC_PORT_XMIT_CNTf); 609 } else if (_SOC_TH_ASF_QUERY == *mmu_prebuf) { 610 *mmu_prebuf = 0; 611 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 612 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 613 614 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 615 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 616 617 *mmu_prebuf = 618 _soc_th2_asf_cfg_table[speed_encoding].mmu_prebuffer; 619 } 620 621 return SOC_E_NONE; 622 } 623 624 /****************************************************************************** 625 * Name: _soc_th2_port_asf_fifo_threshold_get * 626 * Description: * 627 * Query or retrieve FIFO Threshold for the specified port depending on * 628 * the magic number passed in fifo_threshold * 629 * IN params: * 630 * - Unit * 631 * - Logical Port * 632 * - Port Speed * 633 * - ASF Mode * 634 * - Min Source Port Speed * 635 * IN/OUT params: * 636 * - fifo_threshold : IN: carries magic number for query / retrieve * 637 * - fifo_threshold : OUT: contains a valid FIFO Threshold on success * 638 * Returns: * 639 * - SOC_E_NONE on success * 640 * - SOC_E_PARAM on invalid parameter * 641 * - SOC_E_INTERNAL on init/soc errors * 642 */ 643 STATIC int 644 _soc_th2_port_asf_fifo_threshold_get( 645 int unit, 646 soc_port_t port, 647 int port_speed, 648 soc_th_asf_mode_e mode, 649 int min_sp, 650 IN_OUT uint8* const fifo_threshold) 651 { 652 uint32 rval; 653 int speed_encoding; 654 uint32 oversub, port_cl91_state; 655 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 656 657 _SOC_TH_UNIT_VALIDATE(unit); 658 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 659 if (!fifo_threshold) { 660 return SOC_E_PARAM; 661 } 662 663 if (_SOC_TH_ASF_RETRV == *fifo_threshold) { 664 *fifo_threshold = 0; 665 666 if (!_soc_th_asf_ctrl[unit]->init) { 667 return SOC_E_INTERNAL; 668 } 669 670 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 671 *fifo_threshold = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 672 FIFO_THRESHOLDf); 673 } else if (_SOC_TH_ASF_QUERY == *fifo_threshold) { 674 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 675 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 676 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 677 678 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 679 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 680 681 switch(mode) { 682 case _SOC_TH_ASF_MODE_SAME_SPEED: 683 *fifo_threshold = (oversub ? 684 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.ss.oversub : 685 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.ss.line_rate); 686 break; 687 688 case _SOC_TH_ASF_MODE_SLOW_TO_FAST: 689 *fifo_threshold = (oversub ? 690 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.sf.oversub : 691 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.sf.line_rate); 692 break; 693 694 case _SOC_TH_ASF_MODE_FAST_TO_SLOW: 695 *fifo_threshold = (oversub ? 696 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.fs.oversub : 697 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.fs.line_rate); 698 break; 699 700 default: 701 *fifo_threshold = 0; 702 return SOC_E_PARAM; 703 } 704 } 705 706 return SOC_E_NONE; 707 } 708 709 /****************************************************************************** 710 * Name: _soc_th2_port_asf_fifo_depth_get * 711 * Description: * 712 * Query or retrieve FIFO Depth for the specified port depending on the * 713 * magic number passed in buf_sz * 714 * IN params: * 715 * - Unit * 716 * - Logical Port * 717 * - Port Speed * 718 * - ASF Mode * 719 * - Min Src Port Speed * 720 * IN/OUT params: * 721 * - fifo_depth : IN: carries magic number for query/retrieve * 722 * - fifo_depth : OUT: contains a valid FIFO Depth on success * 723 * Returns: * 724 * - SOC_E_NONE on success * 725 * - SOC_E_PARAM on invalid parameter * 726 * - SOC_E_INTERNAL on init/soc errors * 727 */ 728 STATIC int 729 _soc_th2_port_asf_fifo_depth_get( 730 int unit, 731 soc_port_t port, 732 int port_speed, 733 soc_th_asf_mode_e mode, 734 int min_sp, 735 IN_OUT uint8* const fifo_depth) 736 { 737 uint32 rval; 738 int speed_encoding; 739 uint32 oversub, port_cl91_state; 740 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 741 742 _SOC_TH_UNIT_VALIDATE(unit); 743 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 744 if (!fifo_depth) { 745 return SOC_E_PARAM; 746 } 747 748 if (_SOC_TH_ASF_RETRV == *fifo_depth) { 749 if (!_soc_th_asf_ctrl[unit]->init) { 750 return SOC_E_INTERNAL; 751 } 752 753 *fifo_depth = 0; 754 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 755 *fifo_depth = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 756 FIFO_DEPTHf); 757 } else if (_SOC_TH_ASF_QUERY == *fifo_depth) { 758 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 759 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 760 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 761 762 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 763 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 764 765 switch(mode) { 766 case _SOC_TH_ASF_MODE_SAME_SPEED: 767 *fifo_depth = (oversub ? 768 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.ss.oversub : 769 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.ss.line_rate); 770 break; 771 772 case _SOC_TH_ASF_MODE_SLOW_TO_FAST: 773 *fifo_depth = (oversub ? 774 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.sf.oversub : 775 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.sf.line_rate); 776 break; 777 778 case _SOC_TH_ASF_MODE_FAST_TO_SLOW: 779 *fifo_depth = (oversub ? 780 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.fs.oversub : 781 _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.fs.line_rate); 782 break; 783 784 default: 785 *fifo_depth = 0; 786 return SOC_E_PARAM; 787 } 788 } 789 790 return SOC_E_NONE; 791 } 792 793 #endif 794 795 796 /****************************************************************************** 797 * Name: _soc_th_port_asf_xmit_start_count_get * 798 * Description: * 799 * Query or retrieve the XMIT Start Count for the specified source class * 800 * of the port depending on the magic number passed in xmit_cnt * 801 * IN params: * 802 * - Unit * 803 * - Logical Port * 804 * - Source Port's Class * 805 * - Destination Port's CT Class * 806 * - ASF Mode * 807 * IN/OUT params: * 808 * - xmit_cnt : IN: carries magic number for query / retrieve * 809 * - xmit_cnt : OUT: contains a valid XMIT START COUNT for the * 810 * source port class, on success * 811 * Returns: * 812 * - SOC_E_NONE on success * 813 * - SOC_E_PARAM on invalid parameter * 814 * - SOC_E_INTERNAL on init/soc errors * 815 */ 816 STATIC int 817 _soc_th_port_asf_xmit_start_count_get( 818 int unit, 819 soc_port_t port, 820 int sc, 821 int dc, 822 soc_th_asf_mode_e mode, 823 IN_OUT uint8* const xmit_cnt) 824 { 825 soc_info_t *si; 826 egr_xmit_start_count_entry_t entry; 827 int ovs_ratio, port_idx; 828 int speed; 829 int class; 830 int pipe; 831 soc_mem_t config_mem = INVALIDm; 832 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 833 uint32 port_cl91_state; 834 835 _SOC_TH_UNIT_VALIDATE(unit); 836 837 if (!(si = &SOC_INFO(unit))) { 838 return SOC_E_INTERNAL; 839 } 840 841 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 842 843 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 844 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 845 846 if (port_cl91_state) { 847 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 848 } 849 850 pipe = si->port_pipe[port]; 851 config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe]; 852 853 if (_SOC_TH_ASF_MODE_CFG_UPDATE == mode) { /* translate to valid mode */ 854 /* reverse map speed class to speed, to surmount speed deficit */ 855 SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class)); 856 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0); 857 speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class); 858 SOC_IF_ERROR_RETURN(soc_th_port_asf_mode_get(unit, port, speed, &mode)); 859 } 860 if (!xmit_cnt || 861 !((mode >= _SOC_TH_ASF_MODE_SAF) && 862 (mode <= _SOC_TH_ASF_MODE_FAST_TO_SLOW))) { 863 return SOC_E_PARAM; 864 } 865 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(sc, 0); 866 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(dc, 0); 867 868 if (_SOC_TH_ASF_RETRV == *xmit_cnt) { 869 *xmit_cnt = 0; 870 port_idx = ((port % 34) * 16) + sc; 871 872 sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t)); 873 SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, 874 port_idx, &entry)); 875 *xmit_cnt = soc_mem_field32_get(unit, config_mem, 876 &entry, THRESHOLDf); 877 } else if (_SOC_TH_ASF_QUERY == *xmit_cnt) { 878 *xmit_cnt = 0; 879 880 if ((_SOC_TH_ASF_MODE_SAF == mode) || (sc < dc)) { 881 *xmit_cnt = _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.saf; 882 } else if (SOC_PBMP_IS_NULL(si->oversub_pbm)) { /* ports are line-rate */ 883 if (_SOC_TH_ASF_MODE_FAST_TO_SLOW == mode) { /* special case */ 884 *xmit_cnt = 885 (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ? 886 _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.oversub_2_1 : 887 _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.oversub_2_1; 888 889 } else { 890 *xmit_cnt = 891 (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ? 892 _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.line_rate : 893 _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.line_rate; 894 } 895 } else { /* oversub */ 896 SOC_IF_ERROR_RETURN( 897 soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio)); 898 if (ovs_ratio <= 1560) { /* oversub ratio <= 3:2 */ 899 *xmit_cnt = 900 (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ? 901 _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.oversub_3_2 : 902 _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.oversub_3_2; 903 } else { 904 *xmit_cnt = 905 (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ? 906 _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.oversub_2_1 : 907 _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.oversub_2_1; 908 } 909 } 910 } 911 912 return SOC_E_NONE; 913 } 914 915 /****************************************************************************** 916 * Name: _soc_th_port_asf_speed_limits_get * 917 * Description: * 918 * Query or retrieve min & max source port speeds for the specified port * 919 * depending on the magic number passed in min_sp & * 920 * max_sp * 921 * IN params: * 922 * - Unit * 923 * - Logical Port * 924 * - Port Speed * 925 * - ASF Mode * 926 * IN/OUT params: * 927 * - min_sp : IN: carries magic number for query / retrieve * 928 * - min_sp : OUT: contains a valid min source port speed * 929 * on success * 930 * - max_sp : IN: carries magic number for query / retrieve * 931 * - max_sp : OUT: contains a valid max source port speed * 932 * on success * 933 * Returns: * 934 * - SOC_E_NONE on success * 935 * - SOC_E_PARAM on invalid parameter * 936 * - SOC_E_INTERNAL on init/soc errors * 937 */ 938 STATIC int 939 _soc_th_port_asf_speed_limits_get( 940 int unit, 941 soc_port_t port, 942 int port_speed, 943 soc_th_asf_mode_e mode, 944 IN_OUT uint8* const min_sp, 945 IN_OUT uint8* const max_sp) 946 { 947 uint32 rval; 948 int speed_encoding; 949 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 950 uint32 port_cl91_state; 951 952 _SOC_TH_UNIT_VALIDATE(unit); 953 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 954 if (!min_sp || !max_sp) { 955 return SOC_E_PARAM; 956 } 957 958 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 959 960 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 961 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 962 963 if (port_cl91_state) { 964 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 965 } 966 967 if ((_SOC_TH_ASF_RETRV == *min_sp) && 968 (_SOC_TH_ASF_RETRV == *max_sp)) { 969 *min_sp = *max_sp = 0; 970 if (!_soc_th_asf_ctrl[unit]->init) { 971 return SOC_E_INTERNAL; 972 } 973 974 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 975 976 /* MIN_SRC_PORT_SPEED */ 977 *min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 978 MIN_SRC_PORT_SPEEDf); 979 /* MAX_SRC_PORT_SPEED */ 980 *max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 981 MAX_SRC_PORT_SPEEDf); 982 } else if ((_SOC_TH_ASF_QUERY == *min_sp) && 983 (_SOC_TH_ASF_QUERY == *max_sp)) { 984 *min_sp = *max_sp = 0; 985 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 986 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 987 988 switch(mode) { 989 case _SOC_TH_ASF_MODE_SAF: 990 return SOC_E_NONE; 991 992 case _SOC_TH_ASF_MODE_SAME_SPEED: 993 *min_sp = *max_sp = speed_encoding; 994 break; 995 996 case _SOC_TH_ASF_MODE_SLOW_TO_FAST: 997 *min_sp = _soc_th_asf_cfg_table[speed_encoding].min_sp; 998 #ifdef BCM_TOMAHAWK2_SUPPORT 999 /* 40G->50G will be removed from TH support as well, 1000 so this workaround will be deleted after TH ASF changes. */ 1001 if (SOC_IS_TOMAHAWK2(unit)) { 1002 *min_sp = _soc_th2_asf_cfg_tbl[speed_encoding].min_sp; 1003 } 1004 #endif 1005 *max_sp = speed_encoding; 1006 break; 1007 1008 case _SOC_TH_ASF_MODE_FAST_TO_SLOW: 1009 if (_SOC_TH_ASF_MEM_PROFILE_SIMILAR == 1010 _soc_th_asf_ctrl[unit]->asf_mem_profile) { 1011 if (speed_encoding % 2) { /* IEEE */ 1012 /* HG counterpart */ 1013 *max_sp = speed_encoding + 1; 1014 } else { /* HG */ 1015 *max_sp = speed_encoding; 1016 } 1017 } else if (_SOC_TH_ASF_MEM_PROFILE_EXTREME == 1018 _soc_th_asf_ctrl[unit]->asf_mem_profile) { 1019 *max_sp = _soc_th_asf_cfg_table[speed_encoding].max_sp; 1020 } 1021 *min_sp = speed_encoding; 1022 break; 1023 1024 default: 1025 return SOC_E_PARAM; 1026 } 1027 } 1028 1029 return SOC_E_NONE; 1030 } 1031 1032 /****************************************************************************** 1033 * Name: _soc_th_port_asf_mmu_prebuf_get * 1034 * Description: * 1035 * Query or retrieve MMU Prebuffer (Min Source Port XMIT Count) for the * 1036 * specified port depending on the magic number passed in mmu_prebuf * 1037 * IN params: * 1038 * - Unit * 1039 * - Logical Port * 1040 * - Port Speed * 1041 * - ASF Mode * 1042 * IN/OUT params: * 1043 * - mmu_prebuf : IN: carries magic number for query / retrieve * 1044 * - mmu_prebuf : OUT: contains a valid Min Source Port XMIT Count on * 1045 * success * 1046 * Returns: * 1047 * - SOC_E_NONE on success * 1048 * - SOC_E_PARAM on invalid parameter * 1049 * - SOC_E_INTERNAL on init/soc errors * 1050 */ 1051 STATIC int 1052 _soc_th_port_asf_mmu_prebuf_get( 1053 int unit, 1054 soc_port_t port, 1055 int port_speed, 1056 int min_sp, 1057 IN_OUT uint8* const mmu_prebuf) 1058 { 1059 uint32 rval; 1060 int speed_encoding; 1061 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 1062 uint32 port_cl91_state; 1063 1064 _SOC_TH_UNIT_VALIDATE(unit); 1065 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 1066 if (!mmu_prebuf) { 1067 return SOC_E_PARAM; 1068 } 1069 1070 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 1071 1072 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 1073 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 1074 1075 if (port_cl91_state) { 1076 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 1077 } 1078 1079 if (_SOC_TH_ASF_RETRV == *mmu_prebuf) { 1080 *mmu_prebuf = 0; 1081 1082 if (!_soc_th_asf_ctrl[unit]->init) { 1083 return SOC_E_INTERNAL; 1084 } 1085 1086 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1087 *mmu_prebuf = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 1088 MIN_SRC_PORT_XMIT_CNTf); 1089 } else if (_SOC_TH_ASF_QUERY == *mmu_prebuf) { 1090 *mmu_prebuf = 0; 1091 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 1092 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 1093 1094 /* special cases : 50GE & HG[53] */ 1095 if ((9 == speed_encoding) || (10 == speed_encoding)) { 1096 if ((7 == min_sp) || (8 == min_sp)) { /* 40GE or HG[42] */ 1097 *mmu_prebuf = 20; 1098 } else if (9 == min_sp) { /* HG[50] */ 1099 *mmu_prebuf = 7; 1100 } 1101 } else { 1102 *mmu_prebuf = 1103 _soc_th_asf_cfg_table[speed_encoding].min_src_port_xmit_cnt; 1104 } 1105 } 1106 1107 return SOC_E_NONE; 1108 } 1109 1110 /****************************************************************************** 1111 * Name: _soc_th_port_asf_fifo_threshold_get * 1112 * Description: * 1113 * Query or retrieve FIFO Threshold for the specified port depending on * 1114 * the magic number passed in fifo_threshold * 1115 * IN params: * 1116 * - Unit * 1117 * - Logical Port * 1118 * - Port Speed * 1119 * - ASF Mode * 1120 * - Min Source Port Speed * 1121 * IN/OUT params: * 1122 * - fifo_threshold : IN: carries magic number for query / retrieve * 1123 * - fifo_threshold : OUT: contains a valid FIFO Threshold on success * 1124 * Returns: * 1125 * - SOC_E_NONE on success * 1126 * - SOC_E_PARAM on invalid parameter * 1127 * - SOC_E_INTERNAL on init/soc errors * 1128 */ 1129 STATIC int 1130 _soc_th_port_asf_fifo_threshold_get( 1131 int unit, 1132 soc_port_t port, 1133 int port_speed, 1134 soc_th_asf_mode_e mode, 1135 int min_sp, 1136 IN_OUT uint8* const fifo_threshold) 1137 { 1138 uint32 rval; 1139 int ret, speed_encoding; 1140 uint8 mmu_prebuf = 0, oversub; 1141 uint32 port_cl91_state; 1142 1143 _SOC_TH_UNIT_VALIDATE(unit); 1144 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 1145 if (!fifo_threshold) { 1146 return SOC_E_PARAM; 1147 } 1148 1149 if (_SOC_TH_ASF_RETRV == *fifo_threshold) { 1150 *fifo_threshold = 0; 1151 1152 if (!_soc_th_asf_ctrl[unit]->init) { 1153 return SOC_E_INTERNAL; 1154 } 1155 1156 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1157 *fifo_threshold = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 1158 FIFO_THRESHOLDf); 1159 } else if (_SOC_TH_ASF_QUERY == *fifo_threshold) { 1160 *fifo_threshold = 0; 1161 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 1162 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 1163 1164 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 1165 1166 /* Get port CL91 state */ 1167 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 1168 1169 switch(mode) { 1170 case _SOC_TH_ASF_MODE_SAME_SPEED: 1171 if (oversub) { 1172 *fifo_threshold = 10; 1173 } else { 1174 *fifo_threshold = 3; 1175 } 1176 /* Based on SV testing and feedback from arch, if CL91/CL108 is enabled */ 1177 /* for same speed CT on 25G ports, fifo_threshold should be increased by 1 */ 1178 /* for 50G and 100G ports, fifo_threshold should be increased by 2 */ 1179 if (port_cl91_state) { 1180 int speed; 1181 int class; 1182 1183 SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class)); 1184 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0); 1185 speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class); 1186 1187 if ((speed == 25000) || (speed == 27000)) { 1188 *fifo_threshold = *fifo_threshold + 1; 1189 } 1190 else if ((speed == 50000) || (speed == 53000) || 1191 (speed == 100000) || (speed == 106000)) { 1192 *fifo_threshold = *fifo_threshold + 2; 1193 } 1194 } 1195 break; 1196 case _SOC_TH_ASF_MODE_FAST_TO_SLOW: 1197 if (oversub) { 1198 *fifo_threshold = 10; 1199 } else { 1200 *fifo_threshold = 3; 1201 } 1202 break; 1203 1204 case _SOC_TH_ASF_MODE_SLOW_TO_FAST: 1205 if (oversub) { 1206 *fifo_threshold = 10; 1207 } else { 1208 *fifo_threshold = 3; 1209 } 1210 1211 mmu_prebuf = _SOC_TH_ASF_QUERY; 1212 ret = _soc_th_port_asf_mmu_prebuf_get(unit, port, port_speed, 1213 min_sp, &mmu_prebuf); 1214 if (SOC_E_NONE != ret) { 1215 return ret; 1216 } 1217 1218 *fifo_threshold += mmu_prebuf; 1219 break; 1220 1221 default: 1222 return SOC_E_PARAM; 1223 } 1224 } 1225 1226 return SOC_E_NONE; 1227 } 1228 1229 /****************************************************************************** 1230 * Name: _soc_th_port_asf_fifo_depth_get * 1231 * Description: * 1232 * Query or retrieve FIFO Depth for the specified port depending on the * 1233 * magic number passed in buf_sz * 1234 * IN params: * 1235 * - Unit * 1236 * - Logical Port * 1237 * - Port Speed * 1238 * - ASF Mode * 1239 * - Min Src Port Speed * 1240 * IN/OUT params: * 1241 * - fifo_depth : IN: carries magic number for query/retrieve * 1242 * - fifo_depth : OUT: contains a valid FIFO Depth on success * 1243 * Returns: * 1244 * - SOC_E_NONE on success * 1245 * - SOC_E_PARAM on invalid parameter * 1246 * - SOC_E_INTERNAL on init/soc errors * 1247 */ 1248 STATIC int 1249 _soc_th_port_asf_fifo_depth_get( 1250 int unit, 1251 soc_port_t port, 1252 int port_speed, 1253 soc_th_asf_mode_e mode, 1254 int min_sp, 1255 IN_OUT uint8* const fifo_depth) 1256 { 1257 uint32 rval; 1258 int speed_encoding; 1259 uint8 oversub, mmu_prebuf_depth = 0; 1260 uint8 same_speed_ct_depth = 0, same_speed_ct_threshold = 0; 1261 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 1262 uint32 port_cl91_state; 1263 1264 _SOC_TH_UNIT_VALIDATE(unit); 1265 _SOC_TH_ASF_PORT_VALIDATE(unit, port); 1266 if (!fifo_depth) { 1267 return SOC_E_PARAM; 1268 } 1269 1270 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 1271 1272 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 1273 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 1274 1275 if (port_cl91_state) { 1276 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 1277 } 1278 1279 if (_SOC_TH_ASF_RETRV == *fifo_depth) { 1280 if (!_soc_th_asf_ctrl[unit]->init) { 1281 return SOC_E_INTERNAL; 1282 } 1283 1284 *fifo_depth = 0; 1285 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1286 *fifo_depth = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 1287 FIFO_DEPTHf); 1288 } else if (_SOC_TH_ASF_QUERY == *fifo_depth) { 1289 *fifo_depth = 0; 1290 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 1291 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 1292 1293 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 1294 1295 switch(mode) { 1296 case _SOC_TH_ASF_MODE_SAME_SPEED: 1297 if (oversub) { 1298 *fifo_depth = 1299 (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.oversub + 1300 _soc_th_asf_cfg_table[speed_encoding].encap_acc + 17); 1301 } else { 1302 *fifo_depth = 1303 (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.line_rate + 6); 1304 } 1305 /* Based on SV testing and feedback from arch, if CL91/CL108 is enabled */ 1306 /* for same speed CT on 25G ports, fifo_depth should be increased by 2 */ 1307 /* for 50G/100G, fifo_depth should be increased by 4. */ 1308 if (port_cl91_state) { 1309 int speed; 1310 int class; 1311 1312 SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class)); 1313 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0); 1314 speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class); 1315 1316 if ((speed == 25000) || (speed == 27000)) { 1317 *fifo_depth = *fifo_depth + 2; 1318 } else if ((speed == 50000) || (speed == 53000) || 1319 (speed == 100000) || (speed == 106000)) { 1320 *fifo_depth = *fifo_depth + 4; 1321 } 1322 } 1323 break; 1324 1325 case _SOC_TH_ASF_MODE_SLOW_TO_FAST: 1326 if (oversub) { 1327 *fifo_depth = 1328 (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.oversub + 1329 _soc_th_asf_cfg_table[speed_encoding].encap_acc + 17); 1330 } else { 1331 *fifo_depth = 1332 (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.line_rate + 6); 1333 } 1334 1335 /* Extra MMU prebuffer depth */ 1336 if ((9 == speed_encoding) || (10 == speed_encoding)) { /* special cases : 50GE & HG[53] */ 1337 if ((7 == min_sp) || (8 == min_sp)) { /* 40GE or HG[42] */ 1338 mmu_prebuf_depth = 31; 1339 } else if (9 == min_sp) { /* HG[50] */ 1340 mmu_prebuf_depth = 11; 1341 } 1342 } else { 1343 mmu_prebuf_depth = _soc_th_asf_cfg_table[speed_encoding].mmu_prebuf_depth; 1344 } 1345 1346 *fifo_depth += mmu_prebuf_depth; 1347 break; 1348 1349 case _SOC_TH_ASF_MODE_FAST_TO_SLOW: 1350 if (oversub) { 1351 same_speed_ct_depth = 1352 (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.oversub + 1353 _soc_th_asf_cfg_table[speed_encoding].encap_acc + 17); 1354 1355 same_speed_ct_threshold = 10; 1356 } else { 1357 same_speed_ct_depth = 1358 (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.line_rate + 6); 1359 1360 same_speed_ct_threshold = 3; 1361 } 1362 1363 *fifo_depth = 1364 MIN((same_speed_ct_depth + _soc_th_asf_cfg_table[speed_encoding].fast_to_slow_acc), 1365 (same_speed_ct_threshold + 46) ); 1366 break; 1367 1368 default: 1369 return SOC_E_PARAM; 1370 } 1371 } 1372 1373 return SOC_E_NONE; 1374 } 1375 1376 /****************************************************************************** 1377 * Name: _soc_th_asf_obm_ca_fifo_thresh_set * 1378 * Description: * 1379 * Configure Cell Assembly CT FIFO threshold for all OBM and Pipe * 1380 * instances. * 1381 * IN params: * 1382 * - Unit * 1383 * - Logical Port * 1384 * - Cell Assembly CT Threshold * 1385 * Returns: * 1386 * - SOC_E_NONE on success * 1387 * - SOC_E_* on internal errors * 1388 */ 1389 STATIC int 1390 _soc_th_asf_obm_ca_fifo_thresh_set( 1391 int unit, 1392 soc_port_t port, 1393 uint8 ca_thresh) 1394 { 1395 int obm, pipe, clport; 1396 int port_block_base, phy_port, lane; 1397 uint32 rval; 1398 soc_info_t *si = &SOC_INFO(unit); 1399 uint32 thresh_field[4] = { THRESHOLD0f, THRESHOLD1f, 1400 THRESHOLD2f, THRESHOLD3f }; 1401 uint32 port_ct_sel_field[4] = { PORT0_CT_SELf, PORT1_CT_SELf, 1402 PORT2_CT_SELf, PORT3_CT_SELf }; 1403 uint32 idb_obm_ca_ct_ctrl_reg[][4] = { 1404 {IDB_OBM0_CA_CT_CONTROL_PIPE0r, IDB_OBM0_CA_CT_CONTROL_PIPE1r, 1405 IDB_OBM0_CA_CT_CONTROL_PIPE2r, IDB_OBM0_CA_CT_CONTROL_PIPE3r}, 1406 {IDB_OBM1_CA_CT_CONTROL_PIPE0r, IDB_OBM1_CA_CT_CONTROL_PIPE1r, 1407 IDB_OBM1_CA_CT_CONTROL_PIPE2r, IDB_OBM1_CA_CT_CONTROL_PIPE3r}, 1408 {IDB_OBM2_CA_CT_CONTROL_PIPE0r, IDB_OBM2_CA_CT_CONTROL_PIPE1r, 1409 IDB_OBM2_CA_CT_CONTROL_PIPE2r, IDB_OBM2_CA_CT_CONTROL_PIPE3r}, 1410 {IDB_OBM3_CA_CT_CONTROL_PIPE0r, IDB_OBM3_CA_CT_CONTROL_PIPE1r, 1411 IDB_OBM3_CA_CT_CONTROL_PIPE2r, IDB_OBM3_CA_CT_CONTROL_PIPE3r}, 1412 {IDB_OBM4_CA_CT_CONTROL_PIPE0r, IDB_OBM4_CA_CT_CONTROL_PIPE1r, 1413 IDB_OBM4_CA_CT_CONTROL_PIPE2r, IDB_OBM4_CA_CT_CONTROL_PIPE3r}, 1414 {IDB_OBM5_CA_CT_CONTROL_PIPE0r, IDB_OBM5_CA_CT_CONTROL_PIPE1r, 1415 IDB_OBM5_CA_CT_CONTROL_PIPE2r, IDB_OBM5_CA_CT_CONTROL_PIPE3r}, 1416 {IDB_OBM6_CA_CT_CONTROL_PIPE0r, IDB_OBM6_CA_CT_CONTROL_PIPE1r, 1417 IDB_OBM6_CA_CT_CONTROL_PIPE2r, IDB_OBM6_CA_CT_CONTROL_PIPE3r}, 1418 {IDB_OBM7_CA_CT_CONTROL_PIPE0r, IDB_OBM7_CA_CT_CONTROL_PIPE1r, 1419 IDB_OBM7_CA_CT_CONTROL_PIPE2r, IDB_OBM7_CA_CT_CONTROL_PIPE3r}, 1420 #ifdef BCM_TOMAHAWK2_SUPPORT 1421 {IDB_OBM8_CA_CT_CONTROL_PIPE0r, IDB_OBM8_CA_CT_CONTROL_PIPE1r, 1422 IDB_OBM8_CA_CT_CONTROL_PIPE2r, IDB_OBM8_CA_CT_CONTROL_PIPE3r}, 1423 {IDB_OBM9_CA_CT_CONTROL_PIPE0r, IDB_OBM9_CA_CT_CONTROL_PIPE1r, 1424 IDB_OBM9_CA_CT_CONTROL_PIPE2r, IDB_OBM9_CA_CT_CONTROL_PIPE3r}, 1425 {IDB_OBM10_CA_CT_CONTROL_PIPE0r, IDB_OBM10_CA_CT_CONTROL_PIPE1r, 1426 IDB_OBM10_CA_CT_CONTROL_PIPE2r, IDB_OBM10_CA_CT_CONTROL_PIPE3r}, 1427 {IDB_OBM11_CA_CT_CONTROL_PIPE0r, IDB_OBM11_CA_CT_CONTROL_PIPE1r, 1428 IDB_OBM11_CA_CT_CONTROL_PIPE2r, IDB_OBM11_CA_CT_CONTROL_PIPE3r}, 1429 {IDB_OBM12_CA_CT_CONTROL_PIPE0r, IDB_OBM12_CA_CT_CONTROL_PIPE1r, 1430 IDB_OBM12_CA_CT_CONTROL_PIPE2r, IDB_OBM12_CA_CT_CONTROL_PIPE3r}, 1431 {IDB_OBM13_CA_CT_CONTROL_PIPE0r, IDB_OBM13_CA_CT_CONTROL_PIPE1r, 1432 IDB_OBM13_CA_CT_CONTROL_PIPE2r, IDB_OBM13_CA_CT_CONTROL_PIPE3r}, 1433 {IDB_OBM14_CA_CT_CONTROL_PIPE0r, IDB_OBM14_CA_CT_CONTROL_PIPE1r, 1434 IDB_OBM14_CA_CT_CONTROL_PIPE2r, IDB_OBM14_CA_CT_CONTROL_PIPE3r}, 1435 {IDB_OBM15_CA_CT_CONTROL_PIPE0r, IDB_OBM15_CA_CT_CONTROL_PIPE1r, 1436 IDB_OBM15_CA_CT_CONTROL_PIPE2r, IDB_OBM15_CA_CT_CONTROL_PIPE3r}, 1437 #endif 1438 }; 1439 1440 _SOC_TH_UNIT_VALIDATE(unit); 1441 1442 /* Get lane, pipe & obm */ 1443 phy_port = si->port_l2p_mapping[port]; 1444 port_block_base = PORT_BLOCK_BASE_PORT(port); 1445 lane = phy_port - port_block_base; 1446 pipe = si->port_pipe[port]; 1447 clport = si->port_serdes[port]; 1448 if (SOC_IS_TOMAHAWK(unit)) { 1449 /* obm number is reversed (mirrored) in odd pipe */ 1450 obm = pipe & 1 ? 7 - (clport & 7) : clport & 7; 1451 } else { 1452 obm = clport & 15; 1453 } 1454 1455 SOC_IF_ERROR_RETURN( 1456 soc_reg32_get(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], 1457 REG_PORT_ANY, 0, &rval)); 1458 1459 soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval, 1460 port_ct_sel_field[lane], lane); 1461 soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval, 1462 thresh_field[lane], ca_thresh); 1463 1464 SOC_IF_ERROR_RETURN( 1465 soc_reg32_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], 1466 REG_PORT_ANY, 0, rval)); 1467 1468 return SOC_E_NONE; 1469 } 1470 1471 /****************************************************************************** 1472 * Name: _soc_th_asf_obm_bubble_mop_set * 1473 * Description: * 1474 * Configure Bubble MOP for all OBM and Pipe Instances * 1475 * IN params: * 1476 * - Unit * 1477 * - Logical Port * 1478 * - Bubble MOP Flag * 1479 * Returns: * 1480 * - SOC_E_NONE on success * 1481 * - SOC_E_* on internal errors * 1482 */ 1483 STATIC int 1484 _soc_th_asf_obm_bubble_mop_set( 1485 int unit, 1486 soc_port_t port, 1487 uint8 bubble_mop_disable) 1488 { 1489 int obm, pipe, clport; 1490 int port_block_base, phy_port, lane; 1491 uint32 rval; 1492 soc_info_t *si = &SOC_INFO(unit); 1493 uint32 port_field[4] = { 1494 PORT0_BUBBLE_MOP_DISABLEf, PORT1_BUBBLE_MOP_DISABLEf, 1495 PORT2_BUBBLE_MOP_DISABLEf, PORT3_BUBBLE_MOP_DISABLEf }; 1496 uint32 idb_obm_ctrl_reg[][4] = { 1497 {IDB_OBM0_CONTROL_PIPE0r, IDB_OBM0_CONTROL_PIPE1r, 1498 IDB_OBM0_CONTROL_PIPE2r, IDB_OBM0_CONTROL_PIPE3r}, 1499 {IDB_OBM1_CONTROL_PIPE0r, IDB_OBM1_CONTROL_PIPE1r, 1500 IDB_OBM1_CONTROL_PIPE2r, IDB_OBM1_CONTROL_PIPE3r}, 1501 {IDB_OBM2_CONTROL_PIPE0r, IDB_OBM2_CONTROL_PIPE1r, 1502 IDB_OBM2_CONTROL_PIPE2r, IDB_OBM2_CONTROL_PIPE3r}, 1503 {IDB_OBM3_CONTROL_PIPE0r, IDB_OBM3_CONTROL_PIPE1r, 1504 IDB_OBM3_CONTROL_PIPE2r, IDB_OBM3_CONTROL_PIPE3r}, 1505 {IDB_OBM4_CONTROL_PIPE0r, IDB_OBM4_CONTROL_PIPE1r, 1506 IDB_OBM4_CONTROL_PIPE2r, IDB_OBM4_CONTROL_PIPE3r}, 1507 {IDB_OBM5_CONTROL_PIPE0r, IDB_OBM5_CONTROL_PIPE1r, 1508 IDB_OBM5_CONTROL_PIPE2r, IDB_OBM5_CONTROL_PIPE3r}, 1509 {IDB_OBM6_CONTROL_PIPE0r, IDB_OBM6_CONTROL_PIPE1r, 1510 IDB_OBM6_CONTROL_PIPE2r, IDB_OBM6_CONTROL_PIPE3r}, 1511 {IDB_OBM7_CONTROL_PIPE0r, IDB_OBM7_CONTROL_PIPE1r, 1512 IDB_OBM7_CONTROL_PIPE2r, IDB_OBM7_CONTROL_PIPE3r}, 1513 #ifdef BCM_TOMAHAWK2_SUPPORT 1514 {IDB_OBM8_CONTROL_PIPE0r, IDB_OBM8_CONTROL_PIPE1r, 1515 IDB_OBM8_CONTROL_PIPE2r, IDB_OBM8_CONTROL_PIPE3r}, 1516 {IDB_OBM9_CONTROL_PIPE0r, IDB_OBM9_CONTROL_PIPE1r, 1517 IDB_OBM9_CONTROL_PIPE2r, IDB_OBM9_CONTROL_PIPE3r}, 1518 {IDB_OBM10_CONTROL_PIPE0r, IDB_OBM10_CONTROL_PIPE1r, 1519 IDB_OBM10_CONTROL_PIPE2r, IDB_OBM10_CONTROL_PIPE3r}, 1520 {IDB_OBM11_CONTROL_PIPE0r, IDB_OBM11_CONTROL_PIPE1r, 1521 IDB_OBM11_CONTROL_PIPE2r, IDB_OBM11_CONTROL_PIPE3r}, 1522 {IDB_OBM12_CONTROL_PIPE0r, IDB_OBM12_CONTROL_PIPE1r, 1523 IDB_OBM12_CONTROL_PIPE2r, IDB_OBM12_CONTROL_PIPE3r}, 1524 {IDB_OBM13_CONTROL_PIPE0r, IDB_OBM13_CONTROL_PIPE1r, 1525 IDB_OBM13_CONTROL_PIPE2r, IDB_OBM13_CONTROL_PIPE3r}, 1526 {IDB_OBM14_CONTROL_PIPE0r, IDB_OBM14_CONTROL_PIPE1r, 1527 IDB_OBM14_CONTROL_PIPE2r, IDB_OBM14_CONTROL_PIPE3r}, 1528 {IDB_OBM15_CONTROL_PIPE0r, IDB_OBM15_CONTROL_PIPE1r, 1529 IDB_OBM15_CONTROL_PIPE2r, IDB_OBM15_CONTROL_PIPE3r}, 1530 #endif 1531 }; 1532 1533 _SOC_TH_UNIT_VALIDATE(unit); 1534 1535 /* Get lane, pipe & obm */ 1536 phy_port = si->port_l2p_mapping[port]; 1537 port_block_base = PORT_BLOCK_BASE_PORT(port); 1538 lane = phy_port - port_block_base; 1539 pipe = si->port_pipe[port]; 1540 clport = si->port_serdes[port]; 1541 if (SOC_IS_TOMAHAWK(unit)) { 1542 /* obm number is reversed (mirrored) in odd pipe */ 1543 obm = pipe & 1 ? 7 - (clport & 7) : clport & 7; 1544 } else { 1545 obm = clport & 15; 1546 } 1547 1548 /* BubbleMOP - At present only L3 & Full Latency Mode supported */ 1549 SOC_IF_ERROR_RETURN( 1550 soc_reg32_get(unit, idb_obm_ctrl_reg[obm][pipe], 1551 REG_PORT_ANY, 0, &rval)); 1552 1553 soc_reg_field_set(unit, idb_obm_ctrl_reg[obm][pipe], &rval, 1554 port_field[lane], bubble_mop_disable); 1555 1556 SOC_IF_ERROR_RETURN( 1557 soc_reg32_set(unit, idb_obm_ctrl_reg[obm][pipe], REG_PORT_ANY, 1558 0, rval)); 1559 1560 return SOC_E_NONE; 1561 } 1562 1563 /****************************************************************************** 1564 * Name: _soc_th_asf_obm_ct_thresh_ok_set * 1565 * Description: * 1566 * Configure IDB OBM CT FIFO threshold OK for all OBM and Pipe * 1567 * instances. * 1568 * IN params: * 1569 * - Unit * 1570 * - Logical Port * 1571 * - CT allowed if usage is less than or eq threshold * 1572 * Returns: * 1573 * - SOC_E_NONE on success * 1574 * - SOC_E_* on internal errors * 1575 */ 1576 STATIC int 1577 _soc_th_asf_obm_ct_thresh_ok_set( 1578 int unit, 1579 soc_port_t port, 1580 uint32 ct_ok_thresh) 1581 { 1582 int obm, pipe, clport; 1583 int port_block_base, phy_port, lane; 1584 uint64 rval64; 1585 soc_info_t *si = &SOC_INFO(unit); 1586 uint32 idb_obm_ct_thresh_reg[][4] = { 1587 {IDB_OBM0_CT_THRESHOLD_PIPE0r, IDB_OBM0_CT_THRESHOLD_PIPE1r, 1588 IDB_OBM0_CT_THRESHOLD_PIPE2r, IDB_OBM0_CT_THRESHOLD_PIPE3r}, 1589 {IDB_OBM1_CT_THRESHOLD_PIPE0r, IDB_OBM1_CT_THRESHOLD_PIPE1r, 1590 IDB_OBM1_CT_THRESHOLD_PIPE2r, IDB_OBM1_CT_THRESHOLD_PIPE3r}, 1591 {IDB_OBM2_CT_THRESHOLD_PIPE0r, IDB_OBM2_CT_THRESHOLD_PIPE1r, 1592 IDB_OBM2_CT_THRESHOLD_PIPE2r, IDB_OBM2_CT_THRESHOLD_PIPE3r}, 1593 {IDB_OBM3_CT_THRESHOLD_PIPE0r, IDB_OBM3_CT_THRESHOLD_PIPE1r, 1594 IDB_OBM3_CT_THRESHOLD_PIPE2r, IDB_OBM3_CT_THRESHOLD_PIPE3r}, 1595 {IDB_OBM4_CT_THRESHOLD_PIPE0r, IDB_OBM4_CT_THRESHOLD_PIPE1r, 1596 IDB_OBM4_CT_THRESHOLD_PIPE2r, IDB_OBM4_CT_THRESHOLD_PIPE3r}, 1597 {IDB_OBM5_CT_THRESHOLD_PIPE0r, IDB_OBM5_CT_THRESHOLD_PIPE1r, 1598 IDB_OBM5_CT_THRESHOLD_PIPE2r, IDB_OBM5_CT_THRESHOLD_PIPE3r}, 1599 {IDB_OBM6_CT_THRESHOLD_PIPE0r, IDB_OBM6_CT_THRESHOLD_PIPE1r, 1600 IDB_OBM6_CT_THRESHOLD_PIPE2r, IDB_OBM6_CT_THRESHOLD_PIPE3r}, 1601 {IDB_OBM7_CT_THRESHOLD_PIPE0r, IDB_OBM7_CT_THRESHOLD_PIPE1r, 1602 IDB_OBM7_CT_THRESHOLD_PIPE2r, IDB_OBM7_CT_THRESHOLD_PIPE3r}, 1603 #ifdef BCM_TOMAHAWK2_SUPPORT 1604 {IDB_OBM8_CT_THRESHOLD_PIPE0r, IDB_OBM8_CT_THRESHOLD_PIPE1r, 1605 IDB_OBM8_CT_THRESHOLD_PIPE2r, IDB_OBM8_CT_THRESHOLD_PIPE3r}, 1606 {IDB_OBM9_CT_THRESHOLD_PIPE0r, IDB_OBM9_CT_THRESHOLD_PIPE1r, 1607 IDB_OBM9_CT_THRESHOLD_PIPE2r, IDB_OBM9_CT_THRESHOLD_PIPE3r}, 1608 {IDB_OBM10_CT_THRESHOLD_PIPE0r, IDB_OBM10_CT_THRESHOLD_PIPE1r, 1609 IDB_OBM10_CT_THRESHOLD_PIPE2r, IDB_OBM10_CT_THRESHOLD_PIPE3r}, 1610 {IDB_OBM11_CT_THRESHOLD_PIPE0r, IDB_OBM11_CT_THRESHOLD_PIPE1r, 1611 IDB_OBM11_CT_THRESHOLD_PIPE2r, IDB_OBM11_CT_THRESHOLD_PIPE3r}, 1612 {IDB_OBM12_CT_THRESHOLD_PIPE0r, IDB_OBM12_CT_THRESHOLD_PIPE1r, 1613 IDB_OBM12_CT_THRESHOLD_PIPE2r, IDB_OBM12_CT_THRESHOLD_PIPE3r}, 1614 {IDB_OBM13_CT_THRESHOLD_PIPE0r, IDB_OBM13_CT_THRESHOLD_PIPE1r, 1615 IDB_OBM13_CT_THRESHOLD_PIPE2r, IDB_OBM13_CT_THRESHOLD_PIPE3r}, 1616 {IDB_OBM14_CT_THRESHOLD_PIPE0r, IDB_OBM14_CT_THRESHOLD_PIPE1r, 1617 IDB_OBM14_CT_THRESHOLD_PIPE2r, IDB_OBM14_CT_THRESHOLD_PIPE3r}, 1618 {IDB_OBM15_CT_THRESHOLD_PIPE0r, IDB_OBM15_CT_THRESHOLD_PIPE1r, 1619 IDB_OBM15_CT_THRESHOLD_PIPE2r, IDB_OBM15_CT_THRESHOLD_PIPE3r}, 1620 #endif 1621 }; 1622 1623 _SOC_TH_UNIT_VALIDATE(unit); 1624 1625 /* Get lane, pipe & obm */ 1626 phy_port = si->port_l2p_mapping[port]; 1627 port_block_base = PORT_BLOCK_BASE_PORT(port); 1628 lane = phy_port - port_block_base; 1629 pipe = si->port_pipe[port]; 1630 clport = si->port_serdes[port]; 1631 if (SOC_IS_TOMAHAWK(unit)) { 1632 /* obm number is reversed (mirrored) in odd pipe */ 1633 obm = pipe & 1 ? 7 - (clport & 7) : clport & 7; 1634 } else { 1635 obm = clport & 15; 1636 } 1637 1638 SOC_IF_ERROR_RETURN( 1639 soc_reg64_get(unit, idb_obm_ct_thresh_reg[obm][pipe], 1640 REG_PORT_ANY, lane, &rval64)); 1641 1642 soc_reg64_field32_set(unit, idb_obm_ct_thresh_reg[obm][pipe], &rval64, 1643 CUT_THROUGH_OKf, ct_ok_thresh); 1644 1645 SOC_IF_ERROR_RETURN( 1646 soc_reg64_set(unit, idb_obm_ct_thresh_reg[obm][pipe], 1647 REG_PORT_ANY, lane, rval64)); 1648 1649 return SOC_E_NONE; 1650 } 1651 1652 /****************************************************************************** 1653 * Name: _soc_th_asf_force_saf_config_set * 1654 * Description: * 1655 * Configure IDB_OBM_FORCE_SAF_CONFIG register for all OBM and Pipe * 1656 * instances. Also configure IDB_FORCE_SAF_CONFIG register. * 1657 * IN params: * 1658 * - Unit * 1659 * - Logical Port * 1660 * Returns: * 1661 * - SOC_E_NONE on success * 1662 * - SOC_E_* on internal errors * 1663 */ 1664 STATIC int 1665 _soc_th_asf_force_saf_config_set( 1666 int unit, 1667 soc_port_t port, 1668 soc_th_asf_mode_e mode) 1669 { 1670 int obm, pipe, clport; 1671 int port_block_base, phy_port, lane; 1672 uint32 port_cl91_state; 1673 int speed; 1674 int class; 1675 uint32 rval; 1676 uint32 field_a; 1677 uint32 field_b; 1678 uint32 field_c; 1679 soc_info_t *si = &SOC_INFO(unit); 1680 uint32 idb_obm_force_saf_config_reg[][4] = { 1681 {IDB_OBM0_DBG_A_PIPE0r, IDB_OBM0_DBG_A_PIPE1r, 1682 IDB_OBM0_DBG_A_PIPE2r, IDB_OBM0_DBG_A_PIPE3r}, 1683 {IDB_OBM1_DBG_A_PIPE0r, IDB_OBM1_DBG_A_PIPE1r, 1684 IDB_OBM1_DBG_A_PIPE2r, IDB_OBM1_DBG_A_PIPE3r}, 1685 {IDB_OBM2_DBG_A_PIPE0r, IDB_OBM2_DBG_A_PIPE1r, 1686 IDB_OBM2_DBG_A_PIPE2r, IDB_OBM2_DBG_A_PIPE3r}, 1687 {IDB_OBM3_DBG_A_PIPE0r, IDB_OBM3_DBG_A_PIPE1r, 1688 IDB_OBM3_DBG_A_PIPE2r, IDB_OBM3_DBG_A_PIPE3r}, 1689 {IDB_OBM4_DBG_A_PIPE0r, IDB_OBM4_DBG_A_PIPE1r, 1690 IDB_OBM4_DBG_A_PIPE2r, IDB_OBM4_DBG_A_PIPE3r}, 1691 {IDB_OBM5_DBG_A_PIPE0r, IDB_OBM5_DBG_A_PIPE1r, 1692 IDB_OBM5_DBG_A_PIPE2r, IDB_OBM5_DBG_A_PIPE3r}, 1693 {IDB_OBM6_DBG_A_PIPE0r, IDB_OBM6_DBG_A_PIPE1r, 1694 IDB_OBM6_DBG_A_PIPE2r, IDB_OBM6_DBG_A_PIPE3r}, 1695 {IDB_OBM7_DBG_A_PIPE0r, IDB_OBM7_DBG_A_PIPE1r, 1696 IDB_OBM7_DBG_A_PIPE2r, IDB_OBM7_DBG_A_PIPE3r}, 1697 #ifdef BCM_TOMAHAWK2_SUPPORT 1698 {IDB_OBM8_DBG_A_PIPE0r, IDB_OBM8_DBG_A_PIPE1r, 1699 IDB_OBM8_DBG_A_PIPE2r, IDB_OBM8_DBG_A_PIPE3r}, 1700 {IDB_OBM9_DBG_A_PIPE0r, IDB_OBM9_DBG_A_PIPE1r, 1701 IDB_OBM9_DBG_A_PIPE2r, IDB_OBM9_DBG_A_PIPE3r}, 1702 {IDB_OBM10_DBG_A_PIPE0r, IDB_OBM10_DBG_A_PIPE1r, 1703 IDB_OBM10_DBG_A_PIPE2r, IDB_OBM10_DBG_A_PIPE3r}, 1704 {IDB_OBM11_DBG_A_PIPE0r, IDB_OBM11_DBG_A_PIPE1r, 1705 IDB_OBM11_DBG_A_PIPE2r, IDB_OBM11_DBG_A_PIPE3r}, 1706 {IDB_OBM12_DBG_A_PIPE0r, IDB_OBM12_DBG_A_PIPE1r, 1707 IDB_OBM12_DBG_A_PIPE2r, IDB_OBM12_DBG_A_PIPE3r}, 1708 {IDB_OBM13_DBG_A_PIPE0r, IDB_OBM13_DBG_A_PIPE1r, 1709 IDB_OBM13_DBG_A_PIPE2r, IDB_OBM13_DBG_A_PIPE3r}, 1710 {IDB_OBM14_DBG_A_PIPE0r, IDB_OBM14_DBG_A_PIPE1r, 1711 IDB_OBM14_DBG_A_PIPE2r, IDB_OBM14_DBG_A_PIPE3r}, 1712 {IDB_OBM15_DBG_A_PIPE0r, IDB_OBM15_DBG_A_PIPE1r, 1713 IDB_OBM15_DBG_A_PIPE2r, IDB_OBM15_DBG_A_PIPE3r}, 1714 #endif 1715 }; 1716 1717 uint32 idb_force_saf_config_reg[4] = { 1718 IDB_DBG_B_PIPE0r, IDB_DBG_B_PIPE1r, 1719 IDB_DBG_B_PIPE2r, IDB_DBG_B_PIPE3r}; 1720 1721 _SOC_TH_UNIT_VALIDATE(unit); 1722 1723 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 1724 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 1725 1726 SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class)); 1727 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0); 1728 speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class); 1729 1730 field_a = 1; 1731 field_b = 1; 1732 field_c = 4; /* Default value for speeds other than 25G/50G/100G */ 1733 1734 if ((speed == 25000) || (speed == 27000)) { 1735 if (port_cl91_state) { 1736 field_c = 10; 1737 } 1738 else { 1739 field_c = 6; 1740 } 1741 } 1742 else if ((speed == 50000) || (speed == 53000) || 1743 (speed == 100000) || (speed == 106000)) { 1744 field_c= 6; 1745 } 1746 1747 /* Get lane, pipe & obm */ 1748 phy_port = si->port_l2p_mapping[port]; 1749 port_block_base = PORT_BLOCK_BASE_PORT(port); 1750 lane = phy_port - port_block_base; 1751 pipe = si->port_pipe[port]; 1752 clport = si->port_serdes[port]; 1753 if (SOC_IS_TOMAHAWK(unit)) { 1754 /* obm number is reversed (mirrored) in odd pipe */ 1755 obm = pipe & 1 ? 7 - (clport & 7) : clport & 7; 1756 } else { 1757 obm = clport & 15; 1758 } 1759 1760 #ifdef BCM_TOMAHAWK2_SUPPORT 1761 if (SOC_IS_TOMAHAWK2(unit)) { 1762 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 1763 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 1764 field_c = (mode == _SOC_TH_ASF_MODE_SAF) ? 1765 _soc_th2_asf_cfg_table[class].ifsaf_threshold.saf : 1766 _soc_th2_asf_cfg_table[class].ifsaf_threshold.ct; 1767 1768 /* TH2 only need adjust FIELD_C, others are set in _soc_tomahawk2_ing_fsaf_init */ 1769 SOC_IF_ERROR_RETURN( 1770 soc_reg32_get(unit, idb_obm_force_saf_config_reg[obm][pipe], 1771 REG_PORT_ANY, lane, &rval)); 1772 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 1773 FIELD_Cf, field_c); 1774 SOC_IF_ERROR_RETURN( 1775 soc_reg32_set(unit, idb_obm_force_saf_config_reg[obm][pipe], 1776 REG_PORT_ANY, lane, rval)); 1777 1778 return SOC_E_NONE; 1779 } 1780 #endif 1781 1782 SOC_IF_ERROR_RETURN( 1783 soc_reg32_get(unit, idb_obm_force_saf_config_reg[obm][pipe], 1784 REG_PORT_ANY, lane, &rval)); 1785 1786 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 1787 FIELD_Af, field_a); 1788 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 1789 FIELD_Bf, field_b); 1790 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 1791 FIELD_Cf, field_c); 1792 1793 SOC_IF_ERROR_RETURN( 1794 soc_reg32_set(unit, idb_obm_force_saf_config_reg[obm][pipe], 1795 REG_PORT_ANY, lane, rval)); 1796 1797 /* Now setup the IDB_FORCE_SAF_CONFIG register */ 1798 switch (si->frequency) { 1799 case 850: field_a = 1700; 1800 break; 1801 case 765: field_a = 1532; 1802 break; 1803 case 672: field_a = 1344; 1804 break; 1805 case 645: field_a = 1290; 1806 break; 1807 case 545: field_a = 1090; 1808 break; 1809 default: 1810 break; 1811 } 1812 1813 SOC_IF_ERROR_RETURN( 1814 soc_reg32_get(unit, idb_force_saf_config_reg[pipe], 1815 REG_PORT_ANY, 0, &rval)); 1816 soc_reg_field_set(unit, idb_force_saf_config_reg[pipe], &rval, 1817 FIELD_Af, field_a); 1818 SOC_IF_ERROR_RETURN( 1819 soc_reg32_set(unit, idb_force_saf_config_reg[pipe], 1820 REG_PORT_ANY, 0, rval)); 1821 1822 return SOC_E_NONE; 1823 } 1824 1825 int 1826 soc_th_port_asf_valid( 1827 int unit, 1828 soc_port_t port) 1829 { 1830 if (IS_CPU_PORT(((unit)), (port)) || IS_LB_PORT(((unit)), (port)) || \ 1831 SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) { 1832 return FALSE; 1833 } else { 1834 return TRUE; 1835 } 1836 } 1837 1838 /************************************* 1839 * Init Start Routine * 1840 * - Allocates ASF Ctrl structure * 1841 * for the given unit * 1842 */ 1843 int 1844 soc_th_asf_init_start(int unit) 1845 { 1846 _SOC_TH_UNIT_VALIDATE(unit); 1847 1848 if (!(_soc_th_asf_ctrl[unit] = 1849 sal_alloc(sizeof(_soc_th_asf_ctrl_t), "TH ASF Ctrl Area"))) { 1850 return SOC_E_MEMORY; 1851 } 1852 1853 sal_memset(_soc_th_asf_ctrl[unit], 0, sizeof(_soc_th_asf_ctrl_t)); 1854 1855 /* Get current switch latency mode */ 1856 SOC_IF_ERROR_RETURN( 1857 soc_th_latency_get(unit, &_soc_th_asf_ctrl[unit]->latency)); 1858 1859 /* ASF_MEM_PROFILE */ 1860 _soc_th_asf_ctrl[unit]->asf_mem_profile = 1861 soc_property_get(unit, spn_ASF_MEM_PROFILE, 1862 _SOC_TH_ASF_MEM_PROFILE_SIMILAR); 1863 if (!((_soc_th_asf_ctrl[unit]->asf_mem_profile >= 0) && 1864 (_soc_th_asf_ctrl[unit]->asf_mem_profile < 3))) { 1865 _soc_th_asf_ctrl[unit]->asf_mem_profile = 2; 1866 } 1867 1868 return SOC_E_NONE; 1869 } 1870 1871 int 1872 soc_asf_register_linkscan_cb(int unit) 1873 { 1874 int retVal; 1875 1876 /* Register linkscan callback routine */ 1877 retVal = bcm_esw_linkscan_register(unit, soc_th_asf_linkscan_callback); 1878 return retVal; 1879 } 1880 1881 /************************ 1882 * Init Complete Marker * 1883 */ 1884 int 1885 soc_th_asf_init_done(int unit) 1886 { 1887 _SOC_TH_UNIT_VALIDATE(unit); 1888 1889 if (_soc_th_asf_ctrl[unit]) { 1890 _soc_th_asf_ctrl[unit]->init = 1; 1891 LOG_DEBUG(BSL_LS_SOC_INIT, 1892 (BSL_META_U(unit, "*** unit %d: ports %s\n"), unit, 1893 asf_profile_str[_soc_th_asf_ctrl[unit]->asf_mem_profile])); 1894 return SOC_E_NONE; 1895 } else { 1896 return SOC_E_INTERNAL; 1897 } 1898 } 1899 1900 /****************************************************************************** 1901 * Name: soc_th_port_asf_init * 1902 * Description: * 1903 * Initialize ASF primitives for the specified port * 1904 * IN params: * 1905 * - Unit * 1906 * - Logical Port * 1907 * - Port Speed * 1908 * - ASF Mode * 1909 * Returns: * 1910 * - SOC_E_NONE on success * 1911 * - SOC_E_PARAM on invalid parameter * 1912 * - SOC_E_INIT on init/soc errors * 1913 */ 1914 int 1915 soc_th_port_asf_init( 1916 int unit, 1917 soc_port_t port, 1918 int speed, 1919 soc_th_asf_mode_e mode) 1920 { 1921 int speed_encoding; 1922 1923 _SOC_TH_UNIT_VALIDATE(unit); 1924 if (SOC_E_PARAM == (speed_encoding = _soc_th_speed_to_ct_class_map(speed))) { 1925 /* port on a speed unsupported by CT - will resort to SAF */ 1926 speed_encoding = 0; 1927 } 1928 1929 SOC_IF_ERROR_RETURN(soc_th_port_asf_mode_set(unit, port, speed, mode)); 1930 1931 return SOC_E_NONE; 1932 } 1933 1934 /************************ 1935 * Init Start Routine * 1936 */ 1937 int 1938 soc_th_asf_deinit(int unit) 1939 { 1940 _SOC_TH_UNIT_VALIDATE(unit); 1941 /* Unregister linkscan callback routine */ 1942 bcm_esw_linkscan_unregister(unit, soc_th_asf_linkscan_callback); 1943 1944 if (_soc_th_asf_ctrl[unit]) { 1945 sal_free(_soc_th_asf_ctrl[unit]); 1946 _soc_th_asf_ctrl[unit] = NULL; 1947 } 1948 1949 return SOC_E_NONE; 1950 } 1951 1952 /****************************************************************************** 1953 * Name: _soc_th_port_asf_xmit_start_count_set * 1954 * Description: * 1955 * Initialize XMIT START COUNT memory for all the source class for the * 1956 * specified port * 1957 * IN params: * 1958 * - Unit * 1959 * - Logical Port * 1960 * - Port Speed * 1961 * - ASF Mode * 1962 * - Extra cells (if any, to be added to xmit start count) * 1963 * Returns: * 1964 * - SOC_E_NONE on success * 1965 * - SOC_E_PARAM on invalid parameter * 1966 */ 1967 int 1968 soc_th_port_asf_xmit_start_count_set( 1969 int unit, 1970 soc_port_t port, 1971 int port_speed, 1972 soc_th_asf_mode_e mode, 1973 uint8 extra_cells) 1974 { 1975 egr_xmit_start_count_entry_t entry; 1976 soc_info_t *si = &SOC_INFO(unit); 1977 uint8 xmit_cnt = 0; 1978 int rv, src_class, dst_class = 0, port_idx; 1979 int pipe; 1980 soc_mem_t config_mem = INVALIDm; 1981 1982 if (!((mode >= _SOC_TH_ASF_MODE_SAF) && 1983 (mode <= _SOC_TH_ASF_MODE_CFG_UPDATE))) { 1984 return SOC_E_PARAM; 1985 } 1986 1987 if (_SOC_TH_ASF_MODE_CFG_UPDATE != mode) { 1988 if (SOC_E_PARAM == (dst_class = _soc_th_speed_to_ct_class_map(port_speed))) { 1989 /* port on a speed unsupported by CT - will resort to SAF */ 1990 dst_class = 0; 1991 } 1992 } 1993 1994 sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t)); 1995 1996 pipe = si->port_pipe[port]; 1997 config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe]; 1998 1999 for (src_class = 0; src_class < 13; src_class++) { 2000 if (_SOC_TH_ASF_MODE_CFG_UPDATE == mode) { 2001 xmit_cnt = _SOC_TH_ASF_RETRV; 2002 } else { 2003 xmit_cnt = _SOC_TH_ASF_QUERY; 2004 } 2005 2006 #ifdef BCM_TOMAHAWK2_SUPPORT 2007 if (SOC_IS_TOMAHAWK2(unit)) { 2008 rv = _soc_th2_port_asf_xmit_start_count_get(unit, port, src_class, 2009 dst_class, mode, &xmit_cnt); 2010 } else 2011 #endif 2012 { 2013 rv = _soc_th_port_asf_xmit_start_count_get(unit, port, src_class, 2014 dst_class, mode, &xmit_cnt); 2015 } 2016 if (SOC_FAILURE(rv)) { 2017 if (SOC_E_UNAVAIL == rv) { 2018 xmit_cnt = 18; 2019 } else { 2020 return rv; 2021 } 2022 } 2023 2024 xmit_cnt += extra_cells; 2025 2026 port_idx = ((port % 34) * 16) + src_class; 2027 2028 soc_mem_field32_set(unit, config_mem, &entry, 2029 THRESHOLDf, xmit_cnt); 2030 SOC_IF_ERROR_RETURN(soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 2031 port_idx, &entry)); 2032 } 2033 2034 return SOC_E_NONE; 2035 } 2036 2037 /****************************************************************************** 2038 * Name: soc_th_port_asf_mode_get * 2039 * Description: * 2040 * Retrieve the ASF/SAF mode configured on the specified port * 2041 * IN params: * 2042 * - Unit * 2043 * - Logical Port * 2044 * - Port Speed * 2045 * OUT params: * 2046 * - mode : OUT: contains the ASF/SAF mode confiugred on the specified * 2047 * port on success * 2048 * Returns: * 2049 * - SOC_E_NONE on success * 2050 * - SOC_E_PARAM on invalid parameter * 2051 * - SOC_E_INTERNAL on init/soc errors * 2052 */ 2053 int 2054 soc_th_port_asf_mode_get( 2055 int unit, 2056 soc_port_t port, 2057 int port_speed, 2058 OUT soc_th_asf_mode_e* const mode) 2059 { 2060 uint32 rval; 2061 int speed_encoding; 2062 uint8 max_sp, min_sp, enable; 2063 2064 _SOC_TH_UNIT_VALIDATE(unit); 2065 if (!mode) { 2066 return SOC_E_INTERNAL; 2067 } 2068 2069 if (soc_th_port_asf_valid(unit, port)) { 2070 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 2071 enable = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, ENABLEf); 2072 if (!enable) { 2073 *mode = _SOC_TH_ASF_MODE_SAF; 2074 return SOC_E_NONE; 2075 } 2076 } else { 2077 *mode = _SOC_TH_ASF_MODE_SAF; 2078 return SOC_E_NONE; 2079 } 2080 2081 if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->init) { 2082 return SOC_E_INTERNAL; 2083 } 2084 2085 max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MAX_SRC_PORT_SPEEDf); 2086 min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MIN_SRC_PORT_SPEEDf); 2087 2088 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 2089 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 2090 2091 if (max_sp && min_sp) { 2092 if (max_sp == min_sp) { 2093 if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) { 2094 *mode = _SOC_TH_ASF_MODE_SLOW_TO_FAST; 2095 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) { 2096 *mode = _SOC_TH_ASF_MODE_FAST_TO_SLOW; 2097 } else { 2098 *mode = _SOC_TH_ASF_MODE_SAME_SPEED; 2099 } 2100 } else if (max_sp == speed_encoding) { 2101 *mode = _SOC_TH_ASF_MODE_SLOW_TO_FAST; 2102 } 2103 else if (min_sp == speed_encoding) { 2104 *mode = _SOC_TH_ASF_MODE_FAST_TO_SLOW; 2105 } else { 2106 *mode = _SOC_TH_ASF_MODE_UNSUPPORTED; 2107 return SOC_E_UNAVAIL; 2108 } 2109 } else { 2110 *mode = _SOC_TH_ASF_MODE_UNSUPPORTED; 2111 return SOC_E_UNAVAIL; 2112 } 2113 2114 return SOC_E_NONE; 2115 } 2116 2117 /****************************************************************************** 2118 * Name: soc_th_port_asf_mode_set * 2119 * Description: * 2120 * Configure specified ASF/SAF modes on the specified port * 2121 * IN params: * 2122 * - Unit * 2123 * - Logical Port * 2124 * - Port Speed * 2125 * - ASF Mode * 2126 * OUT params: * 2127 * - None * 2128 * Returns: * 2129 * - SOC_E_NONE on success * 2130 * - SOC_E_PARAM on invalid parameter * 2131 * - SOC_E_INTERNAL on init/soc errors * 2132 */ 2133 int 2134 soc_th_port_asf_mode_set( 2135 int unit, 2136 soc_port_t port, 2137 int port_speed, 2138 soc_th_asf_mode_e mode) 2139 { 2140 int ret, speed_encoding = 0, pause_enable = 0, txp = 0, rxp = 0; 2141 uint8 min_sp = 0, max_sp = 0; 2142 uint8 fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0; 2143 uint8 oversub = 0, ca_thresh = 0; 2144 uint8 bubble_mop_disable = 0; 2145 uint32 rval; 2146 soc_info_t *si = NULL; 2147 mac_driver_t *macd; 2148 int latency = SOC_SWITCH_BYPASS_MODE_NONE; 2149 int init = 0; 2150 int ct_class = 0, original_speed = 0; 2151 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 2152 uint32 port_cl91_state; 2153 uint32 ct_ok_thresh; 2154 2155 _SOC_TH_UNIT_VALIDATE(unit); 2156 2157 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 2158 2159 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 2160 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 2161 2162 if (port_cl91_state) { 2163 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 2164 } 2165 2166 if (_SOC_TH_ASF_MODE_INIT == mode) { 2167 init = 1; 2168 mode = _SOC_TH_ASF_MODE_SAF; 2169 } 2170 if ((!init) && (!_soc_th_asf_ctrl[unit] || 2171 !_soc_th_asf_ctrl[unit]->init || !(si = &SOC_INFO(unit)))) { 2172 return SOC_E_INTERNAL; 2173 } 2174 if (!_soc_th_asf_ctrl[unit]->asf_mem_profile) { /* no cut-thru profile */ 2175 if ((_SOC_TH_ASF_MODE_SAF != mode) && 2176 (_SOC_TH_ASF_MODE_CFG_UPDATE != mode)) { 2177 return SOC_E_UNAVAIL; 2178 } 2179 } 2180 if (!soc_th_port_asf_valid(unit, port)) { 2181 if ((_SOC_TH_ASF_MODE_SAF != mode) && 2182 (_SOC_TH_ASF_MODE_CFG_UPDATE != mode)) { 2183 return SOC_E_UNAVAIL; 2184 } 2185 SOC_IF_ERROR_RETURN( 2186 soc_th_port_asf_xmit_start_count_set(unit, port, port_speed, 2187 mode, 0)); 2188 return SOC_E_NONE; 2189 } 2190 2191 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 2192 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 2193 2194 /* min. and max. src port speeds */ 2195 if (_SOC_TH_ASF_MODE_CFG_UPDATE != mode) { 2196 min_sp = max_sp = _SOC_TH_ASF_QUERY; 2197 SOC_IF_ERROR_RETURN( 2198 _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode, 2199 &min_sp, &max_sp)); 2200 } 2201 2202 /* mode specific configurations */ 2203 switch(mode) { 2204 case _SOC_TH_ASF_MODE_SAF: 2205 break; 2206 2207 case _SOC_TH_ASF_MODE_SAME_SPEED: 2208 /* Cannot set cut-through mode for 1G ports */ 2209 if (1000 == port_speed) { 2210 return SOC_E_UNAVAIL; 2211 } 2212 /* verify mode specific conformance */ 2213 if (min_sp != max_sp) { 2214 return SOC_E_PARAM; 2215 } 2216 break; 2217 2218 case _SOC_TH_ASF_MODE_SLOW_TO_FAST: 2219 /* Cannot set cut-through mode for 1G ports */ 2220 if (1000 == port_speed) { 2221 return SOC_E_UNAVAIL; 2222 } 2223 /* verify mode specific conformance */ 2224 if ( !((min_sp >= 2225 _soc_th_asf_cfg_table[speed_encoding].min_sp) && 2226 (max_sp == speed_encoding)) ) { 2227 return SOC_E_PARAM; 2228 } 2229 break; 2230 2231 case _SOC_TH_ASF_MODE_FAST_TO_SLOW: 2232 /* Cannot set cut-through mode for 1G ports */ 2233 if (1000 == port_speed) { 2234 return SOC_E_UNAVAIL; 2235 } 2236 /* verify mode specific conformance */ 2237 if ( !((max_sp <= 2238 _soc_th_asf_cfg_table[speed_encoding].max_sp) && 2239 (min_sp == speed_encoding)) ) { 2240 return SOC_E_PARAM; 2241 } 2242 break; 2243 2244 case _SOC_TH_ASF_MODE_CFG_UPDATE: 2245 SOC_IF_ERROR_RETURN( 2246 _soc_th_port_asf_class_get(unit, port, &ct_class)); 2247 original_speed = _soc_th_asf_cfg_table[ct_class].speed; 2248 ret = soc_th_port_asf_mode_get(unit, port, original_speed, &mode); 2249 if (SOC_E_NONE != ret) { 2250 mode = _SOC_TH_ASF_MODE_SAF; 2251 } 2252 2253 /* disable CT first */ 2254 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 2255 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2256 FIFO_THRESHOLDf, 0); 2257 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2258 sal_usleep(1); 2259 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0); 2260 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2261 2262 /* update new settings & re-enable */ 2263 ret = soc_th_port_asf_mode_set(unit, port, port_speed, mode); 2264 return ret; 2265 2266 default: 2267 return SOC_E_PARAM; 2268 } 2269 2270 if (SOC_IS_TOMAHAWK(unit)) { 2271 SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd)); 2272 } 2273 2274 /* ASF_IPORT_CFG */ 2275 SOC_IF_ERROR_RETURN(READ_ASF_IPORT_CFGr(unit, port, &rval)); 2276 soc_reg_field_set(unit, ASF_IPORT_CFGr, &rval, ASF_PORT_SPEEDf, 2277 port_speed == 1000 ? 0: speed_encoding); 2278 SOC_IF_ERROR_RETURN(WRITE_ASF_IPORT_CFGr(unit, port, rval)); 2279 2280 /* init CT class */ 2281 SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_init(unit, port, speed_encoding)); 2282 2283 if (_SOC_TH_ASF_MODE_SAF != mode) { 2284 /* Oversub */ 2285 oversub = (SOC_PBMP_MEMBER(si->oversub_pbm, port) ? 1 : 0); 2286 2287 #ifdef BCM_TOMAHAWK2_SUPPORT 2288 if (SOC_IS_TOMAHAWK2(unit)) { 2289 /* FIFO threshold */ 2290 fifo_threshold = _SOC_TH_ASF_QUERY; 2291 SOC_IF_ERROR_RETURN( 2292 _soc_th2_port_asf_fifo_threshold_get(unit, port, port_speed, mode, 2293 min_sp, &fifo_threshold)); 2294 2295 /* FIFO depth */ 2296 fifo_depth = _SOC_TH_ASF_QUERY; 2297 SOC_IF_ERROR_RETURN( 2298 _soc_th2_port_asf_fifo_depth_get(unit, port, port_speed, mode, 2299 min_sp, &fifo_depth)); 2300 2301 /* MMU Prebuffer */ 2302 mmu_prebuf = _SOC_TH_ASF_QUERY; 2303 SOC_IF_ERROR_RETURN( 2304 _soc_th2_port_asf_mmu_prebuf_get(unit, port, port_speed, 2305 min_sp, &mmu_prebuf)); 2306 } else 2307 #endif 2308 { 2309 /* FIFO threshold */ 2310 fifo_threshold = _SOC_TH_ASF_QUERY; 2311 SOC_IF_ERROR_RETURN( 2312 _soc_th_port_asf_fifo_threshold_get(unit, port, port_speed, mode, 2313 min_sp, &fifo_threshold)); 2314 2315 /* FIFO depth */ 2316 fifo_depth = _SOC_TH_ASF_QUERY; 2317 SOC_IF_ERROR_RETURN( 2318 _soc_th_port_asf_fifo_depth_get(unit, port, port_speed, mode, 2319 min_sp, &fifo_depth)); 2320 2321 /* MMU Prebuffer */ 2322 mmu_prebuf = _SOC_TH_ASF_QUERY; 2323 SOC_IF_ERROR_RETURN( 2324 _soc_th_port_asf_mmu_prebuf_get(unit, port, port_speed, 2325 min_sp, &mmu_prebuf)); 2326 } 2327 2328 /* Disable BubbleMOP for low latency mode */ 2329 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 2330 #ifdef BCM_TOMAHAWK2_SUPPORT 2331 if (SOC_IS_TOMAHAWK2(unit)) { 2332 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 2333 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 2334 bubble_mop_disable = oversub ? 2335 !(_soc_th2_asf_cfg_table[speed_encoding].mop_enable.oversub[latency]) : 2336 !(_soc_th2_asf_cfg_table[speed_encoding].mop_enable.line_rate[latency]); 2337 } else 2338 #endif 2339 { 2340 /* special cases: 10G & HG[11] */ 2341 if ((SOC_SWITCH_BYPASS_MODE_LOW == latency) && 2342 ((1 == speed_encoding) || (2 == speed_encoding))) { 2343 bubble_mop_disable = 1; 2344 } else { 2345 bubble_mop_disable = 0; 2346 } 2347 } 2348 2349 pause_enable = 0; 2350 ca_thresh = 4; 2351 ct_ok_thresh = 0; 2352 2353 if (port_cl91_state) { 2354 if ((port_speed == 50000) || (port_speed == 53000) || 2355 (port_speed == 100000) || (port_speed == 106000)) { 2356 ca_thresh = 6; 2357 } 2358 if ((port_speed == 25000) || (port_speed == 27000)) { 2359 ct_ok_thresh = (SOC_IS_TOMAHAWK2(unit) ? 15 : 5); 2360 } 2361 } 2362 2363 SOC_IF_ERROR_RETURN( 2364 _soc_th_asf_obm_ct_thresh_ok_set(unit, port, ct_ok_thresh)); 2365 2366 SOC_IF_ERROR_RETURN( 2367 soc_th_port_asf_params_set(unit, port, port_speed, mode, 2368 bubble_mop_disable, ca_thresh, 2369 speed_encoding)); 2370 2371 if (SOC_IS_TOMAHAWK(unit)) { 2372 /* PAUSE */ 2373 SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp)); 2374 if (rxp) { 2375 SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->pause_restore, port); 2376 } 2377 rxp = pause_enable; 2378 SOC_IF_ERROR_RETURN(MAC_PAUSE_SET(macd, unit, port, txp, rxp)); 2379 } 2380 2381 /* drain the port CT FIFO */ 2382 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 2383 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 1); 2384 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0); 2385 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2386 2387 sal_usleep(1); 2388 2389 /* enable cut-through */ 2390 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub); 2391 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2392 MAX_SRC_PORT_SPEEDf, max_sp); 2393 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2394 MIN_SRC_PORT_SPEEDf, min_sp); 2395 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2396 MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf); 2397 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2398 FIFO_THRESHOLDf, fifo_threshold); 2399 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf, 2400 fifo_depth); 2401 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2402 2403 /* bookkeeping */ 2404 if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_ss, port)) { 2405 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ss, port); 2406 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) { 2407 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_sf, port); 2408 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) { 2409 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_fs, port); 2410 } 2411 SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_ports, port); 2412 if (_SOC_TH_ASF_MODE_SAME_SPEED == mode) { 2413 SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_ss, port); 2414 } else if (_SOC_TH_ASF_MODE_SLOW_TO_FAST== mode) { 2415 SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_sf, port); 2416 } else if (_SOC_TH_ASF_MODE_FAST_TO_SLOW== mode) { 2417 SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_fs, port); 2418 } 2419 } else { /* Store and Forward */ 2420 fifo_depth = 0x40; 2421 fifo_threshold = 0x20; 2422 mmu_prebuf = 0; 2423 min_sp = 0; 2424 max_sp = 0; 2425 oversub = 0; 2426 pause_enable = 1; 2427 ca_thresh = 4; 2428 bubble_mop_disable = 0; 2429 2430 if (1000 == port_speed) { 2431 pause_enable = 0; 2432 } 2433 2434 if (SOC_IS_TOMAHAWK(unit)) { 2435 SOC_IF_ERROR_RETURN( 2436 _soc_th_asf_obm_ct_thresh_ok_set(unit, port, 0)); 2437 } 2438 2439 SOC_IF_ERROR_RETURN( 2440 soc_th_port_asf_params_set(unit, port, port_speed, mode, 2441 bubble_mop_disable, ca_thresh, 2442 speed_encoding)); 2443 2444 /* ASF_EPORT_CFG */ 2445 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 2446 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0); 2447 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2448 2449 sal_usleep(1); 2450 2451 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0); 2452 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2453 2454 /* update SAF configs */ 2455 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 2456 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub); 2457 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2458 MAX_SRC_PORT_SPEEDf, max_sp); 2459 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2460 MIN_SRC_PORT_SPEEDf, min_sp); 2461 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2462 MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf); 2463 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 2464 FIFO_THRESHOLDf, fifo_threshold); 2465 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf, 2466 fifo_depth); 2467 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 2468 2469 if (SOC_IS_TOMAHAWK(unit)) { 2470 /* restore pause */ 2471 if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->pause_restore, port)) { 2472 SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp)); 2473 rxp = 1; 2474 SOC_IF_ERROR_RETURN(MAC_PAUSE_SET(macd, unit, port, txp, rxp)); 2475 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->pause_restore, port); 2476 } 2477 } 2478 2479 /* bookkeeping */ 2480 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ports, port); 2481 if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_ss, port)) { 2482 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ss, port); 2483 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) { 2484 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_sf, port); 2485 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) { 2486 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_fs, port); 2487 } 2488 } 2489 2490 return SOC_E_NONE; 2491 } 2492 2493 /****************************************************************************** 2494 * Name: soc_th_port_asf_params_set * 2495 * Description: * 2496 * Configure ASF/SAF mode params on the specified port * 2497 * IN params: * 2498 * - Unit * 2499 * - Logical Port * 2500 * - Port Speed * 2501 * - ASF Mode * 2502 * - Bubble MOP disable flag * 2503 * - CA Threshold * 2504 * - Speed Encoding * 2505 * OUT params: * 2506 * - None * 2507 * Returns: * 2508 * - SOC_E_NONE on success * 2509 * - SOC_E_PARAM on invalid parameter * 2510 * - SOC_E_INTERNAL on init/soc errors * 2511 */ 2512 int 2513 soc_th_port_asf_params_set( 2514 int unit, 2515 soc_port_t port, 2516 int port_speed, 2517 soc_th_asf_mode_e mode, 2518 uint8 bubble_mop_disable, 2519 uint8 ca_thresh, 2520 int speed_encoding) 2521 { 2522 uint32 mmu_ep_credits = 0, egr_mmu_cell_credits = 0; 2523 uint32 rval; 2524 soc_info_t *si = NULL; 2525 uint8 oversub; 2526 #if defined(BCM_TOMAHAWK2_SUPPORT) 2527 egr_mmu_cell_credit_entry_t credit_entry; 2528 #endif 2529 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 2530 uint32 port_cl91_state; 2531 2532 if (!(si = &SOC_INFO(unit))) { 2533 return SOC_E_INTERNAL; 2534 } 2535 2536 /* If oversub mode, setup Ingress Force SAF registers */ 2537 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 2538 if (oversub) { 2539 _soc_th_asf_force_saf_config_set(unit, port, mode); 2540 } 2541 2542 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 2543 2544 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 2545 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 2546 2547 if (port_cl91_state) { 2548 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 2549 } 2550 2551 /* EDB Prebuffer */ 2552 SOC_IF_ERROR_RETURN( 2553 soc_th_port_asf_xmit_start_count_set(unit, port, port_speed, 2554 mode, 0)); 2555 /* OBM Cell Assembly FIFO threshold */ 2556 SOC_IF_ERROR_RETURN( 2557 _soc_th_asf_obm_ca_fifo_thresh_set(unit, port, ca_thresh)); 2558 2559 /* BubbleMOP - At present only L3 & Full Latency Mode supported */ 2560 SOC_IF_ERROR_RETURN( 2561 _soc_th_asf_obm_bubble_mop_set(unit, port, bubble_mop_disable)); 2562 2563 /* MMU EP Credit Threshold */ 2564 #if defined(BCM_TOMAHAWK2_SUPPORT) 2565 if (SOC_IS_TOMAHAWK2(unit)) { 2566 int ovs_ratio = 0; 2567 uint8 mmu_ep_credits_lo = 0; 2568 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 2569 2570 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 2571 2572 SOC_IF_ERROR_RETURN( 2573 soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio)); 2574 if ((1700 == si->frequency) && (ovs_ratio <= 1500)) { 2575 mmu_ep_credits_lo = 2576 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.lr_os_1_5.lo; 2577 mmu_ep_credits = 2578 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.lr_os_1_5.hi; 2579 } else { 2580 mmu_ep_credits_lo = 2581 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.os_2_1.lo; 2582 mmu_ep_credits = 2583 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.os_2_1.hi; 2584 } 2585 2586 /* ASF_CREDIT_THRESH_LO */ 2587 SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_LOr(unit, port, &rval)); 2588 soc_reg_field_set(unit, ASF_CREDIT_THRESH_LOr, &rval, THRESHf, 2589 mmu_ep_credits_lo); 2590 SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_LOr(unit, port, rval)); 2591 } else 2592 #endif 2593 { 2594 if (CCLK_FREQ_850MHZ <= si->frequency) { 2595 mmu_ep_credits = 2596 _soc_th_asf_cfg_table[speed_encoding].mmu_ep_credit.pfc_op_cells; 2597 } else { 2598 mmu_ep_credits = 2599 _soc_th_asf_cfg_table[speed_encoding].mmu_ep_credit.base_cells; 2600 } 2601 } 2602 /* ASF_CREDIT_THRESH_HI */ 2603 SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval)); 2604 soc_reg_field_set(unit, ASF_CREDIT_THRESH_HIr, &rval, THRESHf, 2605 mmu_ep_credits); 2606 SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_HIr(unit, port, rval)); 2607 2608 /* EP credits outstanding */ 2609 SOC_IF_ERROR_RETURN( 2610 soc_th_port_asf_speed_to_mmu_cell_credit(unit, port, port_speed, 2611 &egr_mmu_cell_credits)); 2612 2613 /* EGR_MMU_CELL_CREDIT */ 2614 #if defined(BCM_TOMAHAWK2_SUPPORT) 2615 if (soc_feature(unit, soc_feature_egr_mmu_cell_credit_is_memory)) { 2616 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 2617 si->port_l2p_mapping[port], &credit_entry)); 2618 soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &credit_entry, CREDITf, 2619 egr_mmu_cell_credits); 2620 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ALL, 2621 si->port_l2p_mapping[port], &credit_entry)); 2622 } else 2623 #endif 2624 { 2625 if (SOC_MEM_IS_VALID(unit, EGR_MMU_CELL_CREDITm)) { 2626 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_MMU_CELL_CREDITm, 2627 port, CREDITf, egr_mmu_cell_credits)); 2628 } else { 2629 /* EGR_MMU_CELL_CREDIT */ 2630 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITr(unit, port, &rval)); 2631 soc_reg_field_set(unit, EGR_MMU_CELL_CREDITr, &rval, CREDITf, 2632 egr_mmu_cell_credits); 2633 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITr(unit, port, rval)); 2634 } 2635 } 2636 2637 return SOC_E_NONE; 2638 } 2639 2640 /****************************************************************************** 2641 * Name: soc_th_port_asf_speed_to_mmu_cell_credit * 2642 * Description: * 2643 * Retrieve mmu_cell_credit based on port speed configured. * 2644 * Helper function for misc init. * 2645 * IN params: * 2646 * - Unit * 2647 * - Logical Port * 2648 * - Port Speed * 2649 * OUT params: * 2650 * - MMU Cell credit * 2651 * Returns: * 2652 * - SOC_E_XXX on success * 2653 */ 2654 int 2655 soc_th_port_asf_speed_to_mmu_cell_credit( 2656 int unit, 2657 soc_port_t port, 2658 int port_speed, 2659 OUT uint32 *mmu_cell_credit) 2660 { 2661 int speed_encoding = 0; 2662 soc_info_t *si = NULL; 2663 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 2664 uint32 port_cl91_state; 2665 2666 _SOC_TH_UNIT_VALIDATE(unit); 2667 2668 if (NULL == mmu_cell_credit) { 2669 return SOC_E_PARAM; 2670 } 2671 2672 if (!(si = &SOC_INFO(unit))) { 2673 return SOC_E_INTERNAL; 2674 } 2675 2676 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 2677 2678 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 2679 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 2680 2681 if (port_cl91_state) { 2682 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 2683 } 2684 2685 speed_encoding = _soc_th_speed_to_ct_class_map(port_speed); 2686 _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 2687 2688 #if defined(BCM_TOMAHAWK2_SUPPORT) 2689 if (SOC_IS_TOMAHAWK2(unit)) { 2690 int ovs_ratio = 0; 2691 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 2692 2693 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 2694 SOC_IF_ERROR_RETURN( 2695 soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio)); 2696 if (IS_CPU_PORT(unit, port)) { 2697 speed_encoding = 3; /* 20G for CPU */ 2698 } else if (IS_LB_PORT(unit, port)) { 2699 speed_encoding = 11; /* 100G for LB */ 2700 } 2701 /* At MAX FREQ, the ovs_ratio will always be less than 3:2; 2702 * Still add that check 2703 */ 2704 if ((1700 == si->frequency) && (ovs_ratio <= 1500)) { 2705 *mmu_cell_credit = 2706 _soc_th2_asf_cfg_table[speed_encoding].ep_credit.pfc_op_cells; 2707 } else { 2708 *mmu_cell_credit = 2709 _soc_th2_asf_cfg_table[speed_encoding].ep_credit.base_cells; 2710 } 2711 } else 2712 #endif 2713 { 2714 if (CCLK_FREQ_850MHZ == si->frequency) { 2715 *mmu_cell_credit = (speed_encoding ? 2716 _soc_th_asf_cfg_table[speed_encoding].egr_mmu_credit.pfc_op_cells : 2717 11); 2718 } else { 2719 *mmu_cell_credit = (speed_encoding ? 2720 _soc_th_asf_cfg_table[speed_encoding].egr_mmu_credit.base_cells : 2721 13); 2722 } 2723 } 2724 2725 return SOC_E_NONE; 2726 } 2727 2728 /****************************************************************************** 2729 * Name: soc_th_port_asf_mmu_cell_credit_to_port_speed * 2730 * Description: * 2731 * Retrieve port speed based on mmu_cell_credit configured. * 2732 * Helper function for MAC driver speed get. * 2733 * IN params: * 2734 * - Unit * 2735 * - Logical Port * 2736 * - MMU Cell credit * 2737 * OUT params: * 2738 * - Port speed * 2739 * Returns: * 2740 * - SOC_E_XXX on success * 2741 */ 2742 int 2743 soc_th_port_asf_mmu_cell_credit_to_speed( 2744 int unit, 2745 soc_port_t port, 2746 uint8 mmu_cell_credit, 2747 OUT int *port_speed) 2748 { 2749 int i, freq; 2750 uint8 cell_credit; 2751 int speed; 2752 soc_info_t *si = NULL; 2753 const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table; 2754 uint32 port_cl91_state; 2755 #if defined (BCM_TOMAHAWK_SUPPORT) 2756 uint8 oversub; 2757 int port_mode; 2758 uint32 rval; 2759 #endif 2760 2761 _SOC_TH_UNIT_VALIDATE(unit); 2762 2763 if (NULL == port_speed) { 2764 return SOC_E_PARAM; 2765 } 2766 2767 if (!(si = &SOC_INFO(unit))) { 2768 return SOC_E_INTERNAL; 2769 } 2770 2771 #if defined (BCM_TOMAHAWK_SUPPORT) 2772 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 2773 #endif 2774 2775 /* Special case for 1G ports since 1G ports use same setting as 10G port */ 2776 if (1000 == (speed = si->port_init_speed[port])) { /* Use cached speed instead */ 2777 *port_speed = speed; 2778 return SOC_E_NONE; 2779 } 2780 2781 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl; 2782 2783 /* Get the FEC/CL91 state of the port to choose correct CT parameters */ 2784 SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state)); 2785 2786 if (port_cl91_state) { 2787 _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec; 2788 } 2789 2790 freq = si->frequency; 2791 for (i = 1; i < (COUNTOF(_soc_th_asf_cfg_tbl) - 1); i++) { 2792 #if defined(BCM_TOMAHAWK2_SUPPORT) 2793 if (SOC_IS_TOMAHAWK2(unit)) { 2794 int ovs_ratio = 0; 2795 const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table; 2796 2797 _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state); 2798 SOC_IF_ERROR_RETURN( 2799 soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio)); 2800 /* At max frequency, use the 1.5 ratio settings. 2801 * For all other cases, use the 1.5 ratio as the threshold to 2802 * determine which settings to use. 2803 */ 2804 cell_credit = ((1700 == freq) && (ovs_ratio <= 1500)) ? 2805 _soc_th2_asf_cfg_table[i].ep_credit.pfc_op_cells : 2806 _soc_th2_asf_cfg_table[i].ep_credit.base_cells; 2807 } else 2808 #endif 2809 { 2810 cell_credit = (CCLK_FREQ_850MHZ == freq) ? 2811 _soc_th_asf_cfg_table[i].egr_mmu_credit.pfc_op_cells : 2812 _soc_th_asf_cfg_table[i].egr_mmu_credit.base_cells; 2813 } 2814 if (mmu_cell_credit == cell_credit) { 2815 #if defined (BCM_TOMAHAWK_SUPPORT) 2816 if (oversub && 2817 mmu_cell_credit == 16) { /* 16 is EDB credit value for 25G/20G */ 2818 SOC_IF_ERROR_RETURN(READ_CLPORT_MODE_REGr(unit, port, &rval)); 2819 port_mode = soc_reg_field_get(unit, CLPORT_MODE_REGr, rval, 2820 XPORT0_CORE_PORT_MODEf); 2821 if (!port_mode) { 2822 *port_speed = IS_HG_PORT(unit, port) ? 27000 : 25000; 2823 return SOC_E_NONE; 2824 } 2825 } 2826 #endif 2827 if (IS_HG_PORT(unit, port)) { 2828 *port_speed = _soc_th_asf_cfg_table[i + 1].speed; 2829 } else { 2830 *port_speed = _soc_th_asf_cfg_table[i].speed; 2831 } 2832 #if defined(BCM_TOMAHAWK2_SUPPORT) 2833 if (SOC_IS_TOMAHAWK2(unit)) { 2834 if (SOC_E_NONE != 2835 soc_th_port_speed_supported(unit, port, *port_speed)) { 2836 continue; 2837 } 2838 } 2839 #endif 2840 return SOC_E_NONE; 2841 } 2842 } 2843 2844 return SOC_E_NOT_FOUND; 2845 } 2846 2847 /****************************************************************************** 2848 * Name: soc_th_port_asf_pause_bpmp_get * 2849 * Description: * 2850 * Get pointer of pause_restore bitmap for update * 2851 * IN params: * 2852 * - Unit * 2853 * OUT params: * 2854 * * 2855 * Returns: * 2856 * - Pointer of pause_restore bitmap * 2857 */ 2858 pbmp_t * 2859 soc_th_port_asf_pause_bpmp_get(int unit) 2860 { 2861 if (_soc_th_asf_ctrl[unit] == NULL) { 2862 return NULL; 2863 } 2864 return &_soc_th_asf_ctrl[unit]->pause_restore; 2865 } 2866 2867 /************************ 2868 * ASF Warmboot Support * 2869 */ 2870 #ifdef BCM_WARM_BOOT_SUPPORT 2871 2872 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 2873 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 2874 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1,2) 2875 #define BCM_WB_VERSION_1_3 SOC_SCACHE_VERSION(1,3) 2876 #define BCM_WB_VERSION_1_4 SOC_SCACHE_VERSION(1,4) 2877 #define BCM_WB_VERSION_1_5 SOC_SCACHE_VERSION(1,5) 2878 #define BCM_WB_VERSION_1_6 SOC_SCACHE_VERSION(1,6) 2879 #define BCM_WB_VERSION_1_7 SOC_SCACHE_VERSION(1,7) 2880 #define BCM_WB_VERSION_1_8 SOC_SCACHE_VERSION(1,8) 2881 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_8 2882 2883 int 2884 soc_th_asf_wb_memsz_get( 2885 int unit, 2886 OUT uint32* const mem_sz, 2887 uint16 scache_ver) 2888 { 2889 _SOC_TH_UNIT_VALIDATE(unit); 2890 if (!mem_sz) { 2891 return SOC_E_PARAM; 2892 } 2893 *mem_sz = 0; 2894 2895 if (!SOC_WARM_BOOT(unit)) { 2896 if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->asf_mem_profile) { 2897 return SOC_E_UNAVAIL; 2898 } 2899 if (!_soc_th_asf_ctrl[unit]->init) { 2900 return SOC_E_INTERNAL; 2901 } 2902 } 2903 2904 *mem_sz = sizeof(_soc_th_asf_wb_t); 2905 2906 if (scache_ver < BCM_WB_VERSION_1_8) { 2907 /* adjust wb area sz for lower versions */ 2908 *mem_sz -= sizeof(int); 2909 } 2910 2911 return SOC_E_NONE; 2912 } 2913 2914 int 2915 soc_th_asf_wb_sync( 2916 int unit, 2917 IN_OUT uint8* const wb_data) 2918 { 2919 _soc_th_asf_wb_t *wbd; 2920 2921 _SOC_TH_UNIT_VALIDATE(unit); 2922 if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->asf_mem_profile) { 2923 return SOC_E_UNAVAIL; 2924 } 2925 if (!_soc_th_asf_ctrl[unit]->init) { 2926 return SOC_E_INTERNAL; 2927 } 2928 if (!wb_data) { 2929 return SOC_E_PARAM; 2930 } 2931 2932 wbd = (_soc_th_asf_wb_t *) wb_data; 2933 wbd->unit = unit; 2934 sal_memcpy(&wbd->asf_ctrl, _soc_th_asf_ctrl[unit], 2935 sizeof(_soc_th_asf_ctrl_t)); 2936 2937 return SOC_E_NONE; 2938 } 2939 2940 int 2941 soc_th_asf_wb_recover( 2942 int unit, 2943 uint8* const wb_data, 2944 uint16 scache_ver) 2945 { 2946 _soc_th_asf_wb_t *wbd; 2947 int adj = 0; /*scache ver adjustment */ 2948 2949 _SOC_TH_UNIT_VALIDATE(unit); 2950 if (!SOC_WARM_BOOT(unit)) { 2951 return SOC_E_INTERNAL; 2952 } 2953 if (!wb_data) { 2954 return SOC_E_PARAM; 2955 } 2956 2957 wbd = (_soc_th_asf_wb_t *) wb_data; 2958 if (wbd->unit == unit) { 2959 if (!(_soc_th_asf_ctrl[unit] = 2960 sal_alloc(sizeof(_soc_th_asf_ctrl_t), "TH ASF Ctrl Area"))) { 2961 return SOC_E_MEMORY; 2962 } 2963 2964 if (scache_ver < BCM_WB_VERSION_1_8) { 2965 /* adjust for lower versions */ 2966 adj = sizeof(int); 2967 /* backfill latency querying latency subsystem */ 2968 SOC_IF_ERROR_RETURN( 2969 soc_th_latency_get(unit, &_soc_th_asf_ctrl[unit]->latency)); 2970 } 2971 2972 sal_memcpy(_soc_th_asf_ctrl[unit], &wbd->asf_ctrl, 2973 (sizeof(_soc_th_asf_ctrl_t) - adj)); 2974 } 2975 2976 LOG_CLI((BSL_META_U(unit, "*** unit %d: MMU-ASF subsystem warmbooted: " 2977 "ports %s\n"), unit, 2978 asf_profile_str[_soc_th_asf_ctrl[unit]->asf_mem_profile])); 2979 2980 return SOC_E_NONE; 2981 } 2982 #endif /* BCM_WARM_BOOT_SUPPORT */ 2983 2984 /********************** 2985 * ASF Debug Support * 2986 */ 2987 int 2988 soc_th_asf_pbmp_get(int unit) 2989 { 2990 char pfmt[SOC_PBMP_FMT_LEN]; 2991 2992 _SOC_TH_UNIT_VALIDATE(unit); 2993 if (!_soc_th_asf_ctrl[unit]->init) { 2994 return SOC_E_INTERNAL; 2995 } 2996 2997 LOG_CLI(("ASF PBMP: %s\n", 2998 SOC_PBMP_FMT(_soc_th_asf_ctrl[unit]->asf_ports, pfmt))); 2999 3000 return SOC_E_NONE; 3001 } 3002 3003 int 3004 soc_th_port_asf_show( 3005 int unit, 3006 soc_port_t port, 3007 int port_speed) 3008 { 3009 int ret; 3010 char mode_str[4][15] = {"SAF", "Same speed ", "Slow to Fast", 3011 "Fast to Slow"}; 3012 char speed_str[13][10] = {"SAF", "10G", "HG[11]", "20G", "HG[21]", "25G", 3013 "HG[27]", "40G", "HG[42]", "50G", "HG[53]", 3014 "100G", "HG[106]"}; 3015 soc_th_asf_mode_e mode = _SOC_TH_ASF_RETRV; 3016 uint8 min_speed, max_speed; 3017 3018 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 3019 return BCM_E_NONE; 3020 } 3021 3022 min_speed = max_speed = _SOC_TH_ASF_RETRV; 3023 ret = soc_th_port_asf_mode_get(unit, port, port_speed, &mode); 3024 if (SOC_E_UNAVAIL == ret) { 3025 mode = _SOC_TH_ASF_MODE_SAF; 3026 } else if (SOC_E_NONE != ret) { 3027 return ret; 3028 } 3029 3030 LOG_CLI(("%-5s %-11s ", SOC_PORT_NAME(unit, port), mode_str[mode])); 3031 3032 if (_SOC_TH_ASF_MODE_SAF == mode) { 3033 LOG_CLI((" .. NA ..\n")); 3034 } else if (_SOC_TH_ASF_MODE_FAST_TO_SLOW == mode) { 3035 ret = _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode, 3036 &min_speed, &max_speed); 3037 LOG_CLI(("%s / %s\n", speed_str[max_speed], speed_str[min_speed])); 3038 } else { 3039 ret = _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode, 3040 &min_speed, &max_speed); 3041 LOG_CLI(("%s / %s\n", speed_str[min_speed], speed_str[max_speed])); 3042 } 3043 3044 return SOC_E_NONE; 3045 } 3046 3047 int soc_th_asf_config_dump(int unit) 3048 { 3049 char asf_profile_str[3][25] = {"No cut-thru support", 3050 "Similar speed cut-thru", 3051 "Extreme speed cut-thru"}; 3052 3053 _SOC_TH_UNIT_VALIDATE(unit); 3054 if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->init) { 3055 return SOC_E_INTERNAL; 3056 } 3057 3058 LOG_CLI(("ASF Profile: %s\n\n", 3059 asf_profile_str[_soc_th_asf_ctrl[unit]->asf_mem_profile])); 3060 3061 return SOC_E_NONE; 3062 } 3063 3064 int 3065 soc_th_port_asf_config_dump( 3066 int unit, 3067 soc_port_t port, 3068 int port_speed) 3069 { 3070 int txp = 0, rxp = 0, ct_class = 0; 3071 uint8 src_class = 0, dst_class = 0; 3072 uint8 min_sp = 0, max_sp = 0; 3073 uint8 fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0; 3074 uint8 xmit_start_cnt[13] = {0}; 3075 uint32 rval, mmu_ep_credits = 0, egr_mmu_cell_credits = 0; 3076 mac_driver_t *macd; 3077 soc_th_asf_mode_e mode = _SOC_TH_ASF_RETRV; 3078 #if defined(BCM_TOMAHAWK2_SUPPORT) 3079 egr_mmu_cell_credit_entry_t credit_entry; 3080 #endif 3081 3082 _SOC_TH_UNIT_VALIDATE(unit); 3083 3084 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 3085 return BCM_E_NONE; 3086 } 3087 3088 if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->init) { 3089 return SOC_E_INTERNAL; 3090 } 3091 3092 SOC_IF_ERROR_RETURN( 3093 soc_th_port_asf_mode_get(unit, port, port_speed, &mode)); 3094 3095 if (soc_th_port_asf_valid(unit, port)) { 3096 min_sp = max_sp = fifo_threshold = _SOC_TH_ASF_RETRV; 3097 fifo_depth = mmu_prebuf = _SOC_TH_ASF_RETRV; 3098 3099 SOC_IF_ERROR_RETURN( 3100 _soc_th_port_asf_class_get(unit, port, &ct_class)); 3101 SOC_IF_ERROR_RETURN( 3102 _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode, 3103 &min_sp, &max_sp)); 3104 #ifdef BCM_TOMAHAWK2_SUPPORT 3105 if (SOC_IS_TOMAHAWK2(unit)) { 3106 SOC_IF_ERROR_RETURN( 3107 _soc_th2_port_asf_fifo_threshold_get(unit, port, port_speed, mode, 3108 min_sp, &fifo_threshold)); 3109 3110 SOC_IF_ERROR_RETURN( 3111 _soc_th2_port_asf_fifo_depth_get(unit, port, port_speed, mode, 3112 min_sp, &fifo_depth)); 3113 3114 SOC_IF_ERROR_RETURN( 3115 _soc_th2_port_asf_mmu_prebuf_get(unit, port, port_speed, 3116 min_sp, &mmu_prebuf)); 3117 } else 3118 #endif 3119 { 3120 SOC_IF_ERROR_RETURN( 3121 _soc_th_port_asf_fifo_threshold_get(unit, port, port_speed, mode, 3122 min_sp, &fifo_threshold)); 3123 SOC_IF_ERROR_RETURN( 3124 _soc_th_port_asf_fifo_depth_get(unit, port, port_speed, mode, 3125 min_sp, &fifo_depth)); 3126 SOC_IF_ERROR_RETURN( 3127 _soc_th_port_asf_mmu_prebuf_get(unit, port, port_speed, 3128 min_sp, &mmu_prebuf)); 3129 } 3130 SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval)); 3131 mmu_ep_credits = soc_reg_field_get(unit, ASF_CREDIT_THRESH_HIr, 3132 rval, THRESHf); 3133 } 3134 3135 #ifdef BCM_TOMAHAWK2_SUPPORT 3136 if (SOC_IS_TOMAHAWK2(unit)) { 3137 dst_class = _soc_th_speed_to_ct_class_map(port_speed); 3138 for (src_class = 0; src_class <= 12; src_class++) { 3139 xmit_start_cnt[src_class] = _SOC_TH_ASF_RETRV; 3140 SOC_IF_ERROR_RETURN( 3141 _soc_th2_port_asf_xmit_start_count_get(unit, port, src_class, 3142 dst_class, mode, 3143 &xmit_start_cnt[src_class])); 3144 } 3145 } else 3146 #endif 3147 { 3148 dst_class = _soc_th_speed_to_ct_class_map(port_speed); 3149 for (src_class = 0; src_class <= 12; src_class++) { 3150 xmit_start_cnt[src_class] = _SOC_TH_ASF_RETRV; 3151 SOC_IF_ERROR_RETURN( 3152 _soc_th_port_asf_xmit_start_count_get(unit, port, src_class, 3153 dst_class, mode, 3154 &xmit_start_cnt[src_class])); 3155 } 3156 } 3157 3158 /* 3159 * COVERITY 3160 * 3161 * This fault is false detected. As min_sp and max_sp will be initialized to 0 inside 3162 * _soc_th_port_asf_speed_limits_get and will not be 255(_SOC_TH_ASF_RETRV) when code 3163 * runs to code paragraph. 3164 */ 3165 /* coverity[overrun-local] */ 3166 LOG_CLI(("%-5s %-3d %-3d %-6d %-6d %-3d %-3d ", SOC_PORT_NAME(unit, port), 3167 mode, ct_class, _SOC_TH_CT_CLASS_TO_SPEED_MAP(min_sp), 3168 _SOC_TH_CT_CLASS_TO_SPEED_MAP(max_sp), fifo_threshold, 3169 fifo_depth)); 3170 for (src_class = 0; src_class <= 12; src_class++) { 3171 LOG_CLI(("%-3d ", xmit_start_cnt[src_class])); 3172 } 3173 3174 3175 #if defined(BCM_TOMAHAWK2_SUPPORT) 3176 if (soc_feature(unit, soc_feature_egr_mmu_cell_credit_is_memory)) { 3177 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 3178 SOC_INFO(unit).port_l2p_mapping[port], &credit_entry)); 3179 egr_mmu_cell_credits = soc_EGR_MMU_CELL_CREDITm_field32_get(unit, 3180 &credit_entry, CREDITf); 3181 } else 3182 #endif 3183 { 3184 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITr(unit, port, &rval)); 3185 egr_mmu_cell_credits = soc_reg_field_get(unit, EGR_MMU_CELL_CREDITr, 3186 rval, CREDITf); 3187 } 3188 3189 SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd)); 3190 SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp)); 3191 3192 LOG_CLI((" %-3d %-3d %-3d %-3d\n", mmu_prebuf, mmu_ep_credits, 3193 egr_mmu_cell_credits, rxp)); 3194 3195 return SOC_E_NONE; 3196 } 3197 3198 /****************************************************************************** 3199 * Name: soc_th_port_asf_detach * 3200 * Description: * 3201 * Update ASF when port deleted during Flexport operation * 3202 * IN params: * 3203 * - Unit * 3204 * - Logical Port * 3205 * Returns: * 3206 * - SOC_E_NONE on success * 3207 * - SOC_E_PARAM on invalid parameter * 3208 */ 3209 int 3210 soc_th_port_asf_detach(int unit, soc_port_t port) 3211 { 3212 _SOC_TH_UNIT_VALIDATE(unit); 3213 3214 if (_soc_th_asf_ctrl[unit] == NULL) { 3215 return SOC_E_INIT; 3216 } 3217 3218 SOC_IF_ERROR_RETURN 3219 (soc_th_port_asf_mode_set(unit, port, 3220 SOC_INFO(unit).port_init_speed[port], 3221 _SOC_TH_ASF_MODE_SAF)); 3222 3223 if (soc_th_port_asf_valid(unit, port)) { 3224 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ports, port); 3225 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->pause_restore, port); 3226 if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_ss, port)) { 3227 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ss, port); 3228 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) { 3229 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_sf, port); 3230 } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) { 3231 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_fs, port); 3232 } 3233 } 3234 return SOC_E_NONE; 3235 } 3236 3237 #endif /* BCM_TOMAHAWK_SUPPORT */ 3238